diff options
author | Helge Deller <deller@gmx.de> | 2019-09-11 20:24:52 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-09-11 20:24:52 +0200 |
commit | 1527660fbf8511971e97b6b6c01e272eba225c75 (patch) | |
tree | 4aae30ffd735ee86e61bdd07adc90f36ff3151f0 | |
parent | a9b7813e723e764a4da797149e2828d875df4023 (diff) | |
parent | ba3c6473baf28f7b7b0e6663fb85616be1ce49c4 (diff) | |
download | seabios-hppa-1527660fbf8511971e97b6b6c01e272eba225c75.zip seabios-hppa-1527660fbf8511971e97b6b6c01e272eba225c75.tar.gz seabios-hppa-1527660fbf8511971e97b6b6c01e272eba225c75.tar.bz2 |
Merge pull request #3 from svenschnelle/sti
Merge STI graphics/console support from Sven Schnelle
-rw-r--r-- | Makefile.parisc | 4 | ||||
-rw-r--r-- | src/kbd.c | 5 | ||||
-rw-r--r-- | src/output.c | 19 | ||||
-rw-r--r-- | src/parisc/b160l.h | 6 | ||||
-rw-r--r-- | src/parisc/hppa.h | 3 | ||||
-rw-r--r-- | src/parisc/lasips2.c | 66 | ||||
-rw-r--r-- | src/parisc/lasips2.h | 17 | ||||
-rw-r--r-- | src/parisc/pafirmware.lds.S | 21 | ||||
-rw-r--r-- | src/parisc/parisc.c | 196 | ||||
-rw-r--r-- | src/parisc/sti.c | 196 | ||||
-rw-r--r-- | src/parisc/sticore.h | 505 | ||||
-rw-r--r-- | src/parisc/stirom.c | 555 |
12 files changed, 1176 insertions, 417 deletions
diff --git a/Makefile.parisc b/Makefile.parisc index bc52737..c0d5d95 100644 --- a/Makefile.parisc +++ b/Makefile.parisc @@ -33,7 +33,7 @@ LD32BIT_FLAG:= SRCBOTH=output.c string.c block.c cdrom.c disk.c kbd.c \ serial.c sercon.c clock.c vgahooks.c \ apm.c cp437.c \ - hw/pci.c hw/rtc.c hw/dma.c hw/pic.c hw/ps2port.c hw/serialio.c \ + hw/pci.c hw/rtc.c hw/dma.c hw/pic.c hw/serialio.c \ hw/usb.c hw/usb-uhci.c hw/usb-ohci.c hw/usb-ehci.c \ hw/usb-hid.c hw/usb-msc.c hw/usb-uas.c \ hw/blockcmd.c hw/floppy.c hw/ata.c hw/ramdisk.c \ @@ -48,7 +48,7 @@ SRC32FLAT=$(SRCBOTH) post.c e820map.c romfile.c optionroms.c \ fw/acpi.c fw/mptable.c fw/pirtable.c fw/smbios.c fw/romfile_loader.c \ hw/virtio-ring.c hw/virtio-pci.c hw/virtio-blk.c hw/virtio-scsi.c \ hw/tpm_drivers.c hw/nvme.c \ - version.c parisc/malloc.c parisc/parisc.c parisc/sti.c + version.c parisc/malloc.c parisc/parisc.c parisc/sti.c parisc/lasips2.c parisc/stirom.c DIRS=src src/hw src/fw vgasrc src/parisc # VGA src files @@ -63,11 +63,16 @@ dequeue_key(struct bregs *regs, int incr, int extended) if (buffer_head != buffer_tail) break; +#ifdef CONFIG_PARISC + regs->ax = 0; + return; +#else if (!incr) { regs->flags |= F_ZF; return; } yield_toirq(); +#endif } u16 keycode = GET_FARVAR(SEG_BDA, *(u16*)(buffer_head+0)); diff --git a/src/output.c b/src/output.c index 117bbda..52fdf03 100644 --- a/src/output.c +++ b/src/output.c @@ -18,6 +18,9 @@ #include "stacks.h" // call16_int #include "string.h" // memset #include "util.h" // ScreenAndDebug +#ifdef CONFIG_PARISC +#include "parisc/sticore.h" +#endif struct putcinfo { void (*func)(struct putcinfo *info, char c); @@ -78,16 +81,8 @@ static void screenc(char c) { #if CONFIG_PARISC - for (;;) { - const portaddr_t addr = PORT_SERIAL1; - u8 lsr = inb(addr+SEROFF_LSR); - if ((lsr & 0x60) == 0x60) { - // Success - can write data - outb(c, addr+SEROFF_DATA); - break; - } - } -#endif + parisc_screenc(c); +#else if (!MODESEGMENT && GET_IVT(0x10).segoff == FUNC16(entry_10).segoff) // No need to thunk to 16bit mode if vgabios is not present return; @@ -97,10 +92,6 @@ screenc(char c) br.ah = 0x0e; br.al = c; br.bl = 0x07; -#if CONFIG_PARISC - extern void parisc_teletype_output(struct bregs *regs); - parisc_teletype_output(&br); -#else call16_int(0x10, &br); #endif } diff --git a/src/parisc/b160l.h b/src/parisc/b160l.h index 27857cc..760ebce 100644 --- a/src/parisc/b160l.h +++ b/src/parisc/b160l.h @@ -413,7 +413,7 @@ static struct pdc_system_map_mod_info mod_info_hpa_f8000000 = { .add_addrs = 0x1, }; static struct pdc_module_path mod_path_hpa_f8000000 = { - .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0x8 }, .mod = 0x18 }, + .path = { .flags = 0x0, .bc = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, .mod = 0x1 }, .layers = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }; static struct pdc_iodc iodc_data_hpa_f8000000 = { @@ -431,8 +431,8 @@ static struct pdc_iodc iodc_data_hpa_f8000000 = { .length = 0x0002, /* pad: 0x0000, 0x0000 */ }; -#define HPA_f8000000_num_addr 1 -#define HPA_f8000000_add_addr 0xf0011000, +#define HPA_f8000000_num_addr 0 +#define HPA_f8000000_add_addr 0 #define HPA_fff10000_DESCRIPTION "Merlin L2 160 (9000/778/B160L)" static struct pdc_system_map_mod_info mod_info_hpa_fff10000 = { diff --git a/src/parisc/hppa.h b/src/parisc/hppa.h index 18dcd24..c1ae215 100644 --- a/src/parisc/hppa.h +++ b/src/parisc/hppa.h @@ -1,3 +1,5 @@ +#ifndef HPPA_H +#define HPPA_H /* this file is included by x86.h */ #if 0 @@ -383,3 +385,4 @@ static inline void wrmsr(u32 index, u64 val) void cpuid(u32 index, u32 *eax, u32 *ebx, u32 *ecx, u32 *edx); #endif // !__ASSEMBLY__ +#endif diff --git a/src/parisc/lasips2.c b/src/parisc/lasips2.c new file mode 100644 index 0000000..119c214 --- /dev/null +++ b/src/parisc/lasips2.c @@ -0,0 +1,66 @@ +/* LASI PS2 keyboard support code + * + * Copyright (C) 2019 Sven Schnelle <svens@stackframe.org> + * + * This file may be distributed under the terms of the GNU LGPLv2 license. + */ + +#include "bregs.h" +#include "autoconf.h" +#include "types.h" +#include "output.h" +#include "hw/ps2port.h" +#include "util.h" +#include "string.h" +#include "lasips2.h" + +int lasips2_kbd_in(char *c, int max) +{ + struct bregs regs; + volatile int count = 0; + + while((readl(LASIPS2_KBD_STATUS) & LASIPS2_KBD_STATUS_RBNE)) { + process_key(readb(LASIPS2_KBD_DATA)); + } + + while(count < max) { + memset(®s, 0, sizeof(regs)); + regs.ah = 0x10; + handle_16(®s); + if (!regs.ah) + break; + *c++ = regs.ah; + count++; + } + return count; +} + + +int ps2_kbd_command(int command, u8 *param) +{ + return 0; +} + +int lasips2_command(u16 cmd) +{ + while(readl(LASIPS2_KBD_STATUS) & LASIPS2_KBD_STATUS_TBNE) + udelay(10); + writeb(LASIPS2_KBD_DATA, cmd & 0xff); + + while(!(readl(LASIPS2_KBD_STATUS) & LASIPS2_KBD_STATUS_RBNE)) + udelay(10); + return readb(LASIPS2_KBD_DATA); +} + +void ps2port_setup(void) +{ + writeb(LASIPS2_KBD_RESET, 0); + udelay(1000); + writeb(LASIPS2_KBD_CONTROL, LASIPS2_KBD_CONTROL_EN); + lasips2_command(ATKBD_CMD_RESET_BAT); + lasips2_command(ATKBD_CMD_RESET_DIS); + lasips2_command(ATKBD_CMD_SSCANSET); + lasips2_command(0x01); + lasips2_command(ATKBD_CMD_ENABLE); + kbd_init(); +} diff --git a/src/parisc/lasips2.h b/src/parisc/lasips2.h new file mode 100644 index 0000000..efdd66b --- /dev/null +++ b/src/parisc/lasips2.h @@ -0,0 +1,17 @@ +#ifndef PARISC_LASIPS2_H +#define PARISC_LASIPS2_H + +void ps2port_setup(void); + +int lasips2_kbd_in(char *c, int max); + +#define LASIPS2_KBD_RESET ((void *)(LASI_PS2KBD_HPA+0x00)) +#define LASIPS2_KBD_DATA ((void *)(LASI_PS2KBD_HPA+0x04)) +#define LASIPS2_KBD_CONTROL ((void *)(LASI_PS2KBD_HPA+0x08)) +#define LASIPS2_KBD_STATUS ((void *)(LASI_PS2KBD_HPA+0x0c)) + +#define LASIPS2_KBD_CONTROL_EN 0x01 +#define LASIPS2_KBD_STATUS_RBNE 0x01 +#define LASIPS2_KBD_STATUS_TBNE 0x02 + +#endif diff --git a/src/parisc/pafirmware.lds.S b/src/parisc/pafirmware.lds.S index 7008596..c72a310 100644 --- a/src/parisc/pafirmware.lds.S +++ b/src/parisc/pafirmware.lds.S @@ -16,6 +16,27 @@ SECTIONS *(.text.*) _etext = . ; } + + . = ALIGN(4096); + .sti : { + _sti_rom_start = .; + *(.sti.hdr) + *(.sti.text.init_graph) + *(.sti.text.state_mgmt) + *(.sti.text.font_unpmv) + *(.sti.text.block_move) + *(.sti.text.self_test) + *(.sti.text.excep_hdlr) + *(.sti.text.inq_conf) + *(.sti.text.set_cm_entry) + *(.sti.text.dma_ctrl) + *(.sti.textend) + *(.sti.text) + *(.sti.data) + . = ALIGN(4096); + _sti_rom_end = .; + } + . = ALIGN(8); .rodata : { _rodata = . ; diff --git a/src/parisc/parisc.c b/src/parisc/parisc.c index 33a17cb..fa74344 100644 --- a/src/parisc/parisc.c +++ b/src/parisc/parisc.c @@ -1,6 +1,7 @@ // Glue code for parisc architecture // // Copyright (C) 2017-2019 Helge Deller <deller@gmx.de> +// Copyright (C) 2019 Sven Schnelle <svens@stackframe.org> // // This file may be distributed under the terms of the GNU LGPLv3 license. @@ -25,6 +26,8 @@ #include "parisc/hppa_hardware.h" // DINO_UART_BASE #include "parisc/pdc.h" #include "parisc/b160l.h" +#include "parisc/sticore.h" +#include "parisc/lasips2.h" #include "vgabios.h" @@ -210,6 +213,9 @@ static hppa_device_t parisc_devices[HPPA_MAX_CPUS+16] = { PARISC_DEVICE_LIST }; LASI_LPT_HPA, \ CPU_HPA,\ MEMORY_HPA,\ + LASI_GFX_HPA,\ + LASI_PS2KBD_HPA, \ + LASI_PS2MOU_HPA, \ 0 static const char *hpa_name(unsigned long hpa) @@ -271,6 +277,11 @@ int HPA_is_storage_device(unsigned long hpa) return (hpa == DINO_SCSI_HPA) || (hpa == IDE_HPA) || (hpa == LASI_SCSI_HPA); } +int HPA_is_keyboard_device(unsigned long hpa) +{ + return (hpa == LASI_PS2KBD_HPA); +} + #define GFX_NUM_PAGES 0x2000 int HPA_is_graphics_device(unsigned long hpa) { @@ -322,7 +333,6 @@ static void remove_parisc_devices(unsigned int num_cpus) /* check if qemu emulates LASI chip (LASI_IAR exists) */ if (*(unsigned long *)(LASI_HPA+16) == 0) { - remove_from_keep_list(LASI_HPA); remove_from_keep_list(LASI_UART_HPA); remove_from_keep_list(LASI_LAN_HPA); remove_from_keep_list(LASI_LPT_HPA); @@ -449,6 +459,29 @@ static unsigned long parisc_serial_in(char *c, unsigned long maxchars) return count; } +static void parisc_serial_out(char c) +{ + for (;;) { + if (c == '\n') + parisc_serial_out('\r'); + const portaddr_t addr = PORT_SERIAL1; + u8 lsr = inb(addr+SEROFF_LSR); + if ((lsr & 0x60) == 0x60) { + // Success - can write data + outb(c, addr+SEROFF_DATA); + break; + } + } +} + +void parisc_screenc(char c) +{ + if (HPA_is_graphics_device(PAGE0->mem_cons.hpa)) + sti_putc(c); + else + parisc_serial_out(c); +} + void iodc_log_call(unsigned int *arg, const char *func) { if (pdc_debug) { @@ -472,8 +505,8 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) struct disk_op_s disk_op; if (1 && - ((HPA_is_serial_device(hpa) && option == ENTRY_IO_COUT) || - (HPA_is_serial_device(hpa) && option == ENTRY_IO_CIN) || + (((HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_COUT) || + ((HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) && option == ENTRY_IO_CIN) || (HPA_is_storage_device(hpa) && option == ENTRY_IO_BOOTIN))) { /* avoid debug messages */ } else { @@ -481,19 +514,23 @@ int __VISIBLE parisc_iodc_ENTRY_IO(unsigned int *arg FUNC_MANY_ARGS) } /* console I/O */ - if (HPA_is_serial_device(hpa)) - switch (option) { - case ENTRY_IO_COUT: /* console output */ - c = (char*)ARG6; - result[0] = len = ARG7; + switch (option) { + case ENTRY_IO_COUT: /* console output */ + c = (char*)ARG6; + result[0] = len = ARG7; + if (HPA_is_serial_device(hpa) || HPA_is_graphics_device(hpa)) { while (len--) printf("%c", *c++); - return PDC_OK; - case ENTRY_IO_CIN: /* console input, with 5 seconds timeout */ - c = (char*)ARG6; + } + return PDC_OK; + case ENTRY_IO_CIN: /* console input, with 5 seconds timeout */ + c = (char*)ARG6; + if (HPA_is_serial_device(hpa)) result[0] = parisc_serial_in(c, ARG7); - return PDC_OK; - } + else if (HPA_is_keyboard_device(hpa)) + result[0] = lasips2_kbd_in(c, ARG7); + return PDC_OK; + } /* boot medium I/O */ if (HPA_is_storage_device(hpa)) @@ -1128,6 +1165,9 @@ static int pdc_add_valid(unsigned int *arg) // if (ARG2 < PAGE_SIZE) return PDC_ERROR; if (ARG2 < ram_size) return PDC_OK; + if (ARG2 >= (unsigned long)_sti_rom_start && + ARG2 <= (unsigned long)_sti_rom_end) + return PDC_OK; if (ARG2 < FIRMWARE_END) return 1; if (ARG2 <= 0xffffffff) @@ -1620,12 +1660,30 @@ static int parisc_boot_menu(unsigned long *iplstart, unsigned long *iplend, * FIRMWARE MAIN ENTRY POINT ********************************************************/ +static const struct pz_device mem_cons_sti_boot = { + .hpa = LASI_GFX_HPA, + .iodc_io = (unsigned long)&iodc_entry, + .cl_class = CL_DISPL, +}; + +static const struct pz_device mem_kbd_sti_boot = { + .hpa = LASI_PS2KBD_HPA, + .iodc_io = (unsigned long)&iodc_entry, + .cl_class = CL_KEYBD, +}; + static const struct pz_device mem_cons_boot = { .hpa = PARISC_SERIAL_CONSOLE - 0x800, - .iodc_io = (unsigned long) &iodc_entry, + .iodc_io = (unsigned long)&iodc_entry, .cl_class = CL_DUPLEX, }; +static const struct pz_device mem_kbd_boot = { + .hpa = PARISC_SERIAL_CONSOLE - 0x800, + .iodc_io = (unsigned long)&iodc_entry, + .cl_class = CL_KEYBD, +}; + static const struct pz_device mem_boot_boot = { .dp.flags = PF_AUTOBOOT, .hpa = IDE_HPA, // DINO_SCSI_HPA, // IDE_HPA @@ -1633,12 +1691,6 @@ static const struct pz_device mem_boot_boot = { .cl_class = CL_RANDOM, }; -static const struct pz_device mem_kbd_boot = { - .hpa = PARISC_SERIAL_CONSOLE - 0x800, - .iodc_io = (unsigned long) &iodc_entry, - .cl_class = CL_KEYBD, -}; - static void find_pci_slot_for_dev(unsigned int pciid, char *pci_slot) { struct pci_device *pci; @@ -1650,59 +1702,6 @@ static void find_pci_slot_for_dev(unsigned int pciid, char *pci_slot) } } -static void parisc_vga_init(void) -{ - extern void vga_post(struct bregs *); - struct pci_device *pci; - - foreachpci(pci) { - if (!is_pci_vga(pci)) - continue; - - VgaBDF = pci->bdf; - - parisc_vga_mem = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_0); - parisc_vga_mem &= PCI_BASE_ADDRESS_MEM_MASK; - VBE_framebuffer = parisc_vga_mem; - parisc_vga_mmio = pci_config_readl(pci->bdf, PCI_BASE_ADDRESS_2); - parisc_vga_mmio &= PCI_BASE_ADDRESS_MEM_MASK; - - dprintf(1, "\n"); - - regs.ax = VgaBDF; - vga_post(®s); - - // flag = MF_NOCLEARMEM ? - // - // vga_set_mode(0x119, MF_NOCLEARMEM); // bochs: MM_DIRECT, 1280, 1024, 15, 8, 16, - // vga_set_mode(0x105, 0); // bochs: { 0x105, { MM_PACKED, 1024, 768, 8, 8, 16, SEG_GRAPH } }, - vga_set_mode(0x107, 0); // bochs: { 0x107, { MM_PACKED, 1280, 1024, 8, 8, 16, SEG_GRAPH } }, - // vga_set_mode(0x11c, 0); // bochs: { 0x11C, { MM_PACKED, 1600, 1200, 8, 8, 16, SEG_GRAPH } }, - // vga_set_mode(0x11f, 0); // bochs: { 0x11F, { MM_DIRECT, 1600, 1200, 24, 8, 16, SEG_GRAPH } }, - // vga_set_mode(0x101, 0); // bochs: { 0x101, { MM_PACKED, 640, 480, 8, 8, 16, SEG_GRAPH } }, - // vga_set_mode(0x100, 0); // bochs: { 0x100, { MM_PACKED, 640, 400, 8, 8, 16, SEG_GRAPH } }, - - u32 endian = *(u32 *)(parisc_vga_mmio + 0x0604); - dprintf(1, "parisc: VGA at %pP, mem 0x%lx mmio 0x%lx endian 0x%x found.\n", - pci, parisc_vga_mem, parisc_vga_mmio, endian); - - struct vgamode_s *vmode_g = get_current_mode(); - int bpp = vga_bpp(vmode_g); - int linelength = vgahw_get_linelength(vmode_g); - - dprintf(1, "parisc: VGA resolution: %dx%d-%d memmodel:%d bpp:%d linelength:%d\n", - vmode_g->width, vmode_g->height, vmode_g->depth, - vmode_g->memmodel, bpp, linelength); - - if (linelength == 0) { - printf( "CRITICAL: Please enable BOCHS video support in SeaBIOS\n"); - BUG_ON(1); - } - - break; // only allow one VGA for now. - } -} - /* Prepare boot paths in PAGE0 and stable memory */ static void prepare_boot_path(volatile struct pz_device *dest, const struct pz_device *source, @@ -1737,6 +1736,10 @@ static void prepare_boot_path(volatile struct pz_device *dest, BUG_ON(sizeof(struct device_path) != 0x20); } +static int artist_present(void) +{ + return !!(*(u32 *)0xf8380004 == 0x6dc20006); +} void __VISIBLE start_parisc_firmware(void) { @@ -1752,13 +1755,6 @@ void __VISIBLE start_parisc_firmware(void) if (ram_size >= FIRMWARE_START) ram_size = FIRMWARE_START; - /* Initialize device list */ - remove_parisc_devices(smp_cpus); - - /* Show list of HPA devices which are still returned by firmware. */ - if (0) { for (i=0; parisc_devices[i].hpa; i++) - printf("Kept #%d at 0x%lx\n", i, parisc_devices[i].hpa); - } /* Initialize PAGE0 */ memset((void*)PAGE0, 0, sizeof(*PAGE0)); @@ -1787,6 +1783,30 @@ void __VISIBLE start_parisc_firmware(void) PAGE0->imm_spa_size = ram_size; PAGE0->imm_max_mem = ram_size; + // Initialize boot paths (disc, display & keyboard) + if (artist_present()) { + sti_rom_init(); + sti_console_init(&sti_proc_rom); + ps2port_setup(); + prepare_boot_path(&(PAGE0->mem_cons), &mem_cons_sti_boot, 0x60); + prepare_boot_path(&(PAGE0->mem_kbd), &mem_kbd_sti_boot, 0xa0); + PAGE0->proc_sti = (u32)&sti_proc_rom; + } else { + remove_from_keep_list(LASI_GFX_HPA); + remove_from_keep_list(LASI_PS2KBD_HPA); + remove_from_keep_list(LASI_PS2MOU_HPA); + prepare_boot_path(&(PAGE0->mem_cons), &mem_cons_boot, 0x60); + prepare_boot_path(&(PAGE0->mem_kbd), &mem_kbd_boot, 0xa0); + } + + /* Initialize device list */ + remove_parisc_devices(smp_cpus); + + /* Show list of HPA devices which are still returned by firmware. */ + if (0) { for (i=0; parisc_devices[i].hpa; i++) + printf("Kept #%d at 0x%lx\n", i, parisc_devices[i].hpa); + } + // Initialize stable storage init_stable_storage(); @@ -1823,9 +1843,6 @@ void __VISIBLE start_parisc_firmware(void) serial_setup(); block_setup(); - // We don't have VGA BIOS, so init now. - parisc_vga_init(); - printf("\n"); printf("Firmware Version 6.1\n" "\n" @@ -1850,12 +1867,13 @@ void __VISIBLE start_parisc_firmware(void) find_initial_parisc_boot_drives(&parisc_boot_harddisc, &parisc_boot_cdrom); printf(" Primary boot path: FWSCSI.%d.%d\n" - " Alternate boot path: FWSCSI.%d.%d\n" - " Console path: SERIAL_%d.9600.8.none\n" - " Keyboard path: PS2\n\n", + " Alternate boot path: FWSCSI.%d.%d\n" + " Console path: %s\n" + " Keyboard path: PS2\n\n", parisc_boot_harddisc->target, parisc_boot_harddisc->lun, parisc_boot_cdrom->target, parisc_boot_cdrom->lun, - (PARISC_SERIAL_CONSOLE == PORT_SERIAL1) ? 1 : 2); + HPA_is_graphics_device(PAGE0->mem_cons.hpa) ? "GRAPHICS(1)" : + ((PARISC_SERIAL_CONSOLE == PORT_SERIAL1) ? "SERIAL_1.9600.8.none" : "SERIAL_2.9600.8.none")); if (bootdrive == 'c') boot_drive = parisc_boot_harddisc; @@ -1872,10 +1890,8 @@ void __VISIBLE start_parisc_firmware(void) mod_path_emulated_drives.layers[1] = parisc_boot_harddisc->lun; } - // Initialize boot paths (disc, display & keyboard) - prepare_boot_path(&(PAGE0->mem_cons), &mem_cons_boot, 0x60); prepare_boot_path(&(PAGE0->mem_boot), &mem_boot_boot, 0x0); - prepare_boot_path(&(PAGE0->mem_kbd), &mem_kbd_boot, 0xa0); + // copy primary boot path to alt boot path memcpy(&stable_storage[0x80], &stable_storage[0], 0x20); if (parisc_boot_cdrom) { diff --git a/src/parisc/sti.c b/src/parisc/sti.c index 1017194..7935770 100644 --- a/src/parisc/sti.c +++ b/src/parisc/sti.c @@ -1,44 +1,172 @@ -// VGA / STI code for parisc architecture -// -// Copyright (C) 2017 Helge Deller <deller@gmx.de> -// -// This file may be distributed under the terms of the GNU LGPLv3 license. +/* STI console code + * + * Copyright (C) 2019 Sven Schnelle <svens@stackframe.org> + * + * This file may be distributed under the terms of the GNU LGPLv3 license. + */ #include "autoconf.h" #include "types.h" #include "std/optionrom.h" -#include "hw/pci.h" // pci_config_readl -#include "hw/pci_regs.h" // PCI_BASE_ADDRESS_0 #include "vgahw.h" #include "parisc/sticore.h" +#include "output.h" +#include "pdc.h" -/**************************************************************** - * PCI Data - ****************************************************************/ -#if 0 -struct pci_data __VISIBLE rom_pci_data = { - .signature = PCI_ROM_SIGNATURE, - .vendor = CONFIG_VGA_VID, - .device = CONFIG_VGA_DID, - .dlen = 0x18, - .class_hi = 0x300, - .irevision = 1, - .type = PCIROM_CODETYPE_X86, - .indicator = 0x80, -}; -#endif - -extern void handle_100e(struct bregs *regs); - -void parisc_teletype_output(struct bregs *regs) +#define PAGE0 ((volatile struct zeropage *) 0UL) + +static int sti_enabled; + +static struct sti_init_flags sti_init_flags = { + .wait = 1, + .reset = 1, + .text = 1, + .nontext = 1, + .cmap_blk = 1, + .no_chg_bet = 1, + .no_chg_bei = 1, + .init_cmap_tx = 1, +}; + +static struct sti_glob_cfg_ext sti_glob_ext_cfg = { +}; + +static struct sti_glob_cfg sti_glob_cfg = { + .region_ptrs = { 0, 0xf9000000, 0xf8100000, 0xf8380000, 0, 0, 0, 0 }, + .ext_ptr = (u32)&sti_glob_ext_cfg, +}; + +static struct sti_init_inptr_ext sti_init_inptr_ext = { + .config_mon_type = 1, +}; + +static struct sti_init_inptr sti_init_inptr = { + .text_planes = 3, + .ext_ptr = (u32)&sti_init_inptr_ext, +}; + +static struct sti_init_outptr sti_init_outptr = { +}; + +static struct sti_font_flags sti_font_flags = { + .wait = 1, +}; + +static struct sti_font_inptr sti_font_inptr = { + .fg_color = 1, + .bg_color = 0, +}; + +static struct sti_font_outptr sti_font_outptr = { +}; + +static struct sti_blkmv_flags sti_blkmv_flags = { + .wait = 1, +}; + +static struct sti_blkmv_inptr sti_blkmv_inptr = { +}; + +static struct sti_blkmv_outptr sti_blkmv_outptr = { +}; + +static void sti_putchar(struct sti_rom *rom, int row, int column, const char c) +{ + int (*sti_unpmv)(struct sti_font_flags *, + struct sti_font_inptr *, + struct sti_font_outptr *, + struct sti_glob_cfg *); + + struct sti_rom_font *font = (void *)rom + rom->font_start; + sti_unpmv = (void *)rom + rom->font_unpmv; + + sti_font_inptr.dest_x = column * font->width; + sti_font_inptr.dest_y = row * font->height; + sti_font_inptr.index = c; + sti_font_inptr.font_start_addr = (u32)rom + rom->font_start; + + sti_unpmv(&sti_font_flags, &sti_font_inptr, + &sti_font_outptr, &sti_glob_cfg); +} + +static void sti_block_move(struct sti_rom *rom, int src_x, int src_y, + int dest_x, int dest_y, + int width, int height, + int clear) +{ + int (*sti_block_move)(struct sti_blkmv_flags *, + struct sti_blkmv_inptr *, + struct sti_blkmv_outptr *, + struct sti_glob_cfg *); + sti_block_move = (void *)rom + rom->block_move; + + sti_blkmv_inptr.src_x = src_x; + sti_blkmv_inptr.src_y = src_y; + sti_blkmv_inptr.dest_x = dest_x; + sti_blkmv_inptr.dest_y = dest_y; + sti_blkmv_inptr.width = width; + sti_blkmv_inptr.height = height; + sti_blkmv_flags.clear = clear; + + sti_block_move(&sti_blkmv_flags, &sti_blkmv_inptr, + &sti_blkmv_outptr, &sti_glob_cfg); +} + +void sti_console_init(struct sti_rom *rom) { - // re-read PCI addresses. Linux kernel reconfigures those at boot. - parisc_vga_mem = pci_config_readl(VgaBDF, PCI_BASE_ADDRESS_0); - parisc_vga_mem &= PCI_BASE_ADDRESS_MEM_MASK; - VBE_framebuffer = parisc_vga_mem; - parisc_vga_mmio = pci_config_readl(VgaBDF, PCI_BASE_ADDRESS_2); - parisc_vga_mmio &= PCI_BASE_ADDRESS_MEM_MASK; - - handle_100e(regs); + int (*sti_init)(struct sti_init_flags *, + struct sti_init_inptr *, + struct sti_init_outptr *, + struct sti_glob_cfg *); + + sti_init = (void *)rom + rom->init_graph; + + sti_init(&sti_init_flags, &sti_init_inptr, + &sti_init_outptr, &sti_glob_cfg); + + sti_enabled = 1; } +void sti_putc(const char c) +{ + struct sti_rom *rom = (struct sti_rom *)PAGE0->proc_sti; + struct sti_rom_font *font = (void *)rom + rom->font_start; + static int row, col; + + if (!sti_enabled) + return; + + if (c == '\r') { + col = 0; + return; + } + + if (c == 0x08) { + if (col > 0) + col--; + return; + } + + if (c == '\n') { + col = 0; + row++; + + if (row >= sti_glob_cfg.onscreen_y / font->height) { + sti_block_move(rom, + 0, font->height, + 0, 0, + sti_glob_cfg.total_x, sti_glob_cfg.onscreen_y - font->height, 0); + + /* clear new line at bottom */ + sti_block_move(rom, + 0, 0, /* source */ + 0, sti_glob_cfg.onscreen_y - font->height, /* dest */ + sti_glob_cfg.onscreen_x, font->height, + 1); + + row = (sti_glob_cfg.onscreen_y / font->height)-1; + } + return; + } + sti_putchar(rom, row, col++, c); +} diff --git a/src/parisc/sticore.h b/src/parisc/sticore.h index 0ce1016..8c3a98a 100644 --- a/src/parisc/sticore.h +++ b/src/parisc/sticore.h @@ -1,369 +1,326 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +/* SPDX-License-Identifier:GPL-2.0 */ #ifndef STICORE_H #define STICORE_H +#include "types.h" + /* generic STI structures & functions */ -#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ +#define MAX_STI_ROMS 4 /* max no. of ROMs which this driver handles */ -#define STI_REGION_MAX 8 /* hardcoded STI constants */ +#define STI_REGION_MAX 8 /* hardcoded STI constants */ #define STI_DEV_NAME_LENGTH 32 #define STI_MONITOR_MAX 256 #define STI_FONT_HPROMAN8 1 #define STI_FONT_KANA8 2 -#define ALT_CODE_TYPE_UNKNOWN 0x00 /* alt code type values */ +#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 - * function exited with 1 as return value. - * - * As all of the functions below could be called from interrupt context, - * we have to spin_lock_irqsave around the do { ret = bla(); } while(ret==1) - * block. Really bad latency there. - * - * Probably the best solution to all this is have the generic code manage - * the screen buffer and a kernel thread to call STI occasionally. - * - * Luckily, the frame buffer guys have the same problem so we can just wait - * for them to fix it and steal their solution. prumpf - */ - #define STI_WAIT 1 -#define STI_PTR(p) ( virt_to_phys(p) ) -#define PTR_STI(p) ( phys_to_virt((unsigned long)p) ) - -#define sti_onscreen_x(sti) (sti->glob_cfg->onscreen_x) -#define sti_onscreen_y(sti) (sti->glob_cfg->onscreen_y) - -/* sti_font_xy() use the native font ROM ! */ -#define sti_font_x(sti) (PTR_STI(sti->font)->width) -#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 */ typedef union region { - struct { - u32 offset : 14; /* offset in 4kbyte page */ - u32 sys_only : 1; /* don't map to user space */ - u32 cache : 1; /* map to data cache */ - u32 btlb : 1; /* map to block tlb */ - u32 last : 1; /* last region in list */ - u32 length : 14; /* length in 4kbyte page */ - } region_desc; - - u32 region; /* complete region value */ + struct { + u32 offset:14; /* offset in 4kbyte page */ + u32 sys_only:1; /* don't map to user space */ + u32 cache:1; /* map to data cache */ + u32 btlb:1; /* map to block tlb */ + u32 last:1; /* last region in list */ + u32 length:14; /* length in 4kbyte page */ + } region_desc; + + u32 region; /* complete region value */ } region_t; -#define REGION_OFFSET_TO_PHYS( rt, hpa ) \ - (((rt).region_desc.offset << 12) + (hpa)) - struct sti_glob_cfg_ext { - u8 curr_mon; /* current monitor configured */ - 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 */ + u8 curr_mon; /* current monitor configured */ + 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 */ }; struct sti_glob_cfg { - s32 text_planes; /* number of planes used for text */ - s16 onscreen_x; /* screen width in pixels */ - s16 onscreen_y; /* screen height in pixels */ - s16 offscreen_x; /* offset width in pixels */ - 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 */ - 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 */ + s32 text_planes; /* number of planes used for text */ + s16 onscreen_x; /* screen width in pixels */ + s16 onscreen_y; /* screen height in pixels */ + s16 offscreen_x; /* offset width in pixels */ + 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 */ + 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 { - u32 wait : 1; /* should routine idle wait or not */ - u32 reset : 1; /* hard reset the device? */ - u32 text : 1; /* turn on text display planes? */ - u32 nontext : 1; /* turn on non-text display planes? */ - u32 clear : 1; /* clear text display planes? */ - u32 cmap_blk : 1; /* non-text planes cmap black? */ - u32 enable_be_timer : 1; /* enable bus error timer */ - u32 enable_be_int : 1; /* enable bus error timer interrupt */ - u32 no_chg_tx : 1; /* don't change text settings */ - u32 no_chg_ntx : 1; /* don't change non-text settings */ - u32 no_chg_bet : 1; /* don't change berr timer settings */ - u32 no_chg_bei : 1; /* don't change berr int settings */ - u32 init_cmap_tx : 1; /* initialize cmap for text planes */ - u32 cmt_chg : 1; /* change current monitor type */ - u32 retain_ie : 1; /* don't allow reset to clear int enables */ - u32 caller_bootrom : 1; /* set only by bootrom for each call */ - 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 wait:1; /* should routine idle wait or not */ + u32 reset:1; /* hard reset the device? */ + u32 text:1; /* turn on text display planes? */ + u32 nontext:1; /* turn on non-text display planes? */ + u32 clear:1; /* clear text display planes? */ + u32 cmap_blk:1; /* non-text planes cmap black? */ + u32 enable_be_timer:1; /* enable bus error timer */ + u32 enable_be_int:1; /* enable bus error timer interrupt */ + u32 no_chg_tx:1; /* don't change text settings */ + u32 no_chg_ntx:1; /* don't change non-text settings */ + u32 no_chg_bet:1; /* don't change berr timer settings */ + u32 no_chg_bei:1; /* don't change berr int settings */ + u32 init_cmap_tx:1; /* initialize cmap for text planes */ + u32 cmt_chg:1; /* change current monitor type */ + u32 retain_ie:1; /* don't allow reset to clear int enables */ + u32 caller_bootrom:1; /* set only by bootrom for each call */ + 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 */ }; 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 */ + 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 */ }; struct sti_init_inptr { - s32 text_planes; /* number of planes to use for text */ - u32 ext_ptr; /* pointer to extended init_graph inptr data structure*/ + s32 text_planes; /* number of planes to use for text */ + u32 ext_ptr; /* pointer to extended init_graph inptr data structure*/ }; 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 */ + s32 errno; /* error number on failure */ + s32 text_planes; /* number of planes used for text */ + u32 future_ptr; /* pointer to future data */ }; - - /* STI configuration function structs */ 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 wait:1; /* should routine idle wait or not */ + u32 pad:31; /* pad to word boundary */ + 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 crt_config[3]; /* hardware specific X11/OGL information */ + u32 crt_hdw[3]; + u32 future_ptr; }; struct sti_conf_outptr { - s32 errno; /* error number on failure */ - s16 onscreen_x; /* screen width in pixels */ - s16 onscreen_y; /* screen height in pixels */ - s16 offscreen_x; /* offscreen width in pixels */ - s16 offscreen_y; /* offscreen height in pixels */ - s16 total_x; /* frame buffer width in pixels */ - s16 total_y; /* frame buffer height in pixels */ - s32 bits_per_pixel; /* bits/pixel device has configured */ - s32 bits_used; /* bits which can be accessed */ - s32 planes; /* number of fb planes in system */ - u8 dev_name[STI_DEV_NAME_LENGTH]; /* null terminated product name */ - u32 attributes; /* flags denoting attributes */ - u32 ext_ptr; /* pointer to future data */ + s32 errno; /* error number on failure */ + s16 onscreen_x; /* screen width in pixels */ + s16 onscreen_y; /* screen height in pixels */ + s16 offscreen_x; /* offscreen width in pixels */ + s16 offscreen_y; /* offscreen height in pixels */ + s16 total_x; /* frame buffer width in pixels */ + s16 total_y; /* frame buffer height in pixels */ + s32 bits_per_pixel; /* bits/pixel device has configured */ + s32 bits_used; /* bits which can be accessed */ + s32 planes; /* number of fb planes in system */ + u8 dev_name[STI_DEV_NAME_LENGTH]; /* null terminated product name */ + u32 attributes; /* flags denoting attributes */ + u32 ext_ptr; /* pointer to future data */ }; -struct sti_rom { - u8 type[4]; - u8 res004; - u8 num_mons; - u8 revno[2]; - u32 graphics_id[2]; - - u32 font_start; - u32 statesize; - u32 last_addr; - u32 region_list; - - u16 reentsize; - u16 maxtime; - u32 mon_tbl_addr; - u32 user_data_addr; - u32 sti_mem_req; - - u32 user_data_size; - u16 power; - u8 bus_support; - u8 ext_bus_support; - u8 alt_code_type; - u8 ext_dd_struct[3]; - u32 cfb_addr; - - u32 init_graph; - u32 state_mgmt; - u32 font_unpmv; - u32 block_move; - u32 self_test; - u32 excep_hdlr; - u32 inq_conf; - u32 set_cm_entry; - u32 dma_ctrl; - u8 res040[7 * 4]; - - 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]; -}; +typedef struct { + u32 x:12; + u32 y:12; + u32 hz:7; + u32 class_flat:1; + u32 class_vesa:1; + u32 class_grey:1; + u32 class_dbl:1; + u32 class_user:1; + u32 class_stereo:1; + u32 class_sam:1; + u32 pad:15; + u32 hz_upper:3; + u32 index:8; +} mon_tbl_desc; -struct sti_rom_font { - u16 first_char; - u16 last_char; - u8 width; - u8 height; - u8 font_type; /* language type */ - u8 bytes_per_char; - u32 next_font; - u8 underline_height; - u8 underline_pos; - u8 res008[2]; +struct sti_rom { + u8 type[4]; + u8 res004; + u8 num_mons; + u8 revno[2]; + u32 graphics_id[2]; + + u32 font_start; + u32 statesize; + u32 last_addr; + u32 region_list; + + u16 reentsize; + u16 maxtime; + u32 mon_tbl_addr; + u32 user_data_addr; + u32 sti_mem_req; + + u32 user_data_size; + u16 power; + u8 bus_support; + u8 ext_bus_support; + u8 alt_code_type; + u8 ext_dd_struct[3]; + u32 cfb_addr; + + u32 init_graph; + u32 state_mgmt; + u32 font_unpmv; + u32 block_move; + u32 self_test; + u32 excep_hdlr; + u32 inq_conf; + u32 set_cm_entry; + u32 dma_ctrl; + u32 flow_ctrl; + u32 user_timing; + u32 process_mgr; + u32 sti_util; + u32 end; + + u32 res040[2]; + + 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]; }; -/* sticore internal font handling */ -struct sti_cooked_font { - struct sti_rom_font *raw; - struct sti_cooked_font *next_font; +struct sti_rom_font { + u16 first_char; + u16 last_char; + u8 width; + u8 height; + u8 font_type; /* language type */ + u8 bytes_per_char; + u32 next_font; + u8 underline_height; + u8 underline_pos; + u8 res008[2]; }; -struct sti_cooked_rom { - struct sti_rom *raw; - struct sti_cooked_font *font_start; +struct font { + struct sti_rom_font hdr; + char font[16*256]; }; /* STI font printing function structs */ struct sti_font_inptr { - u32 font_start_addr; /* 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 font_start_addr; /* 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 */ }; 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 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 */ }; - + struct sti_font_outptr { - s32 errno; /* error number on failure */ - u32 future_ptr; /* pointer to future data */ + s32 errno; /* error number on failure */ + u32 future_ptr; /* pointer to future data */ }; /* STI blockmove structs */ struct sti_blkmv_flags { - u32 wait : 1; /* should routine idle wait or not */ - u32 color : 1; /* change color during move? */ - 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 wait:1; /* should routine idle wait or not */ + u32 color:1; /* change color during move? */ + 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 */ }; struct sti_blkmv_inptr { - u8 fg_color; /* foreground color after move */ - u8 bg_color; /* background color after move */ - s16 src_x; /* source upper left pixel x location */ - s16 src_y; /* source upper left pixel y location */ - s16 dest_x; /* dest upper left pixel x location */ - 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 */ + u8 fg_color; /* foreground color after move */ + u8 bg_color; /* background color after move */ + s16 src_x; /* source upper left pixel x location */ + s16 src_y; /* source upper left pixel y location */ + s16 dest_x; /* dest upper left pixel x location */ + 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 */ }; struct sti_blkmv_outptr { - s32 errno; /* error number on failure */ - u32 future_ptr; /* pointer to future data */ + s32 errno; /* error number on failure */ + u32 future_ptr; /* pointer to future data */ }; - -/* 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 ! */ +struct sti_state_flags { + u32 wait:1; /* should routing idle wait or not */ + u32 save:1; /* save (1) or restore (0) state */ + u32 res_disp:1; /* restore all display planes */ + u32 pad:29; /* pad to word boundary */ + s32 *future_ptr; /* pointer to future data */ }; -/* internal generic STI struct */ - -struct sti_struct { - /* the following fields needs to be filled in by the word/byte routines */ - int font_width; - int font_height; - /* char **mon_strings; */ - int sti_mem_request; - u32 graphics_id[2]; - - struct sti_cooked_rom *rom; - - unsigned long font_unpmv; - unsigned long block_move; - unsigned long init_graph; - unsigned long inq_conf; - - /* all following fields are initialized by the generic routines */ - int text_planes; - region_t regions[STI_REGION_MAX]; - unsigned long regions_phys[STI_REGION_MAX]; +struct sti_state_inptr { + s32 *save_addr; /* where to save or restore state */ + s32 *future_ptr; /* pointer to future data */ +}; - struct sti_glob_cfg *glob_cfg; /* points into sti_all_data */ +struct sti_state_outptr { + s32 errno; /* error number on failure */ + s32 *future_ptr; /* pointer to future data */ +}; - struct sti_cooked_font *font; /* ptr to selected font (cooked) */ +struct setcm_flags { + u32 wait:1; /* should routine idle wait or not */ + u32 pad:31; /* pad to word boundary */ + s32 *future_ptr; /* pointer to future data */ +}; - struct pci_dev *pd; +struct setcm_inptr { + s32 entry; /* entry number */ + u32 value; /* entry value */ + s32 *future_ptr; /* pointer to future data */ +}; - /* PCI data structures (pg. 17ff from sti.pdf) */ - u8 rm_entry[16]; /* pci region mapper array == pci config space offset */ +struct setcm_outptr { + s32 errno; /* error number on failure */ + s32 *future_ptr; /* pointer to future data */ +}; - /* pointer to the fb_info where this STI device is used */ - struct fb_info *info; +void sti_rom_init(void); +void sti_console_init(struct sti_rom *rom); +void sti_putc(const char c); - /* pointer to all internal data */ - struct sti_all_data *sti_data; -}; +extern struct sti_rom sti_proc_rom; +extern char _sti_rom_end[]; +extern char _sti_rom_start[]; +extern void parisc_screenc(char c); -#endif /* STICORE_H */ +#endif /* STICORE_H */ diff --git a/src/parisc/stirom.c b/src/parisc/stirom.c new file mode 100644 index 0000000..feaadd9 --- /dev/null +++ b/src/parisc/stirom.c @@ -0,0 +1,555 @@ +#include "sticore.h" +#include "hppa.h" + +#define ARTIST_VRAM_IDX 0x4a0 +#define ARTIST_VRAM_BITMASK 0x5a0 +#define ARTIST_VRAM_WRITE_INCR_X 0x600 +#define ARTIST_VRAM_BYTE_WRITE 0x620 +#define ARTIST_CMAP_ACCESS 0x18000 +#define ARTIST_DST_BM_ACCESS 0x18004 +#define ARTIST_SRC_BM_ACCESS 0x18008 +#define ARTIST_BGCOLOR 0x18014 +#define ARTIST_FGCOLOR 0x18010 +#define ARTIST_BITMAP_OP 0x1801c +#define ARTIST_PLANE_BITMASK 0x18018 +#define ARTIST_VRAM_DEST 0x800 +#define ARTIST_VRAM_SIZE 0x804 +#define ARTIST_VRAM_SRC 0x808 + +#define ARTIST_VRAM_SIZE_TRIGGER_WINFILL 0xa04 +#define ARTIST_VRAM_DEST_TRIGGER_BLOCKMOVE 0xb00 + +#define __stiheader __attribute__((section(".sti.hdr"))) +#define __stidata __attribute__((section(".sti.data"))) +#define __stitext __attribute__((section(".sti.text"))) + +/* Don't ask - HP-UX assumes a certain order of functions + * when it copies them to RAM. So we put the functions into + * different sections and order them in the linker script. + */ + +#define __stifunc(_name) __attribute__((section(".sti.text." _name))) + +static const __stidata char user_data[256]; +static const u32 sti_region_list[STI_REGION_MAX] __stidata = { 0x8002, 0x40009000, 0x04008280, 0x0e024001, 0, 0 }; +static const struct font __stidata sti_rom_font = { + .hdr = { + .first_char = 0, + .last_char = 0, + .width = 8, + .height = 16, + .font_type = STI_FONT_HPROMAN8, + .bytes_per_char = 16, + .underline_height = 1, + .underline_pos = 15, + }, + .font = { + 0x00, 0x48, 0x68, 0x58, 0x48, 0x48, 0x00, 0x12, 0x12, 0x12, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x22, 0x14, 0x08, 0x14, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x1c, 0x22, 0x22, 0x2a, 0x1c, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x78, 0x48, 0x48, 0x00, 0x12, 0x14, 0x18, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x0e, 0x10, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x40, 0x40, 0x40, 0x40, 0x78, 0x00, 0x1e, 0x10, 0x1c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x3e, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x00, 0x1e, 0x10, 0x1c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x00, 0x1c, 0x12, 0x1c, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x0e, 0x04, 0x04, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x04, 0x0c, 0x04, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x48, 0x48, 0x70, 0x0c, 0x12, 0x02, 0x0c, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x1c, 0x02, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x48, 0x48, 0x70, 0x00, 0x14, 0x14, 0x1e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x68, 0x58, 0x48, 0x48, 0x00, 0x12, 0x14, 0x18, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x22, 0x14, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x00, 0x12, 0x1a, 0x16, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x22, 0x36, 0x2a, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x30, 0x08, 0x70, 0x00, 0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x78, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x00, 0x0e, 0x10, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x58, 0x48, 0x38, 0x00, 0x0e, 0x10, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x50, 0x48, 0x00, 0x0e, 0x10, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x0e, 0x10, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x28, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x38, 0x54, 0x50, 0x30, 0x18, 0x14, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x54, 0x28, 0x08, 0x10, 0x10, 0x20, 0x24, 0x4a, 0x44, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x30, 0x48, 0x48, 0x50, 0x20, 0x50, 0x8a, 0x84, 0x8c, 0x72, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x10, 0x10, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x10, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x54, 0x38, 0x7c, 0x38, 0x54, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0xfe, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x5a, 0x5a, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x02, 0x02, 0x0c, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x02, 0x02, 0x1c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x04, 0x0c, 0x14, 0x24, 0x44, 0x7e, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x30, 0x30, 0x10, 0x20, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x40, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x04, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x02, 0x02, 0x04, 0x08, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x4e, 0x52, 0x52, 0x52, 0x4c, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x4e, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0e, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x44, 0x48, 0x50, 0x70, 0x48, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x66, 0x5a, 0x5a, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x62, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x46, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x4a, 0x3c, 0x04, 0x02, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0x7c, 0x50, 0x48, 0x44, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x44, 0x28, 0x28, 0x28, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x5a, 0x5a, 0x66, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x42, 0x42, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x02, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x20, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x1c, 0x22, 0x20, 0x20, 0x20, 0x78, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x7c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x18, 0x00, + 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x44, 0x48, 0x50, 0x68, 0x44, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x7c, 0x40, 0x40, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x46, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x32, 0x20, 0x20, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x40, 0x3c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x92, 0x92, 0x92, 0x92, 0x6c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x24, 0x18, 0x18, 0x24, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x04, 0x08, 0x10, 0x20, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x10, 0x10, 0x10, 0x10, 0x20, 0x10, 0x10, 0x10, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x00, 0x00, 0x30, 0x08, 0x08, 0x08, 0x08, 0x04, 0x08, 0x08, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x2a, 0x54, 0x2a, 0x54, 0x2a, 0x54, 0x2a, 0x54, 0x2a, 0x54, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x20, 0x20, 0x20, 0x70, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x0c, 0x10, 0x16, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x20, 0x20, 0x20, 0x70, 0x00, 0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x48, 0x48, 0x48, 0x30, 0x00, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x70, 0x20, 0x20, 0x20, 0x70, 0x00, 0x22, 0x22, 0x14, 0x14, 0x08, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x0c, 0x10, 0x16, 0x12, 0x0c, 0x00, 0xff, 0x00, 0x00, + 0x00, 0x70, 0x20, 0x20, 0x20, 0x70, 0x00, 0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00, 0xff, 0x00, 0x00, + 0x00, 0xa8, 0xa8, 0xa8, 0xa8, 0x50, 0x00, 0x12, 0x12, 0x1e, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x50, 0x48, 0x00, 0x1c, 0x12, 0x12, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x48, 0x48, 0x30, 0x10, 0x10, 0x00, 0x1e, 0x10, 0x1c, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x40, 0x58, 0x48, 0x30, 0x00, 0x1c, 0x12, 0x1c, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x38, 0x40, 0x40, 0x40, 0x38, 0x00, 0x12, 0x12, 0x0c, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x12, 0x12, 0x12, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xd8, 0xa8, 0x88, 0x88, 0x00, 0x0c, 0x10, 0x16, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x12, 0x14, 0x18, 0x14, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x04, 0x0c, 0x04, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0c, 0x12, 0x04, 0x08, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1c, 0x02, 0x1c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x14, 0x14, 0x1e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1e, 0x10, 0x1c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0c, 0x10, 0x1c, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1e, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0c, 0x12, 0x0c, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x78, 0x08, 0x30, 0x00, 0x0c, 0x12, 0x1e, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1c, 0x12, 0x1c, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x0e, 0x10, 0x10, 0x10, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1c, 0x12, 0x12, 0x12, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1e, 0x10, 0x1c, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x30, 0x48, 0x38, 0x08, 0x30, 0x00, 0x1e, 0x10, 0x1c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x14, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x28, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x08, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x12, 0x10, 0x3c, 0x10, 0x3c, 0x10, 0x70, 0x91, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x48, 0x70, 0x48, 0x70, 0x00, 0x04, 0x0c, 0x04, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x42, 0x3c, 0x10, 0x08, 0x10, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x42, 0x3c, 0x10, 0x08, 0x10, 0x00, + 0x32, 0x4c, 0x00, 0x42, 0x62, 0x52, 0x52, 0x4a, 0x4a, 0x46, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x5c, 0x62, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x20, 0x40, 0x40, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x41, 0x22, 0x1c, 0x22, 0x22, 0x22, 0x22, 0x1c, 0x22, 0x41, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0c, 0x12, 0x10, 0x10, 0x3c, 0x10, 0x10, 0x70, 0x91, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x82, 0x44, 0x28, 0x10, 0x7c, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x1c, 0x20, 0x20, 0x10, 0x18, 0x24, 0x24, 0x18, 0x08, 0x04, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, 0x08, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x20, 0xc0, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x3e, 0x49, 0x48, 0x48, 0x49, 0x3e, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x14, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3c, 0x42, 0x7e, 0x40, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x18, 0x24, 0x18, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x10, 0x28, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3d, 0x42, 0x46, 0x4a, 0x4a, 0x52, 0x52, 0x62, 0x42, 0xbc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3f, 0x48, 0x48, 0x48, 0x7e, 0x48, 0x48, 0x48, 0x48, 0x4f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x08, 0x14, 0x08, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x42, 0x4e, 0x72, 0x42, 0xbc, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x09, 0x3f, 0x48, 0x49, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x10, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x00, 0x7e, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x40, 0x7e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x30, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x18, 0x24, 0x44, 0x48, 0x70, 0x48, 0x44, 0x44, 0x64, 0x58, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x28, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x4c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x7e, 0x42, 0x42, 0x42, 0x42, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x42, 0x3e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7c, 0x42, 0x42, 0x42, 0xe2, 0x42, 0x42, 0x42, 0x42, 0x7c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x07, 0x02, 0x3e, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x10, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x08, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x32, 0x4c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x32, 0x4c, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x10, 0x00, 0x3c, 0x42, 0x40, 0x40, 0x3c, 0x02, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x28, 0x10, 0x00, 0x3c, 0x40, 0x3c, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, + 0x24, 0x00, 0x41, 0x41, 0x22, 0x14, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x42, 0x42, 0x42, 0x42, 0x42, 0x3e, 0x02, 0x02, 0x3c, 0x00, + 0x00, 0x00, 0x38, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x1c, 0x12, 0x12, 0x1c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x00, 0x0c, 0x12, 0x04, 0x08, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x00, 0x1c, 0x02, 0x0c, 0x02, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x78, 0x40, 0x70, 0x40, 0x40, 0x00, 0x14, 0x14, 0x1e, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x70, 0x20, 0x20, 0x20, 0x70, 0x00, 0x0c, 0x12, 0x12, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x60, 0x22, 0x24, 0x28, 0x14, 0x2c, 0x54, 0x1e, 0x04, 0x0e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x20, 0x60, 0x22, 0x24, 0x28, 0x10, 0x2c, 0x52, 0x04, 0x08, 0x1e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x02, 0x3e, 0x42, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3c, 0x42, 0x42, 0x42, 0x3c, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x09, 0x12, 0x24, 0x48, 0x24, 0x12, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x48, 0x24, 0x12, 0x09, 0x12, 0x24, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x7e, 0x5a, 0x5a, 0x56, 0x4e, 0x56, 0x5a, 0x5a, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, + } +}; + +static const mon_tbl_desc __stidata sti_mon_table[1] = { + { .x = 1280, .y = 1024, .hz = 70, .class_vesa = 1, .index = 0 } +}; + +struct sti_rom __stiheader sti_proc_rom = { + .type = { 0x03, 0x03, 0x03, 0x03 }, + .num_mons = 1, + .revno = { 0x84, 0x07 }, + .graphics_id = { 0x2b4ded6d, 0x40a00499 }, +}; + +static void __stitext write_artist(struct sti_glob_cfg *cfg, + int reg, u32 val) +{ + writel((void *)cfg->region_ptrs[2] + reg, val); +} + +static int __stifunc("state_mgmt") sti_state_mgmt(struct sti_state_flags *flags, + struct sti_state_inptr *in, + struct sti_state_outptr *out, + struct sti_glob_cfg *cfg) +{ + (void)flags; + (void)in; + (void)cfg; + out->errno = 0; + return 0; +} + +static u32 __stifunc("block_move") sti_bmove(struct sti_blkmv_flags *flags, + struct sti_blkmv_inptr *in, + struct sti_blkmv_outptr *out, + struct sti_glob_cfg *cfg) +{ + write_artist(cfg, ARTIST_PLANE_BITMASK, 0xffffffff); + write_artist(cfg, ARTIST_BITMAP_OP, 0x03000300); + write_artist(cfg, ARTIST_SRC_BM_ACCESS, 0x2ea01000); + write_artist(cfg, ARTIST_DST_BM_ACCESS, 0x2ea01000); + write_artist(cfg, ARTIST_FGCOLOR, in->fg_color); + write_artist(cfg, ARTIST_BGCOLOR, in->bg_color); + + if (flags->clear) { + write_artist(cfg, ARTIST_VRAM_DEST, (in->dest_x << 16) | (in->dest_y)); + barrier(); + write_artist(cfg, ARTIST_VRAM_SIZE_TRIGGER_WINFILL, + (in->width << 16) | (in->height)); + } else { + write_artist(cfg, ARTIST_VRAM_SIZE, (in->width << 16) | (in->height)); + write_artist(cfg, ARTIST_VRAM_SRC, (in->src_x << 16) | (in->src_y)); + barrier(); + write_artist(cfg, ARTIST_VRAM_DEST_TRIGGER_BLOCKMOVE, + (in->dest_x << 16) | (in->dest_y)); + } + out->errno = 0; + return 0; +} + +static int __stifunc("font_unpmv") sti_font_unpmv(struct sti_font_flags *flags, + struct sti_font_inptr *in, + struct sti_font_outptr *out, + struct sti_glob_cfg *cfg) +{ + unsigned char *src = (unsigned char *)in->font_start_addr \ + + sizeof(struct sti_rom_font) + (in->index * 16); + int y; + (void)flags; + + write_artist(cfg, ARTIST_VRAM_IDX, + (in->dest_y << 13) | (in->dest_x << 2)); + + write_artist(cfg, ARTIST_FGCOLOR, in->fg_color); + write_artist(cfg, ARTIST_BGCOLOR, in->bg_color); + write_artist(cfg, ARTIST_BITMAP_OP, 0x23000300); + write_artist(cfg, ARTIST_VRAM_BITMASK, 0xff000000); + write_artist(cfg, ARTIST_DST_BM_ACCESS, 0x2ea01000); + write_artist(cfg, ARTIST_PLANE_BITMASK, 7); + barrier(); + + for(y = 0; y < 16; y++) { + write_artist(cfg, ARTIST_VRAM_BYTE_WRITE, src[y] << 24); + barrier(); + } + out->errno = 0; + return 0; +} + +static int __stifunc("init_graph") sti_init_graph(struct sti_init_flags *flags, + struct sti_init_inptr *in, + struct sti_init_outptr *out, + struct sti_glob_cfg *cfg) +{ + u32 *cmap = (u32 *)cfg->region_ptrs[1]; + + out->errno = 0; + out->text_planes = in->text_planes; + + cfg->text_planes = 8; + cfg->onscreen_x = 1280; + cfg->onscreen_y = 1024; + cfg->offscreen_x = 0; + cfg->offscreen_y = 0; + cfg->total_x = 1280; + cfg->total_y = 1024; + + if (flags->clear) { + /* clear screen */ + write_artist(cfg, ARTIST_VRAM_BITMASK, 0xffffffff); + write_artist(cfg, ARTIST_FGCOLOR, 1); + write_artist(cfg, ARTIST_BGCOLOR, 0); + write_artist(cfg, ARTIST_VRAM_DEST, 0); + barrier(); + write_artist(cfg, ARTIST_VRAM_SIZE_TRIGGER_WINFILL, + (cfg->total_x << 16) | cfg->total_y); + } + + if (flags->init_cmap_tx) { + /* STI color map */ + write_artist(cfg, ARTIST_CMAP_ACCESS, 0x3ba0f000); + cmap[0x100] = 0x000000; /* black */ + cmap[0x101] = 0xffffff; /* white */ + cmap[0x102] = 0xff0000; /* red */ + cmap[0x103] = 0xffff00; /* yellow */ + cmap[0x104] = 0x00ff00; /* green */ + cmap[0x105] = 0x00ffff; /* cyan */ + cmap[0x106] = 0x0000ff; /* blue */ + cmap[0x107] = 0xff00ff; /* magenta */ + write_artist(cfg, ARTIST_DST_BM_ACCESS, 0x2ea0f000); + } + return 0; +} + +static __stifunc("self_test") int sti_self_test(struct sti_init_flags *flags, + struct sti_init_inptr *in, + struct sti_init_outptr *out, + struct sti_glob_cfg *cfg) +{ + (void)flags; + (void)in; + (void)cfg; + + out->errno = 0; + return 0; +} + +static __stifunc("inq_conf") int sti_inq_conf(struct sti_conf_flags *flags, + struct sti_conf_inptr *in, + struct sti_conf_outptr *out, + struct sti_glob_cfg *cfg) +{ + (void)in; + (void)flags; + + out->errno = 0; + out->onscreen_x = cfg->onscreen_x; + out->onscreen_y = cfg->onscreen_y; + out->total_x = cfg->total_x; + out->total_y = cfg->total_y; + out->bits_per_pixel = 8; + out->planes = 8; + out->dev_name[0] = 'H'; + out->dev_name[1] = 'P'; + out->dev_name[2] = 'A'; + out->dev_name[3] = '2'; + out->dev_name[4] = '0'; + out->dev_name[5] = '8'; + out->dev_name[6] = 'L'; + out->dev_name[7] = 'C'; + out->dev_name[8] = '1'; + out->dev_name[9] = '2'; + out->dev_name[10] = '8'; + out->dev_name[11] = '0'; + out->dev_name[12] = '\0'; + return 0; +} + +int __stifunc("excep_hdlr") sti_excep_hdlr(void) +{ + return 0; +} + +int __stifunc("set_cm_entry") sti_set_cm_entry(struct setcm_flags *flags, + struct setcm_inptr *in, + struct setcm_outptr *out, + struct sti_glob_cfg *cfg) +{ + u32 *cmap = (u32 *)cfg->region_ptrs[1]; + (void)flags; + (void)cfg; + + cmap[in->entry & 0xffff] = in->value; + out->errno = 0; + return 0; +} + +int __stifunc("dma_ctrl") sti_dma_ctrl(void) +{ + return 0; +} + +void __stifunc("end") sti_end(void) +{ +} + +static void update_crc(struct sti_rom *rom) +{ + u8 *c, *romend = (u8 *)rom + rom->last_addr - 2; + u16 code = 0, poly = 0x8408, accum = 0; + int i, j; + + for (c = (u8 *)rom, j = 0; c <= romend; c++, j++) { + accum = (accum << 8) | (*c & 0xff); + if (j & 1) { + accum ^= code; + for (i = 0; i < 16; i++) { + /* do a left rotate */ + if (accum & 0x8000) { + accum = (accum << 1) | 0x0001; + accum ^= poly; + } else { + accum <<= 1; + } + } + code = accum; + } + } + *(u16 *)(romend+1) = code; +} + +#define STI_OFFSET(_x) ((u32)&(_x) - (u32)&_sti_rom_start) + +void sti_rom_init(void) +{ + sti_proc_rom.last_addr = _sti_rom_end - _sti_rom_start - 1; + + sti_proc_rom.font_start = STI_OFFSET(sti_rom_font); + sti_proc_rom.state_mgmt = STI_OFFSET(sti_state_mgmt); + sti_proc_rom.inq_conf = STI_OFFSET(sti_inq_conf); + sti_proc_rom.init_graph = STI_OFFSET(sti_init_graph); + sti_proc_rom.block_move = STI_OFFSET(sti_bmove); + sti_proc_rom.region_list = STI_OFFSET(sti_region_list); + sti_proc_rom.font_unpmv = STI_OFFSET(sti_font_unpmv); + sti_proc_rom.self_test = STI_OFFSET(sti_self_test); + sti_proc_rom.mon_tbl_addr = STI_OFFSET(sti_mon_table); + sti_proc_rom.user_data_addr = STI_OFFSET(user_data); + sti_proc_rom.excep_hdlr = STI_OFFSET(sti_excep_hdlr); + sti_proc_rom.set_cm_entry = STI_OFFSET(sti_set_cm_entry); + sti_proc_rom.dma_ctrl = STI_OFFSET(sti_dma_ctrl); + sti_proc_rom.end = STI_OFFSET(sti_end); + update_crc(&sti_proc_rom); +} |