* Helge Deller <deller@xxxxxx>: > STI text console (sticon) was broken on 64bit machines with more than > 4GB and 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 this just adds complexity and on some > machines a 64bit STI is just not available. Just for the archive - here is an unfinished version of my STIcon patch which can be used to develop a version which additionally supports the 64bit STI functions. Most changes are identical to the committed version. Signed-off-by: Helge Deller <deller@xxxxxx> diff --git a/arch/parisc/include/asm/pdc.h b/arch/parisc/include/asm/pdc.h index 7eb616e..501e564 100644 --- a/arch/parisc/include/asm/pdc.h +++ b/arch/parisc/include/asm/pdc.h @@ -318,9 +318,14 @@ int pdc_iodc_getc(void); int pdc_iodc_print(const unsigned char *str, unsigned count); void pdc_emergency_unlock(void); -int pdc_sti_call(unsigned long func, unsigned long flags, +int pdc_sti_call32(unsigned long func, unsigned long flags, unsigned long inptr, unsigned long outputr, unsigned long glob_cfg); +#ifdef CONFIG_64BIT +int pdc_sti_call64(unsigned long func, unsigned long flags, + unsigned long inptr, unsigned long outputr, + unsigned long glob_cfg); +#endif static inline char * os_id_to_string(u16 os_id) { switch(os_id) { diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c index 2239590..cb50107 100644 --- a/arch/parisc/kernel/firmware.c +++ b/arch/parisc/kernel/firmware.c @@ -1185,7 +1185,7 @@ int pdc_iodc_getc(void) return ch; } -int pdc_sti_call(unsigned long func, unsigned long flags, +int pdc_sti_call32(unsigned long func, unsigned long flags, unsigned long inptr, unsigned long outputr, unsigned long glob_cfg) { @@ -1198,9 +1198,25 @@ int pdc_sti_call(unsigned long func, unsigned long flags, return retval; } -EXPORT_SYMBOL(pdc_sti_call); +EXPORT_SYMBOL(pdc_sti_call32); #ifdef CONFIG_64BIT +int pdc_sti_call64(unsigned long func, unsigned long flags, + unsigned long inptr, unsigned long outputr, + unsigned long glob_cfg) +{ + int retval; + unsigned long irqflags; + + spin_lock_irqsave(&pdc_lock, irqflags); + retval = real64_call(func, flags, inptr, outputr, glob_cfg); + spin_unlock_irqrestore(&pdc_lock, irqflags); + + return retval; +} +EXPORT_SYMBOL(pdc_sti_call64); + + /** * pdc_pat_cell_get_number - Returns the cell number. * @cell_info: The return buffer. diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 35687fd..0095f50 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -73,28 +73,34 @@ static const struct sti_init_flags default_init_flags = { static int sti_init_graph(struct sti_struct *sti) { - struct sti_init_inptr_ext inptr_ext = { 0, }; - struct sti_init_inptr inptr = { - .text_planes = 3, /* # of text planes (max 3 for STI) */ - .ext_ptr = STI_PTR(&inptr_ext) - }; - struct sti_init_outptr outptr = { 0, }; + struct sti_init_inptr *inptr = &sti->sti_data->init_inptr; + struct sti_init_inptr_ext *inptr_ext = &sti->sti_data->init_inptr_ext; + struct sti_init_outptr *outptr = &sti->sti_data->init_outptr; unsigned long flags; - int ret; + int ret, err; spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->init_graph, &default_init_flags, &inptr, - &outptr, sti->glob_cfg); + memset(inptr, 0, sizeof(*inptr)); + inptr->text_planes = 3; /* # of text planes (max 3 for STI) */ + memset(inptr_ext, 0, sizeof(*inptr_ext)); + inptr->ext_ptr = STI_LONGPTR(sti, inptr_ext); + outptr->errno = 0; + + ret = sti_call(sti, sti->init_graph, &default_init_flags, inptr, + outptr, sti->glob_cfg); + + if (ret >= 0) + sti->text_planes = outptr->text_planes; + err = outptr->errno; spin_unlock_irqrestore(&sti->lock, flags); if (ret < 0) { - printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n",ret,outptr.errno); + printk(KERN_ERR "STI init_graph failed (ret %d, errno %d)\n", ret, err); return -1; } - sti->text_planes = outptr.text_planes; return 0; } @@ -104,16 +110,18 @@ static const struct sti_conf_flags default_conf_flags = { static void sti_inq_conf(struct sti_struct *sti) { - struct sti_conf_inptr inptr = { 0, }; + struct sti_conf_inptr *inptr = &sti->sti_data->inq_inptr; + struct sti_conf_outptr *outptr = &sti->sti_data->inq_outptr; unsigned long flags; s32 ret; - sti->outptr.ext_ptr = STI_PTR(&sti->outptr_ext); + outptr->ext_ptr = STI_LONGPTR(sti, &sti->sti_data->inq_outptr_ext); do { spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->inq_conf, &default_conf_flags, - &inptr, &sti->outptr, sti->glob_cfg); + memset(inptr, 0, sizeof(*inptr)); + ret = sti_call(sti, sti->inq_conf, &default_conf_flags, + inptr, outptr, sti->glob_cfg); spin_unlock_irqrestore(&sti->lock, flags); } while (ret == 1); } @@ -126,7 +134,8 @@ static const struct sti_font_flags default_font_flags = { void sti_putc(struct sti_struct *sti, int c, int y, int x) { - struct sti_font_inptr inptr = { + struct sti_font_inptr *inptr = &sti->sti_data->font_inptr; + struct sti_font_inptr inptr_default = { .font_start_addr= STI_PTR(sti->font->raw), .index = c_index(sti, c), .fg_color = c_fg(sti, c), @@ -134,14 +143,15 @@ sti_putc(struct sti_struct *sti, int c, int y, int x) .dest_x = x * sti->font_width, .dest_y = y * sti->font_height, }; - struct sti_font_outptr outptr = { 0, }; + struct sti_font_outptr *outptr = &sti->sti_data->font_outptr; s32 ret; unsigned long flags; do { spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->font_unpmv, &default_font_flags, - &inptr, &outptr, sti->glob_cfg); + *inptr = inptr_default; + ret = sti_call(sti, sti->font_unpmv, &default_font_flags, + inptr, outptr, sti->glob_cfg); spin_unlock_irqrestore(&sti->lock, flags); } while (ret == 1); } @@ -156,7 +166,8 @@ void sti_set(struct sti_struct *sti, int src_y, int src_x, int height, int width, u8 color) { - struct sti_blkmv_inptr inptr = { + struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; + struct sti_blkmv_inptr inptr_default = { .fg_color = color, .bg_color = color, .src_x = src_x, @@ -166,14 +177,15 @@ sti_set(struct sti_struct *sti, int src_y, int src_x, .width = width, .height = height, }; - struct sti_blkmv_outptr outptr = { 0, }; + struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; unsigned long flags; do { spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->block_move, &clear_blkmv_flags, - &inptr, &outptr, sti->glob_cfg); + *inptr = inptr_default; + ret = sti_call(sti, sti->block_move, &clear_blkmv_flags, + inptr, outptr, sti->glob_cfg); spin_unlock_irqrestore(&sti->lock, flags); } while (ret == 1); } @@ -182,7 +194,8 @@ void sti_clear(struct sti_struct *sti, int src_y, int src_x, int height, int width, int c) { - struct sti_blkmv_inptr inptr = { + struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; + struct sti_blkmv_inptr inptr_default = { .fg_color = c_fg(sti, c), .bg_color = c_bg(sti, c), .src_x = src_x * sti->font_width, @@ -192,14 +205,15 @@ sti_clear(struct sti_struct *sti, int src_y, int src_x, .width = width * sti->font_width, .height = height* sti->font_height, }; - struct sti_blkmv_outptr outptr = { 0, }; + struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; unsigned long flags; do { spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->block_move, &clear_blkmv_flags, - &inptr, &outptr, sti->glob_cfg); + *inptr = inptr_default; + ret = sti_call(sti, sti->block_move, &clear_blkmv_flags, + inptr, outptr, sti->glob_cfg); spin_unlock_irqrestore(&sti->lock, flags); } while (ret == 1); } @@ -212,7 +226,8 @@ void sti_bmove(struct sti_struct *sti, int src_y, int src_x, int dst_y, int dst_x, int height, int width) { - struct sti_blkmv_inptr inptr = { + struct sti_blkmv_inptr *inptr = &sti->sti_data->blkmv_inptr; + struct sti_blkmv_inptr inptr_default = { .src_x = src_x * sti->font_width, .src_y = src_y * sti->font_height, .dest_x = dst_x * sti->font_width, @@ -220,14 +235,15 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x, .width = width * sti->font_width, .height = height* sti->font_height, }; - struct sti_blkmv_outptr outptr = { 0, }; + struct sti_blkmv_outptr *outptr = &sti->sti_data->blkmv_outptr; s32 ret; unsigned long flags; do { spin_lock_irqsave(&sti->lock, flags); - ret = STI_CALL(sti->block_move, &default_blkmv_flags, - &inptr, &outptr, sti->glob_cfg); + *inptr = inptr_default; + ret = sti_call(sti, sti->block_move, &default_blkmv_flags, + inptr, outptr, sti->glob_cfg); spin_unlock_irqrestore(&sti->lock, flags); } while (ret == 1); } @@ -389,10 +405,10 @@ static void sti_dump_outptr(struct sti_struct *sti) "%d used bits\n" "%d planes\n" "attributes %08x\n", - sti->outptr.bits_per_pixel, - sti->outptr.bits_used, - sti->outptr.planes, - sti->outptr.attributes)); + sti->sti_data->inq_outptr.bits_per_pixel, + sti->sti_data->inq_outptr.bits_used, + sti->sti_data->inq_outptr.planes, + sti->sti_data->inq_outptr.attributes)); } static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, @@ -402,24 +418,21 @@ static int sti_init_glob_cfg(struct sti_struct *sti, unsigned long rom_address, struct sti_glob_cfg_ext *glob_cfg_ext; void *save_addr; void *sti_mem_addr; - const int save_addr_size = 1024; /* XXX */ - int i; + int i, size; - if (!sti->sti_mem_request) + if (sti->sti_mem_request < 256) sti->sti_mem_request = 256; /* STI default */ - glob_cfg = kzalloc(sizeof(*sti->glob_cfg), GFP_KERNEL); - glob_cfg_ext = kzalloc(sizeof(*glob_cfg_ext), GFP_KERNEL); - save_addr = kzalloc(save_addr_size, GFP_KERNEL); - sti_mem_addr = kzalloc(sti->sti_mem_request, GFP_KERNEL); + size = sizeof(struct sti_all_data) + sti->sti_mem_request - 256; - if (!(glob_cfg && glob_cfg_ext && save_addr && sti_mem_addr)) { - kfree(glob_cfg); - kfree(glob_cfg_ext); - kfree(save_addr); - kfree(sti_mem_addr); + sti->sti_data = kzalloc(size, GFP_KERNEL | GFP_DMA); + if (!sti->sti_data) return -ENOMEM; - } + + glob_cfg = &sti->sti_data->glob_cfg; + glob_cfg_ext = &sti->sti_data->glob_cfg_ext; + save_addr = &sti->sti_data->save_addr; + sti_mem_addr = &sti->sti_data->sti_mem_addr; glob_cfg->ext_ptr = STI_PTR(glob_cfg_ext); glob_cfg->save_addr = STI_PTR(save_addr); @@ -500,7 +513,7 @@ sti_select_fbfont(struct sti_cooked_rom *cooked_rom, const char *fbfont_name) size = bpc * 256; size += sizeof(struct sti_rom_font); - nf = kzalloc(size, GFP_KERNEL); + nf = kzalloc(size, GFP_KERNEL | GFP_DMA); if (!nf) return NULL; @@ -637,7 +650,7 @@ static void *sti_bmode_font_raw(struct sti_cooked_font *f) unsigned char *n, *p, *q; int size = f->raw->bytes_per_char*256+sizeof(struct sti_rom_font); - n = kzalloc (4*size, GFP_KERNEL); + n = kzalloc (4*size, GFP_KERNEL | GFP_DMA); if (!n) return NULL; p = n + 3; @@ -673,7 +686,7 @@ static struct sti_rom *sti_get_bmode_rom (unsigned long address) sti_bmode_rom_copy(address + BMODE_LAST_ADDR_OFFS, sizeof(size), &size); size = (size+3) / 4; - raw = kmalloc(size, GFP_KERNEL); + raw = kmalloc(size, GFP_KERNEL | GFP_DMA); if (raw) { sti_bmode_rom_copy(address, size, raw); memmove (&raw->res004, &raw->type[0], 0x3c); @@ -707,7 +720,7 @@ static struct sti_rom *sti_get_wmode_rom(unsigned long address) /* read the ROM size directly from the struct in ROM */ size = gsc_readl(address + offsetof(struct sti_rom,last_addr)); - raw = kmalloc(size, GFP_KERNEL); + raw = kmalloc(size, GFP_KERNEL | GFP_DMA); if (raw) sti_rom_copy(address, size, raw); @@ -743,11 +756,48 @@ static int sti_read_rom(int wordmode, struct sti_struct *sti, address = (unsigned long) STI_PTR(raw); + pr_info("STI ROM supports 32 %sbit firmware functions.\n", + raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64 ? "and 64 ":""); + +#ifdef CONFIG_64BIT + /* Check if STI firmware includes 64bit API functions. */ + sti->use_64bit = (raw->alt_code_type == ALT_CODE_TYPE_PA_RISC_64); + + sti->use_64bit = 0; /* XXX */ + + /* Prefer 64bit STI API if available. */ + if (STI_USE_64bit) { + pr_warn("STI: Using 64bit STI functions.\n"); + sti->font_unpmv = address + (raw->font_unp_64bit & 0x03ffffff); + sti->block_move = address + (raw->block_move_64bit & 0x03ffffff); + sti->init_graph = address + (raw->init_graph_64bit & 0x03ffffff); + sti->inq_conf = address + (raw->inq_conf_64bit & 0x03ffffff); + goto cont1; + } + + pr_warn("STI: Memory = %u bytes\n", PAGE0->imm_max_mem); + if (PAGE0->imm_max_mem >= (3UL*1024+512)*1024*1024) { + pr_warn("STI: Sorry, 64bit STI firmware functions needed on machines with > 3.5 GB.\n"); + goto out_err; + } + + /* If the machine has less than 4GB physical RAM, then just use the + * 32bit STI functions. Since we need to convert all pointers into + * physical addresses, all will be below 4GB which is reachable by + * the 32bit STI implementation. + */ +#endif + + pr_warn("STI: Using 32bit STI functions.\n"); sti->font_unpmv = address + (raw->font_unpmv & 0x03ffffff); sti->block_move = address + (raw->block_move & 0x03ffffff); sti->init_graph = address + (raw->init_graph & 0x03ffffff); sti->inq_conf = address + (raw->inq_conf & 0x03ffffff); +#ifdef CONFIG_64BIT +cont1: +#endif + sti->rom = cooked; sti->rom->raw = raw; @@ -901,7 +951,7 @@ test_rom: sti_dump_globcfg(sti->glob_cfg, sti->sti_mem_request); sti_dump_outptr(sti); - printk(KERN_INFO " graphics card name: %s\n", sti->outptr.dev_name ); + printk(KERN_INFO " graphics card name: %s\n", sti->sti_data->inq_outptr.dev_name ); sti_roms[num_sti_roms] = sti; num_sti_roms++; @@ -1073,6 +1123,35 @@ struct sti_struct * sti_get_rom(unsigned int index) } EXPORT_SYMBOL(sti_get_rom); + +int sti_call(const struct sti_struct *sti, unsigned long func, const void *flags, + void *inptr, void *outptr, struct sti_glob_cfg *glob_cfg) +{ + unsigned long _flags = STI_PTR(flags); + unsigned long _inptr = STI_PTR(inptr); + unsigned long _outptr = STI_PTR(outptr); + unsigned long _glob_cfg = STI_PTR(glob_cfg); + int ret; + + if (!STI_USE_64bit) { + /* Check for overflow when using 32bit STI on 64bit kernel. */ + if (_flags>>32 || _inptr>>32 || _outptr>>32 || _glob_cfg>>32) { + WARN_ONCE(1, "INVALID POINTERS!"); + return -1; + } + } + +// pr_warn("sti_call(%#lx, %#lx, %#lx, %#lx, %#lx)\n", +// func, _flags, _inptr, _outptr, _glob_cfg); + + if (STI_USE_64bit) + ret = pdc_sti_call64( func, _flags, _inptr, _outptr, _glob_cfg); + else + ret = pdc_sti_call32( func, _flags, _inptr, _outptr, _glob_cfg); + + return ret; +} + MODULE_AUTHOR("Philipp Rumpf, Helge Deller, Thomas Bogendoerfer"); MODULE_DESCRIPTION("Core STI driver for HP's NGLE series graphics cards in HP PARISC machines"); MODULE_LICENSE("GPL v2"); diff --git a/drivers/video/sticore.h b/drivers/video/sticore.h index addf7b6..fe42c93 100644 --- a/drivers/video/sticore.h +++ b/drivers/video/sticore.h @@ -3,7 +3,7 @@ /* generic STI structures & functions */ -#if 0 +#if 1 #define DPRINTK(x) printk x #else #define DPRINTK(x) @@ -18,6 +18,9 @@ #define STI_FONT_HPROMAN8 1 #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 * 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 @@ -35,19 +38,25 @@ */ #include <asm/io.h> +#include <linux/bug.h> #define STI_WAIT 1 -#define STI_PTR(p) ( virt_to_phys(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)); \ - }) +#ifdef CONFIG_64BIT +#define STI_USE_64bit sti->use_64bit +#else +#define STI_USE_64bit 0 +#endif + +// #define STI_PTR(p) ( virt_to_phys(p) ) +#define STI_PTR(p) ({ unsigned long _p = virt_to_phys(p); WARN_ONCE(_p>>32, "STI_PTR too big"); _p; }) +#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) +#if 0 // def CONFIG_64BIT +# define STI_LONGPTR(sti,p) ({ unsigned long _x = virt_to_phys(p); STI_USE_64bit ? (u32*)_x:(u32*)(_x<<32); }) +#else +# define STI_LONGPTR(sti,p) STI_PTR(p) +#endif #define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) #define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) @@ -80,8 +89,8 @@ struct sti_glob_cfg_ext { u8 friendly_boot; /* in friendly boot mode */ s16 power; /* power calculation (in Watts) */ s32 freq_ref; /* frequency reference */ - u32 sti_mem_addr; /* pointer to global sti memory (size=sti_mem_request) */ - u32 future_ptr; /* pointer to future data */ + u32 sti_mem_addr; /* XXX pointer to global sti memory (size=sti_mem_request) */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_glob_cfg { @@ -92,13 +101,12 @@ struct sti_glob_cfg { s16 offscreen_y; /* offset height in pixels */ s16 total_x; /* frame buffer width in pixels */ s16 total_y; /* frame buffer height in pixels */ - u32 region_ptrs[STI_REGION_MAX]; /* region pointers */ + u32 region_ptrs[STI_REGION_MAX]; /* XXX region pointers */ s32 reent_lvl; /* storage for reentry level value */ u32 save_addr; /* where to save or restore reentrant state */ u32 ext_ptr; /* pointer to extended glob_cfg data structure */ }; - /* STI init function structs */ struct sti_init_flags { @@ -121,14 +129,14 @@ struct sti_init_flags { u32 caller_kernel : 1; /* set only by kernel for each call */ u32 caller_other : 1; /* set only by non-[BR/K] caller */ u32 pad : 14; /* pad to word boundary */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_init_inptr_ext { u8 config_mon_type; /* configure to monitor type */ u8 pad[1]; /* pad to word boundary */ u16 inflight_data; /* inflight data possible on PCI */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_init_inptr { @@ -140,7 +148,7 @@ struct sti_init_inptr { struct sti_init_outptr { s32 errno; /* error number on failure */ s32 text_planes; /* number of planes used for text */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; @@ -150,17 +158,17 @@ struct sti_init_outptr { struct sti_conf_flags { u32 wait : 1; /* should routine idle wait or not */ u32 pad : 31; /* pad to word boundary */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_conf_inptr { - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_conf_outptr_ext { u32 crt_config[3]; /* hardware specific X11/OGL information */ u32 crt_hdw[3]; - u32 future_ptr; + u32 *future_ptr; }; struct sti_conf_outptr { @@ -214,18 +222,18 @@ struct sti_rom { u32 inq_conf; u32 set_cm_entry; u32 dma_ctrl; - u8 res040[7 * 4]; + u32 res040[7]; - u32 init_graph_addr; - u32 state_mgmt_addr; - u32 font_unp_addr; - u32 block_move_addr; - u32 self_test_addr; - u32 excep_hdlr_addr; - u32 inq_conf_addr; - u32 set_cm_entry_addr; - u32 image_unpack_addr; - u32 pa_risx_addrs[7]; + u32 init_graph_64bit; + u32 state_mgmt_64bit; + u32 font_unp_64bit; + u32 block_move_64bit; + u32 self_test_64bit; + u32 excep_hdlr_64bit; + u32 inq_conf_64bit; + u32 set_cm_entry_64bit; + u32 image_unpack_64bit; + u32 pa_risx_64bits[7]; }; struct sti_rom_font { @@ -256,25 +264,25 @@ struct sti_cooked_rom { /* STI font printing function structs */ struct sti_font_inptr { - u32 font_start_addr; /* address of font start */ + u32 font_start_addr; /* XXX address of font start */ s16 index; /* index into font table of character */ u8 fg_color; /* foreground color of character */ u8 bg_color; /* background color of character */ s16 dest_x; /* X location of character upper left */ s16 dest_y; /* Y location of character upper left */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_font_flags { u32 wait : 1; /* should routine idle wait or not */ u32 non_text : 1; /* font unpack/move in non_text planes =1, text =0 */ u32 pad : 30; /* pad to word boundary */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_font_outptr { s32 errno; /* error number on failure */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; /* STI blockmove structs */ @@ -285,7 +293,7 @@ struct sti_blkmv_flags { u32 clear : 1; /* clear during move? */ u32 non_text : 1; /* block move in non_text planes =1, text =0 */ u32 pad : 28; /* pad to word boundary */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_blkmv_inptr { @@ -297,15 +305,43 @@ struct sti_blkmv_inptr { s16 dest_y; /* dest upper left pixel y location */ s16 width; /* block width in pixels */ s16 height; /* block height in pixels */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; struct sti_blkmv_outptr { s32 errno; /* error number on failure */ - u32 future_ptr; /* pointer to future data */ + u32 *future_ptr; /* pointer to future data */ }; +/* this internal struct needs to be allocated in low_mem (<4GB) + * if used with 32bit STI */ + +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 */ struct sti_struct { @@ -320,6 +356,7 @@ struct sti_struct { struct sti_cooked_rom *rom; + int use_64bit; /* enabled, if 64bit sti functions are being called. */ unsigned long font_unpmv; unsigned long block_move; unsigned long init_graph; @@ -330,11 +367,9 @@ struct sti_struct { region_t regions[STI_REGION_MAX]; unsigned long regions_phys[STI_REGION_MAX]; - struct sti_glob_cfg *glob_cfg; - struct sti_cooked_font *font; /* ptr to selected font (cooked) */ + struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ - struct sti_conf_outptr outptr; /* configuration */ - struct sti_conf_outptr_ext outptr_ext; + struct sti_cooked_font *font; /* ptr to selected font (cooked) */ struct pci_dev *pd; @@ -343,6 +378,9 @@ struct sti_struct { /* pointer to the fb_info where this STI device is used */ struct fb_info *info; + + /* pointer to all internal data */ + struct sti_all_data *sti_data; }; @@ -350,6 +388,13 @@ struct sti_struct { 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 */ void sti_putc(struct sti_struct *sti, int c, int y, int x); -- To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html