Commit 0219132f authored by Helge Deller's avatar Helge Deller

parisc: sticon - unbreak on 64bit kernel

STI text console (sticon) was broken on 64bit machines with more than
4GB RAM and this lead in some cases to a kernel crash.

Since sticon uses the 32bit STI API it needs to keep pointers to memory
below 4GB. But on a 64bit kernel some memory regions (e.g. the kernel
stack) might be above 4GB which then may crash the kernel in the STI
functions.

Additionally sticon didn't selected the built-in framebuffer fonts by
default. This is now fixed.

On a side-note: Theoretically we could enhance the sticon driver to
use the 64bit STI API. But - beside the fact that some machines don't
provide a 64bit STI ROM - this would just add complexity.
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Cc: stable@vger.kernel.org # 3.8+
parent 1f2048fd
This diff is collapsed.
...@@ -18,6 +18,9 @@ ...@@ -18,6 +18,9 @@
#define STI_FONT_HPROMAN8 1 #define STI_FONT_HPROMAN8 1
#define STI_FONT_KANA8 2 #define STI_FONT_KANA8 2
#define ALT_CODE_TYPE_UNKNOWN 0x00 /* alt code type values */
#define ALT_CODE_TYPE_PA_RISC_64 0x01
/* The latency of the STI functions cannot really be reduced by setting /* The latency of the STI functions cannot really be reduced by setting
* this to 0; STI doesn't seem to be designed to allow calling a different * this to 0; STI doesn't seem to be designed to allow calling a different
* function (or the same function with different arguments) after a * function (or the same function with different arguments) after a
...@@ -40,14 +43,6 @@ ...@@ -40,14 +43,6 @@
#define STI_PTR(p) ( virt_to_phys(p) ) #define STI_PTR(p) ( virt_to_phys(p) )
#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) #define PTR_STI(p) ( phys_to_virt((unsigned long)p) )
#define STI_CALL(func, flags, inptr, outptr, glob_cfg) \
({ \
pdc_sti_call( func, STI_PTR(flags), \
STI_PTR(inptr), \
STI_PTR(outptr), \
STI_PTR(glob_cfg)); \
})
#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x)
#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y)
...@@ -56,6 +51,12 @@ ...@@ -56,6 +51,12 @@
#define sti_font_x(sti) (PTR_STI(sti->font)->width) #define sti_font_x(sti) (PTR_STI(sti->font)->width)
#define sti_font_y(sti) (PTR_STI(sti->font)->height) #define sti_font_y(sti) (PTR_STI(sti->font)->height)
#ifdef CONFIG_64BIT
#define STI_LOWMEM (GFP_KERNEL | GFP_DMA)
#else
#define STI_LOWMEM (GFP_KERNEL)
#endif
/* STI function configuration structs */ /* STI function configuration structs */
...@@ -306,6 +307,34 @@ struct sti_blkmv_outptr { ...@@ -306,6 +307,34 @@ struct sti_blkmv_outptr {
}; };
/* sti_all_data is an internal struct which needs to be allocated in
* low memory (< 4GB) if STI is used with 32bit STI on a 64bit kernel */
struct sti_all_data {
struct sti_glob_cfg glob_cfg;
struct sti_glob_cfg_ext glob_cfg_ext;
struct sti_conf_inptr inq_inptr;
struct sti_conf_outptr inq_outptr; /* configuration */
struct sti_conf_outptr_ext inq_outptr_ext;
struct sti_init_inptr_ext init_inptr_ext;
struct sti_init_inptr init_inptr;
struct sti_init_outptr init_outptr;
struct sti_blkmv_inptr blkmv_inptr;
struct sti_blkmv_outptr blkmv_outptr;
struct sti_font_inptr font_inptr;
struct sti_font_outptr font_outptr;
/* leave as last entries */
unsigned long save_addr[1024 / sizeof(unsigned long)];
/* min 256 bytes which is STI default, max sti->sti_mem_request */
unsigned long sti_mem_addr[256 / sizeof(unsigned long)];
/* do not add something below here ! */
};
/* internal generic STI struct */ /* internal generic STI struct */
struct sti_struct { struct sti_struct {
...@@ -330,11 +359,9 @@ struct sti_struct { ...@@ -330,11 +359,9 @@ struct sti_struct {
region_t regions[STI_REGION_MAX]; region_t regions[STI_REGION_MAX];
unsigned long regions_phys[STI_REGION_MAX]; unsigned long regions_phys[STI_REGION_MAX];
struct sti_glob_cfg *glob_cfg; struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */
struct sti_cooked_font *font; /* ptr to selected font (cooked) */
struct sti_conf_outptr outptr; /* configuration */ struct sti_cooked_font *font; /* ptr to selected font (cooked) */
struct sti_conf_outptr_ext outptr_ext;
struct pci_dev *pd; struct pci_dev *pd;
...@@ -343,6 +370,9 @@ struct sti_struct { ...@@ -343,6 +370,9 @@ struct sti_struct {
/* pointer to the fb_info where this STI device is used */ /* pointer to the fb_info where this STI device is used */
struct fb_info *info; struct fb_info *info;
/* pointer to all internal data */
struct sti_all_data *sti_data;
}; };
...@@ -350,6 +380,14 @@ struct sti_struct { ...@@ -350,6 +380,14 @@ struct sti_struct {
struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */ struct sti_struct *sti_get_rom(unsigned int index); /* 0: default sti */
/* sticore main function to call STI firmware */
int sti_call(const struct sti_struct *sti, unsigned long func,
const void *flags, void *inptr, void *outptr,
struct sti_glob_cfg *glob_cfg);
/* functions to call the STI ROM directly */ /* functions to call the STI ROM directly */
void sti_putc(struct sti_struct *sti, int c, int y, int x); void sti_putc(struct sti_struct *sti, int c, int y, int x);
......
...@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1101,6 +1101,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
var = &info->var; var = &info->var;
fb->sti = sti; fb->sti = sti;
dev_name = sti->sti_data->inq_outptr.dev_name;
/* store upper 32bits of the graphics id */ /* store upper 32bits of the graphics id */
fb->id = fb->sti->graphics_id[0]; fb->id = fb->sti->graphics_id[0];
...@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1114,11 +1115,11 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
Since this driver only supports standard mode, we check Since this driver only supports standard mode, we check
if the device name contains the string "DX" and tell the if the device name contains the string "DX" and tell the
user how to reconfigure the card. */ user how to reconfigure the card. */
if (strstr(sti->outptr.dev_name, "DX")) { if (strstr(dev_name, "DX")) {
printk(KERN_WARNING printk(KERN_WARNING
"WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n" "WARNING: stifb framebuffer driver does not support '%s' in double-buffer mode.\n"
"WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n", "WARNING: Please disable the double-buffer mode in IPL menu (the PARISC-BIOS).\n",
sti->outptr.dev_name); dev_name);
goto out_err0; goto out_err0;
} }
/* fall though */ /* fall though */
...@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1130,7 +1131,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
break; break;
default: default:
printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n", printk(KERN_WARNING "stifb: '%s' (id: 0x%08x) not supported.\n",
sti->outptr.dev_name, fb->id); dev_name, fb->id);
goto out_err0; goto out_err0;
} }
...@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1154,7 +1155,6 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
fb->id = S9000_ID_A1659A; fb->id = S9000_ID_A1659A;
break; break;
case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */ case S9000_ID_TIMBER: /* HP9000/710 Any (may be a grayscale device) */
dev_name = fb->sti->outptr.dev_name;
if (strstr(dev_name, "GRAYSCALE") || if (strstr(dev_name, "GRAYSCALE") ||
strstr(dev_name, "Grayscale") || strstr(dev_name, "Grayscale") ||
strstr(dev_name, "grayscale")) strstr(dev_name, "grayscale"))
...@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref) ...@@ -1290,7 +1290,7 @@ static int __init stifb_init_fb(struct sti_struct *sti, int bpp_pref)
var->xres, var->xres,
var->yres, var->yres,
var->bits_per_pixel, var->bits_per_pixel,
sti->outptr.dev_name, dev_name,
fb->id, fb->id,
fix->mmio_start); fix->mmio_start);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment