From 413f05aaf54fa08c0ae7e997327a4f4a473c0a8d Mon Sep 17 00:00:00 2001 From: Upstream Date: Mon, 12 Jan 1970 13:46:40 +0000 Subject: external/qemu 0.8.2 --- pc-bios/Makefile | 24 + pc-bios/README | 16 + pc-bios/bios.bin | Bin 0 -> 65536 bytes pc-bios/bios.diff | 270 +++++++ pc-bios/linux_boot.S | 29 + pc-bios/linux_boot.bin | Bin 0 -> 512 bytes pc-bios/ohw.diff | 1843 ++++++++++++++++++++++++++++++++++++++++++++ pc-bios/openbios-sparc32 | Bin 0 -> 506966 bytes pc-bios/ppc_rom.bin | Bin 0 -> 524288 bytes pc-bios/vgabios-cirrus.bin | Bin 0 -> 35328 bytes pc-bios/vgabios.bin | Bin 0 -> 37888 bytes pc-bios/vgabios.diff | 896 +++++++++++++++++++++ pc-bios/video.x | Bin 0 -> 12192 bytes 13 files changed, 3078 insertions(+) create mode 100644 pc-bios/Makefile create mode 100644 pc-bios/README create mode 100644 pc-bios/bios.bin create mode 100644 pc-bios/bios.diff create mode 100644 pc-bios/linux_boot.S create mode 100644 pc-bios/linux_boot.bin create mode 100644 pc-bios/ohw.diff create mode 100644 pc-bios/openbios-sparc32 create mode 100644 pc-bios/ppc_rom.bin create mode 100644 pc-bios/vgabios-cirrus.bin create mode 100644 pc-bios/vgabios.bin create mode 100644 pc-bios/vgabios.diff create mode 100644 pc-bios/video.x (limited to 'pc-bios') diff --git a/pc-bios/Makefile b/pc-bios/Makefile new file mode 100644 index 0000000..7ae0ff0 --- /dev/null +++ b/pc-bios/Makefile @@ -0,0 +1,24 @@ +# +# NOTE: only compilable with x86 cross compile tools +# +include ../config-host.mak + +DEFINES= + +TARGETS= +ifeq ($(ARCH),i386) +TARGETS+=linux_boot.bin +endif + +all: $(TARGETS) + +linux_boot.bin: linux_boot.o + ld --oformat binary -Ttext 0 -o $@ $< + chmod a-x $@ + +%.o: %.S + $(CC) $(DEFINES) -c -o $@ $< + +clean: + rm -f $(TARGETS) *.o *~ + diff --git a/pc-bios/README b/pc-bios/README new file mode 100644 index 0000000..fc85eb4 --- /dev/null +++ b/pc-bios/README @@ -0,0 +1,16 @@ +- The PC BIOS comes from the Bochs project + (http://bochs.sourceforge.net/). A patch from bios.diff was applied. + +- The VGA BIOS and the Cirrus VGA BIOS come from the LGPL VGA bios + project (http://www.nongnu.org/vgabios/). + +- The PowerPC Open Hack'Ware Open Firmware Compatible BIOS is + available at http://perso.magic.fr/l_indien/OpenHackWare/index.htm. + +- video.x is a PowerMac NDRV compatible driver for a VGA frame + buffer. It comes from the Mac-on-Linux project + (http://www.maconlinux.org/). + +- OpenBIOS (http://www.openbios.org/) is a free (GPL v2) portable + firmware implementation. The goal is to implement a 100% IEEE + 1275-1994 (referred to as Open Firmware) compliant firmware. diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin new file mode 100644 index 0000000..64be517 Binary files /dev/null and b/pc-bios/bios.bin differ diff --git a/pc-bios/bios.diff b/pc-bios/bios.diff new file mode 100644 index 0000000..e875927 --- /dev/null +++ b/pc-bios/bios.diff @@ -0,0 +1,270 @@ +Index: apmbios.S +=================================================================== +RCS file: /cvsroot/bochs/bochs/bios/apmbios.S,v +retrieving revision 1.4 +diff -u -w -r1.4 apmbios.S +--- apmbios.S 26 Dec 2005 10:35:51 -0000 1.4 ++++ apmbios.S 3 May 2006 21:22:46 -0000 +@@ -225,6 +225,7 @@ + APMSYM(05): + cmp al, #0x05 + jne APMSYM(07) ++ sti + hlt + jmp APMSYM(ok) + +Index: rombios.c +=================================================================== +RCS file: /cvsroot/bochs/bochs/bios/rombios.c,v +retrieving revision 1.160 +diff -u -w -r1.160 rombios.c +--- rombios.c 25 Jan 2006 17:51:49 -0000 1.160 ++++ rombios.c 3 May 2006 21:22:48 -0000 +@@ -1816,6 +1816,7 @@ + { + printf(BX_APPNAME" BIOS - build: %s\n%s\nOptions: ", + BIOS_BUILD_DATE, bios_cvs_version_string); ++#if 0 + printf( + #ifdef BX_APM + "apmbios " +@@ -1827,6 +1828,9 @@ + "eltorito " + #endif + "\n\n"); ++#else ++ printf("apmbios pcibios eltorito \n\n"); ++#endif + } + + //-------------------------------------------------------------------------- +@@ -3999,6 +4003,29 @@ + } + #endif + ++ ++void set_e820_range(ES, DI, start, end, type) ++ Bit16u ES; ++ Bit16u DI; ++ Bit32u start; ++ Bit32u end; ++ Bit16u type; ++{ ++ write_word(ES, DI, start); ++ write_word(ES, DI+2, start >> 16); ++ write_word(ES, DI+4, 0x00); ++ write_word(ES, DI+6, 0x00); ++ ++ end -= start; ++ write_word(ES, DI+8, end); ++ write_word(ES, DI+10, end >> 16); ++ write_word(ES, DI+12, 0x0000); ++ write_word(ES, DI+14, 0x0000); ++ ++ write_word(ES, DI+16, type); ++ write_word(ES, DI+18, 0x0); ++} ++ + void + int15_function32(regs, ES, DS, FLAGS) + pushad_regs_t regs; // REGS pushed via pushad +@@ -4063,19 +4090,8 @@ + switch(regs.u.r16.bx) + { + case 0: +- write_word(ES, regs.u.r16.di, 0x00); +- write_word(ES, regs.u.r16.di+2, 0x00); +- write_word(ES, regs.u.r16.di+4, 0x00); +- write_word(ES, regs.u.r16.di+6, 0x00); +- +- write_word(ES, regs.u.r16.di+8, 0xFC00); +- write_word(ES, regs.u.r16.di+10, 0x0009); +- write_word(ES, regs.u.r16.di+12, 0x0000); +- write_word(ES, regs.u.r16.di+14, 0x0000); +- +- write_word(ES, regs.u.r16.di+16, 0x1); +- write_word(ES, regs.u.r16.di+18, 0x0); +- ++ set_e820_range(ES, regs.u.r16.di, ++ 0x0000000L, 0x0009fc00L, 1); + regs.u.r32.ebx = 1; + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; +@@ -4083,6 +4099,24 @@ + return; + break; + case 1: ++ set_e820_range(ES, regs.u.r16.di, ++ 0x0009fc00L, 0x000a0000L, 2); ++ regs.u.r32.ebx = 2; ++ regs.u.r32.eax = 0x534D4150; ++ regs.u.r32.ecx = 0x14; ++ CLEAR_CF(); ++ return; ++ break; ++ case 2: ++ set_e820_range(ES, regs.u.r16.di, ++ 0x000e8000L, 0x00100000L, 2); ++ regs.u.r32.ebx = 3; ++ regs.u.r32.eax = 0x534D4150; ++ regs.u.r32.ecx = 0x14; ++ CLEAR_CF(); ++ return; ++ break; ++ case 3: + extended_memory_size = inb_cmos(0x35); + extended_memory_size <<= 8; + extended_memory_size |= inb_cmos(0x34); +@@ -4092,9 +4126,9 @@ + extended_memory_size = 0x3bc000; // everything after this is reserved memory until we get to 0x100000000 + } + extended_memory_size *= 1024; +- extended_memory_size += 15728640; // make up for the 16mb of memory that is chopped off ++ extended_memory_size += (16L * 1024 * 1024); + +- if(extended_memory_size <= 15728640) ++ if(extended_memory_size <= (16L * 1024 * 1024)) + { + extended_memory_size = inb_cmos(0x31); + extended_memory_size <<= 8; +@@ -4102,28 +4136,23 @@ + extended_memory_size *= 1024; + } + +- write_word(ES, regs.u.r16.di, 0x0000); +- write_word(ES, regs.u.r16.di+2, 0x0010); +- write_word(ES, regs.u.r16.di+4, 0x0000); +- write_word(ES, regs.u.r16.di+6, 0x0000); +- +- write_word(ES, regs.u.r16.di+8, extended_memory_size); +- extended_memory_size >>= 16; +- write_word(ES, regs.u.r16.di+10, extended_memory_size); +- extended_memory_size >>= 16; +- write_word(ES, regs.u.r16.di+12, extended_memory_size); +- extended_memory_size >>= 16; +- write_word(ES, regs.u.r16.di+14, extended_memory_size); +- +- write_word(ES, regs.u.r16.di+16, 0x1); +- write_word(ES, regs.u.r16.di+18, 0x0); +- +- regs.u.r32.ebx = 0; ++ set_e820_range(ES, regs.u.r16.di, ++ 0x00100000L, extended_memory_size, 1); ++ regs.u.r32.ebx = 4; + regs.u.r32.eax = 0x534D4150; + regs.u.r32.ecx = 0x14; + CLEAR_CF(); + return; + break; ++ case 4: ++ /* 256KB BIOS area at the end of 4 GB */ ++ set_e820_range(ES, regs.u.r16.di, ++ 0xfffc0000L, 0x00000000L, 2); ++ regs.u.r32.ebx = 0; ++ regs.u.r32.eax = 0x534D4150; ++ regs.u.r32.ecx = 0x14; ++ CLEAR_CF(); ++ return; + default: /* AX=E820, DX=534D4150, BX unrecognized */ + goto int15_unimplemented; + break; +@@ -8713,6 +8742,7 @@ + mov al, #0x80 + bios32_end: + popf ++ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu + retf + + .align 16 +@@ -8823,17 +8853,17 @@ + pci_pro_fail: + pop edi + pop esi +- sti + popf + stc ++ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu + retf + pci_pro_ok: + xor ah, ah + pop edi + pop esi +- sti + popf + clc ++ and dword ptr[esp+4],0xfffffffc ;; reset CS.RPL for kqemu + retf + + pci_pro_select_reg: +@@ -8971,7 +9001,7 @@ + jmp pci_real_ok + pci_real_f0d: ;; write configuration dword + cmp al, #0x0d +- jne pci_real_unknown ++ jne pci_real_f0e + call pci_real_select_reg + push dx + mov dx, #0x0cfc +@@ -8979,6 +9009,46 @@ + out dx, eax + pop dx + jmp pci_real_ok ++pci_real_f0e: ;; get irq routing options ++ cmp al, #0x0e ++ jne pci_real_unknown ++ SEG ES ++ cmp word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start ++ jb pci_real_too_small ++ SEG ES ++ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start ++ pushf ++ push ds ++ push es ++ push cx ++ push si ++ push di ++ cld ++ mov si, #pci_routing_table_structure_start ++ push cs ++ pop ds ++ SEG ES ++ mov cx, [di+2] ++ SEG ES ++ mov es, [di+4] ++ mov di, cx ++ mov cx, #pci_routing_table_structure_end - pci_routing_table_structure_start ++ rep ++ movsb ++ pop di ++ pop si ++ pop cx ++ pop es ++ pop ds ++ popf ++ mov bx, #(1 << 9) | (1 << 11) ;; irq 9 and 11 are used ++ jmp pci_real_ok ++pci_real_too_small: ++ SEG ES ++ mov word ptr [di], #pci_routing_table_structure_end - pci_routing_table_structure_start ++ mov ah, #0x89 ++ jmp pci_real_fail ++ + pci_real_unknown: + mov ah, #0x81 + pci_real_fail: +@@ -9019,6 +9089,7 @@ + dw 0,0 ;; Miniport data + db 0,0,0,0,0,0,0,0,0,0,0 ;; reserved + db 0x07 ;; checksum ++pci_routing_table_structure_start: + ;; first slot entry PCI-to-ISA (embedded) + db 0 ;; pci bus number + db 0x08 ;; pci device number (bit 7-3) +@@ -9097,6 +9168,7 @@ + dw 0xdef8 ;; IRQ bitmap INTD# + db 5 ;; physical slot (0 = embedded) + db 0 ;; reserved ++pci_routing_table_structure_end: + + pci_irq_list: + db 11, 10, 9, 5; diff --git a/pc-bios/linux_boot.S b/pc-bios/linux_boot.S new file mode 100644 index 0000000..22fcd4b --- /dev/null +++ b/pc-bios/linux_boot.S @@ -0,0 +1,29 @@ +/* + * QEMU Boot sector to launch a preloaded Linux kernel + * Copyright (c) 2004 Fabrice Bellard + */ + +#define LOAD_SEG 0x9000 + +.code16 +.text + .globl _start + +_start: + cli + cld + mov $LOAD_SEG, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + mov $0x8ffe, %sp + ljmp $LOAD_SEG + 0x20, $0 + +1: + .fill 510 - (1b - _start), 1, 0 + + /* boot sector signature */ + .byte 0x55 + .byte 0xaa diff --git a/pc-bios/linux_boot.bin b/pc-bios/linux_boot.bin new file mode 100644 index 0000000..80f7b5f Binary files /dev/null and b/pc-bios/linux_boot.bin differ diff --git a/pc-bios/ohw.diff b/pc-bios/ohw.diff new file mode 100644 index 0000000..4fb5422 --- /dev/null +++ b/pc-bios/ohw.diff @@ -0,0 +1,1843 @@ +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bios.h OpenHackWare-release-0.4/src/bios.h +--- OpenHackWare-release-0.4.org/src/bios.h 2005-04-06 23:20:22.000000000 +0200 ++++ OpenHackWare-release-0.4/src/bios.h 2005-07-07 01:10:20.000000000 +0200 +@@ -64,6 +64,7 @@ + ARCH_CHRP, + ARCH_MAC99, + ARCH_POP, ++ ARCH_HEATHROW, + }; + + /* Hardware definition(s) */ +@@ -174,6 +175,7 @@ + int bd_ioctl (bloc_device_t *bd, int func, void *args); + uint32_t bd_seclen (bloc_device_t *bd); + void bd_close (bloc_device_t *bd); ++void bd_reset_all(void); + uint32_t bd_seclen (bloc_device_t *bd); + uint32_t bd_maxbloc (bloc_device_t *bd); + void bd_sect2CHS (bloc_device_t *bd, uint32_t secnum, +@@ -183,12 +185,12 @@ + part_t *bd_probe (int boot_device); + bloc_device_t *bd_get (int device); + void bd_put (bloc_device_t *bd); +-void bd_set_boot_part (bloc_device_t *bd, part_t *partition); ++void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum); + part_t **_bd_parts (bloc_device_t *bd); + + void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1, + uint32_t io_base2, uint32_t io_base3, +- void *OF_private); ++ void *OF_private0, void *OF_private1); + void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1, + void *OF_private); + +@@ -399,17 +401,23 @@ + uint16_t min_grant, uint16_t max_latency); + void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses); + void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn, +- uint32_t *regions, uint32_t *sizes); ++ uint32_t *regions, uint32_t *sizes, ++ int irq_line); + void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size, + void *private_data); ++void OF_finalize_pci_ide (void *dev, ++ uint32_t io_base0, uint32_t io_base1, ++ uint32_t io_base2, uint32_t io_base3); + int OF_register_bus (const unsigned char *name, uint32_t address, + const unsigned char *type); + int OF_register_serial (const unsigned char *bus, const unsigned char *name, + uint32_t io_base, int irq); + int OF_register_stdio (const unsigned char *dev_in, + const unsigned char *dev_out); +-void OF_vga_register (const unsigned char *name, uint32_t address, +- int width, int height, int depth); ++void OF_vga_register (const unsigned char *name, unused uint32_t address, ++ int width, int height, int depth, ++ unsigned long vga_bios_addr, ++ unsigned long vga_bios_size); + void *OF_blockdev_register (void *parent, void *private, + const unsigned char *type, + const unsigned char *name, int devnum, +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bloc.c OpenHackWare-release-0.4/src/bloc.c +--- OpenHackWare-release-0.4.org/src/bloc.c 2005-04-06 23:21:00.000000000 +0200 ++++ OpenHackWare-release-0.4/src/bloc.c 2005-07-08 00:28:26.000000000 +0200 +@@ -55,6 +55,7 @@ + /* Partitions */ + part_t *parts, *bparts; + part_t *boot_part; ++ int bpartnum; + /* Chain */ + bloc_device_t *next; + }; +@@ -66,6 +67,7 @@ + + static int ide_initialize (bloc_device_t *bd, int device); + static int ide_read_sector (bloc_device_t *bd, void *buffer, int secnum); ++static int ide_reset (bloc_device_t *bd); + + static int mem_initialize (bloc_device_t *bd, int device); + static int mem_read_sector (bloc_device_t *bd, void *buffer, int secnum); +@@ -212,6 +214,17 @@ + { + } + ++void bd_reset_all(void) ++{ ++ bloc_device_t *bd; ++ for (bd = bd_list; bd != NULL; bd = bd->next) { ++ if (bd->init == &ide_initialize) { ++ /* reset IDE drive because Darwin wants all IDE devices to be reset */ ++ ide_reset(bd); ++ } ++ } ++} ++ + uint32_t bd_seclen (bloc_device_t *bd) + { + return bd->seclen; +@@ -223,10 +236,12 @@ + } + + /* XXX: to be suppressed */ +-void bd_set_boot_part (bloc_device_t *bd, part_t *partition) ++void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum) + { ++ dprintf("%s: part %p (%p) %d\n", __func__, partition, bd->boot_part, partnum); + if (bd->boot_part == NULL) { + bd->boot_part = partition; ++ bd->bpartnum = partnum; + } + } + +@@ -240,6 +255,13 @@ + return &bd->bparts; + } + ++void bd_set_boot_device (bloc_device_t *bd) ++{ ++#if defined (USE_OPENFIRMWARE) ++ OF_blockdev_set_boot_device(bd->OF_private, bd->bpartnum, "\\\\ofwboot"); ++#endif ++} ++ + part_t *bd_probe (int boot_device) + { + char devices[] = { /*'a', 'b',*/ 'c', 'd', 'e', 'f', 'm', '\0', }; +@@ -272,9 +294,7 @@ + tmp = part_probe(bd, force_raw); + if (boot_device == bd->device) { + boot_part = tmp; +-#if defined (USE_OPENFIRMWARE) +- OF_blockdev_set_boot_device(bd->OF_private, 2, "\\\\ofwboot"); +-#endif ++ bd_set_boot_device(bd); + } + } + +@@ -717,34 +737,29 @@ + /* IDE PCI access for pc */ + static uint8_t ide_pci_port_read (bloc_device_t *bd, int port) + { +- eieio(); +- +- return *(uint8_t *)(bd->io_base + port); ++ uint8_t value; ++ value = inb(bd->io_base + port); ++ return value; + } + + static void ide_pci_port_write (bloc_device_t *bd, int port, uint8_t value) + { +- *(uint8_t *)(bd->io_base + port) = value; +- eieio(); ++ outb(bd->io_base + port, value); + } + + static uint32_t ide_pci_data_readl (bloc_device_t *bd) + { +- eieio(); +- +- return *((uint32_t *)bd->io_base); ++ return inl(bd->io_base); + } + + static void ide_pci_data_writel (bloc_device_t *bd, uint32_t val) + { +- *(uint32_t *)(bd->io_base) = val; +- eieio(); ++ outl(bd->io_base, val); + } + + static void ide_pci_control_write (bloc_device_t *bd, uint32_t val) + { +- *((uint8_t *)bd->tmp) = val; +- eieio(); ++ outb(bd->tmp + 2, val); + } + + static ide_ops_t ide_pci_pc_ops = { +@@ -761,7 +776,7 @@ + + void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1, + uint32_t io_base2, uint32_t io_base3, +- unused void *OF_private) ++ void *OF_private0, void *OF_private1) + { + if (ide_pci_ops == NULL) { + ide_pci_ops = malloc(sizeof(ide_ops_t)); +@@ -770,19 +785,19 @@ + memcpy(ide_pci_ops, &ide_pci_pc_ops, sizeof(ide_ops_t)); + } + if ((io_base0 != 0 || io_base1 != 0) && +- ide_pci_ops->base[0] == 0 && ide_pci_ops->base[1] == 0) { ++ ide_pci_ops->base[0] == 0 && ide_pci_ops->base[2] == 0) { + ide_pci_ops->base[0] = io_base0; +- ide_pci_ops->base[1] = io_base1; ++ ide_pci_ops->base[2] = io_base1; + #ifdef USE_OPENFIRMWARE +- ide_pci_ops->OF_private[0] = OF_private; ++ ide_pci_ops->OF_private[0] = OF_private0; + #endif + } + if ((io_base2 != 0 || io_base3 != 0) && +- ide_pci_ops->base[2] == 0 && ide_pci_ops->base[3] == 0) { +- ide_pci_ops->base[2] = io_base2; ++ ide_pci_ops->base[1] == 0 && ide_pci_ops->base[3] == 0) { ++ ide_pci_ops->base[1] = io_base2; + ide_pci_ops->base[3] = io_base3; + #ifdef USE_OPENFIRMWARE +- ide_pci_ops->OF_private[1] = OF_private; ++ ide_pci_ops->OF_private[1] = OF_private1; + #endif + } + } +@@ -935,6 +950,8 @@ + } + + static void atapi_pad_req (void *buffer, int len); ++static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer, ++ int maxlen); + static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum); + + static int ide_initialize (bloc_device_t *bd, int device) +@@ -1035,9 +1052,7 @@ + DPRINTF("INQUIRY\n"); + len = spc_inquiry_req(&atapi_buffer, 36); + atapi_pad_req(&atapi_buffer, len); +- ide_port_write(bd, 0x07, 0xA0); +- for (i = 0; i < 3; i++) +- ide_data_writel(bd, ldswap32(&atapi_buffer[i])); ++ atapi_make_req(bd, atapi_buffer, 36); + status = ide_port_read(bd, 0x07); + if (status != 0x48) { + ERROR("ATAPI INQUIRY : status %0x != 0x48\n", status); +@@ -1053,9 +1068,7 @@ + DPRINTF("READ_CAPACITY\n"); + len = mmc_read_capacity_req(&atapi_buffer); + atapi_pad_req(&atapi_buffer, len); +- ide_port_write(bd, 0x07, 0xA0); +- for (i = 0; i < 3; i++) +- ide_data_writel(bd, ldswap32(&atapi_buffer[i])); ++ atapi_make_req(bd, atapi_buffer, 8); + status = ide_port_read(bd, 0x07); + if (status != 0x48) { + ERROR("ATAPI READ_CAPACITY : status %0x != 0x48\n", status); +@@ -1105,6 +1118,22 @@ + memset(p + len, 0, 12 - len); + } + ++static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer, ++ int maxlen) ++{ ++ int i; ++ /* select drive */ ++ if (bd->drv == 0) ++ ide_port_write(bd, 0x06, 0x40); ++ else ++ ide_port_write(bd, 0x06, 0x50); ++ ide_port_write(bd, 0x04, maxlen & 0xff); ++ ide_port_write(bd, 0x05, (maxlen >> 8) & 0xff); ++ ide_port_write(bd, 0x07, 0xA0); ++ for (i = 0; i < 3; i++) ++ ide_data_writel(bd, ldswap32(&buffer[i])); ++} ++ + static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum) + { + uint32_t atapi_buffer[4]; +@@ -1112,16 +1141,9 @@ + uint32_t status, value; + int i, len; + +- /* select drive */ +- if (bd->drv == 0) +- ide_port_write(bd, 0x06, 0x40); +- else +- ide_port_write(bd, 0x06, 0x50); + len = mmc_read12_req(atapi_buffer, secnum, 1); + atapi_pad_req(&atapi_buffer, len); +- ide_port_write(bd, 0x07, 0xA0); +- for (i = 0; i < 3; i++) +- ide_data_writel(bd, ldswap32(&atapi_buffer[i])); ++ atapi_make_req(bd, atapi_buffer, bd->seclen); + status = ide_port_read(bd, 0x07); + if (status != 0x48) { + ERROR("ATAPI READ12 : status %0x != 0x48\n", status); +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/apple.c OpenHackWare-release-0.4/src/libpart/apple.c +--- OpenHackWare-release-0.4.org/src/libpart/apple.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/libpart/apple.c 2005-07-03 16:17:41.000000000 +0200 +@@ -199,14 +199,18 @@ + if (len == 0) { + /* Place holder. Skip it */ + DPRINTF("%s placeholder part\t%d\n", __func__, i); ++ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; ++ part_register(bd, part, name, i); + } else if (strncmp("Apple_Void", type, 32) == 0) { + /* Void partition. Skip it */ + DPRINTF("%s Void part\t%d [%s]\n", __func__, i, type); ++ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; ++ part_register(bd, part, name, i); + } else if (strncmp("Apple_Free", type, 32) == 0) { + /* Free space. Skip it */ + DPRINTF("%s Free part (%d)\n", __func__, i); + part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; +- part_register(bd, part, name); ++ part_register(bd, part, name, i); + } else if (strncmp("Apple_partition_map", type, 32) == 0 || + strncmp("Apple_Partition_Map", type, 32) == 0 + #if 0 // Is this really used or is it just a mistake ? +@@ -226,7 +230,7 @@ + */ + } + part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; +- part_register(bd, part, name); ++ part_register(bd, part, name, i); + } else if (strncmp("Apple_Driver", type, 32) == 0 || + strncmp("Apple_Driver43", type, 32) == 0 || + strncmp("Apple_Driver43_CD", type, 32) == 0 || +@@ -236,8 +240,12 @@ + strncmp("Apple_Driver_IOKit", type, 32) == 0) { + /* Drivers. don't care for now */ + DPRINTF("%s Drivers part\t%d [%s]\n", __func__, i, type); ++ part->flags = PART_TYPE_APPLE | PART_FLAG_DRIVER; ++ part_register(bd, part, name, i); + } else if (strncmp("Apple_Patches", type, 32) == 0) { + /* Patches: don't care for now */ ++ part->flags = PART_TYPE_APPLE | PART_FLAG_PATCH; ++ part_register(bd, part, name, i); + DPRINTF("%s Patches part\t%d [%s]\n", __func__, i, type); + } else if (strncmp("Apple_HFS", type, 32) == 0 || + strncmp("Apple_MFS", type, 32) == 0 || +@@ -256,9 +264,8 @@ + count = partmap->bloc_cnt * HFS_BLOCSIZE; + if (partmap->boot_size == 0 || partmap->boot_load == 0) { + printf("Not a bootable partition %d %d (%p %p)\n", +- partmap->boot_size, partmap->boot_load,boot_part, part); +- if (boot_part == NULL) +- boot_part = part; ++ partmap->boot_size, partmap->boot_load, ++ boot_part, part); + part->flags = PART_TYPE_APPLE | PART_FLAG_FS; + } else { + part->boot_start.bloc = partmap->boot_start; +@@ -278,8 +285,8 @@ + boot_part = part; + part->flags = PART_TYPE_APPLE | PART_FLAG_FS | PART_FLAG_BOOT; + } +- printf("Partition: %d %s st %0x size %0x", +- i, name, partmap->start_bloc, partmap->bloc_cnt); ++ printf("Partition: %d '%s' '%s' st %0x size %0x", ++ i, name, type, partmap->start_bloc, partmap->bloc_cnt); + #ifndef DEBUG + printf("\n"); + #endif +@@ -290,11 +297,13 @@ + part->boot_load, part->boot_entry); + DPRINTF(" load %0x entry %0x %0x\n", + partmap->boot_load2, partmap->boot_entry2, HFS_BLOCSIZE); +- part_register(bd, part, name); ++ part_register(bd, part, name, i); + } else { + memcpy(tmp, type, 32); + tmp[32] = '\0'; + ERROR("Unknown partition type [%s]\n", tmp); ++ part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; ++ part_register(bd, part, name, i); + } + } + error: +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/core.c OpenHackWare-release-0.4/src/libpart/core.c +--- OpenHackWare-release-0.4.org/src/libpart/core.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/libpart/core.c 2005-07-03 16:17:41.000000000 +0200 +@@ -126,7 +126,7 @@ + } + + int part_register (bloc_device_t *bd, part_t *partition, +- const unsigned char *name) ++ const unsigned char *name, int partnum) + { + part_t **cur; + +@@ -134,6 +134,7 @@ + partition->bd = bd; + partition->next = NULL; + partition->name = strdup(name); ++ partition->partnum = partnum; + for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) + continue; + *cur = partition; +@@ -141,29 +142,15 @@ + return 0; + } + +-static inline int set_boot_part (bloc_device_t *bd, int partnum) +-{ +- part_t *cur; +- +- cur = part_get(bd, partnum); +- if (cur == NULL) +- return -1; +- bd_set_boot_part(bd, cur); +- +- return 0; +-} +- + part_t *part_get (bloc_device_t *bd, int partnum) + { + part_t **listp, *cur; +- int i; + + listp = _bd_parts(bd); +- cur = *listp; +- for (i = 0; i != partnum; i++) { +- if (cur == NULL) ++ ++ for (cur = *listp; cur != NULL; cur = cur->next) { ++ if (cur->partnum == partnum) + break; +- cur = cur->next; + } + + return cur; +@@ -192,17 +179,20 @@ + part_set_blocsize(bd, part, 512); + part->bd = bd; + part->flags = PART_TYPE_RAW | PART_FLAG_BOOT; +- part_register(bd, part, "Raw"); ++ part_register(bd, part, "Raw", 0); + + return part; + } + ++bloc_device_t *part_get_bd (part_t *part) ++{ ++ return part->bd; ++} ++ + part_t *part_probe (bloc_device_t *bd, int set_raw) + { +- part_t *part0, *boot_part, **cur; ++ part_t *part0 = NULL, *boot_part, **cur; + +- /* Register the 0 partition: raw partition containing the whole disk */ +- part0 = part_get_raw(bd); + /* Try to find a valid boot partition */ + boot_part = Apple_probe_partitions(bd); + if (boot_part == NULL) { +@@ -210,10 +200,13 @@ + if (boot_part == NULL && arch == ARCH_PREP) + boot_part = PREP_find_partition(bd); + if (boot_part == NULL && set_raw != 0) { +- boot_part = part0; +- set_boot_part(bd, 0); ++ dprintf("Use bloc device as raw partition\n"); + } + } ++ if (_bd_parts(bd) == NULL) { ++ /* Register the 0 partition: raw partition containing the whole disk */ ++ part0 = part_get_raw(bd); ++ } + /* Probe filesystem on each found partition */ + for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) { + const unsigned char *map, *type; +@@ -248,23 +241,28 @@ + type = "unknown"; + break; + } +- DPRINTF("Probe filesystem on %s %s partition '%s' %s\n", ++ dprintf("Probe filesystem on %s %s partition '%s' %s %p\n", + type, map, (*cur)->name, +- ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : ""); ++ ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur); + if (((*cur)->flags) & PART_FLAG_FS) { + if (((*cur)->flags) & PART_FLAG_BOOT) + (*cur)->fs = fs_probe(*cur, 1); + else + (*cur)->fs = fs_probe(*cur, 0); ++ } else if (((*cur)->flags) & PART_TYPE_RAW) { ++ (*cur)->fs = fs_probe(*cur, 2); + } else { + (*cur)->fs = fs_probe(*cur, 2); + } +- if (((*cur)->flags) & PART_FLAG_BOOT) { +- bd_set_boot_part(bd, *cur); + fs_get_bootfile((*cur)->fs); ++ if (((*cur)->flags) & PART_FLAG_BOOT) { ++ dprintf("Partition is bootable (%d)\n", (*cur)->partnum); ++ bd_set_boot_part(bd, *cur, (*cur)->partnum); ++ if (boot_part == NULL) ++ boot_part = *cur; + } + } +- DPRINTF("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs, ++ dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs, + part_fs(boot_part), part0); + + return boot_part; +@@ -279,6 +277,7 @@ + part->boot_size.offset = 0; + part->boot_load = 0; + part->boot_entry = 0; ++ part->flags |= PART_FLAG_BOOT; + + return 0; + } +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/isofs.c OpenHackWare-release-0.4/src/libpart/isofs.c +--- OpenHackWare-release-0.4.org/src/libpart/isofs.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/libpart/isofs.c 2005-07-03 16:17:41.000000000 +0200 +@@ -242,7 +242,7 @@ + part->boot_start.bloc, part->boot_size.bloc, + part->boot_load, part->boot_entry); + part->flags = PART_TYPE_ISO9660 | PART_FLAG_BOOT; +- part_register(bd, part, name); ++ part_register(bd, part, name, i + 1); + fs_raw_set_bootfile(part, part->boot_start.bloc, + part->boot_start.offset, + part->boot_size.bloc, +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/libpart.h OpenHackWare-release-0.4/src/libpart/libpart.h +--- OpenHackWare-release-0.4.org/src/libpart/libpart.h 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/libpart/libpart.h 2005-07-03 16:17:41.000000000 +0200 +@@ -30,6 +30,7 @@ + + struct part_t { + bloc_device_t *bd; ++ int partnum; + uint32_t start; /* Partition first bloc */ + uint32_t size; /* Partition size, in blocs */ + uint32_t spb; +@@ -54,7 +55,7 @@ + }; + + int part_register (bloc_device_t *bd, part_t *partition, +- const unsigned char *name); ++ const unsigned char *name, int partnum); + void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize); + void part_private_set (part_t *part, void *private); + void *part_private_get (part_t *part); +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/prep.c OpenHackWare-release-0.4/src/libpart/prep.c +--- OpenHackWare-release-0.4.org/src/libpart/prep.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/libpart/prep.c 2005-07-03 16:17:41.000000000 +0200 +@@ -164,7 +164,7 @@ + part->boot_load = 0; + part->boot_entry = boot_offset - part->bloc_size; + part->flags = PART_TYPE_PREP | PART_FLAG_BOOT; +- part_register(bd, part, "PREP boot"); ++ part_register(bd, part, "PREP boot", i); + fs_raw_set_bootfile(part, part->boot_start.bloc, + part->boot_start.offset, + part->boot_size.bloc, +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/main.c OpenHackWare-release-0.4/src/main.c +--- OpenHackWare-release-0.4.org/src/main.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/main.c 2005-06-07 23:48:39.000000000 +0200 +@@ -364,20 +364,24 @@ + void *load_base, *load_entry, *last_alloc, *load_end; + uint32_t memsize, boot_image_size, cmdline_size, ramdisk_size; + uint32_t boot_base, boot_nb; +- int boot_device; ++ int boot_device, i; ++ static const uint32_t isa_base_tab[3] = { ++ 0x80000000, /* PREP */ ++ 0xFE000000, /* Grackle (Heathrow) */ ++ 0xF2000000, /* UniNorth (Mac99) */ ++ }; + + /* Retrieve NVRAM configuration */ +- nvram_retry: ++ for(i = 0; i < 3; i++) { ++ isa_io_base = isa_base_tab[i]; + nvram = NVRAM_get_config(&memsize, &boot_device, + &boot_image, &boot_image_size, + &cmdline, &cmdline_size, + &ramdisk, &ramdisk_size); +- if (nvram == NULL) { +- /* Retry with another isa_io_base */ +- if (isa_io_base == 0x80000000) { +- isa_io_base = 0xF2000000; +- goto nvram_retry; ++ if (nvram) ++ break; + } ++ if (i == 3) { + ERROR("Unable to load configuration from NVRAM. Aborting...\n"); + return -1; + } +@@ -402,7 +406,7 @@ + cpu_name = CPU_get_name(pvr); + OF_register_cpu(cpu_name, 0, pvr, + 200 * 1000 * 1000, 200 * 1000 * 1000, +- 100 * 1000 * 1000, 10 * 1000 * 1000, ++ 100 * 1000 * 1000, 100 * 1000 * 1000, + 0x0092); + } + OF_register_memory(memsize, 512 * 1024 /* TOFIX */); +@@ -433,9 +437,12 @@ + vga_puts(copyright); + vga_puts("\n"); + ++#if 0 + /* QEMU is quite incoherent: d is cdrom, not second drive */ ++ /* XXX: should probe CD-ROM position */ + if (boot_device == 'd') + boot_device = 'e'; ++#endif + /* Open boot device */ + boot_part = bd_probe(boot_device); + if (boot_device == 'm') { +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/nvram.c OpenHackWare-release-0.4/src/nvram.c +--- OpenHackWare-release-0.4.org/src/nvram.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/nvram.c 2005-06-04 23:44:03.000000000 +0200 +@@ -334,6 +334,7 @@ + ret = NVRAM_chrp_format(nvram); + break; + case ARCH_MAC99: ++ case ARCH_HEATHROW: /* XXX: may be incorrect */ + ret = NVRAM_mac99_format(nvram); + break; + case ARCH_POP: +@@ -409,13 +410,12 @@ + arch = ARCH_MAC99; + } else if (strcmp(sign, "POP") == 0) { + arch = ARCH_POP; ++ } else if (strcmp(sign, "HEATHROW") == 0) { ++ arch = ARCH_HEATHROW; + } else { + ERROR("Unknown PPC architecture: '%s'\n", sign); + return NULL; + } +- /* HACK */ +- if (arch == ARCH_CHRP) +- arch = ARCH_MAC99; + lword = NVRAM_get_lword(nvram, 0x30); + *RAM_size = lword; + byte = NVRAM_get_byte(nvram, 0x34); +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/of.c OpenHackWare-release-0.4/src/of.c +--- OpenHackWare-release-0.4.org/src/of.c 2005-04-06 23:17:26.000000000 +0200 ++++ OpenHackWare-release-0.4/src/of.c 2005-07-07 23:30:08.000000000 +0200 +@@ -489,7 +489,7 @@ + ERROR("%s can't alloc new node '%s' name\n", __func__, name); + return NULL; + } +- new->prop_address = OF_prop_int_new(env, new, "address", address); ++ new->prop_address = OF_prop_int_new(env, new, "unit-address", address); + if (new->prop_address == NULL) { + free(new->prop_name->value); + free(new->prop_name); +@@ -1017,6 +1017,33 @@ + string, strlen(string) + 1); + } + ++/* convert '\1' char to '\0' */ ++static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node, ++ const unsigned char *name, ++ const unsigned char *string) ++{ ++ int len, i; ++ OF_prop_t *ret; ++ unsigned char *str; ++ ++ if (strchr(string, '\1') == NULL) { ++ return OF_prop_string_new(env, node, name, string); ++ } else { ++ len = strlen(string) + 1; ++ str = malloc(len); ++ if (!str) ++ return NULL; ++ memcpy(str, string, len); ++ for(i = 0; i < len; i++) ++ if (str[i] == '\1') ++ str[i] = '\0'; ++ ret = OF_property_new(env, node, name, ++ str, len); ++ free(str); ++ return ret; ++ } ++} ++ + __attribute__ (( section (".OpenFirmware") )) + static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node, + const unsigned char *name, uint32_t value) +@@ -1421,15 +1448,12 @@ + __attribute__ (( section (".OpenFirmware") )) + int OF_init (void) + { +- const unsigned char compat_str[] = + #if 0 + "PowerMac3,1\0MacRISC\0Power Macintosh\0"; + "PowerMac1,2\0MacRISC\0Power Macintosh\0"; + "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0"; + "AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0"; + "AAPL,Gossamer\0MacRISC\0Power Macintosh\0"; +-#else +- "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0"; + #endif + OF_env_t *OF_env; + OF_node_t *als, *opt, *chs, *pks; +@@ -1455,15 +1479,21 @@ + return -1; + } + OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom"); +-#if 0 +- OF_prop_string_new(OF_env, OF_node_root, +- "model", "PPC Open Hack'Ware " BIOS_VERSION); +-#else ++ if (arch == ARCH_HEATHROW) { ++ const unsigned char compat_str[] = ++ "PowerMac1,1\0MacRISC\0Power Macintosh"; ++ OF_property_new(OF_env, OF_node_root, "compatible", ++ compat_str, sizeof(compat_str)); + OF_prop_string_new(OF_env, OF_node_root, +- "model", compat_str); +-#endif ++ "model", "Power Macintosh"); ++ } else { ++ const unsigned char compat_str[] = ++ "PowerMac3,1\0MacRISC\0Power Macintosh"; + OF_property_new(OF_env, OF_node_root, "compatible", + compat_str, sizeof(compat_str)); ++ OF_prop_string_new(OF_env, OF_node_root, ++ "model", "PowerMac3,1"); ++ } + #if 0 + OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright); + #else +@@ -1561,14 +1591,15 @@ + range.size = 0x00800000; + OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t)); + OF_prop_int_new(OF_env, rom, "#address-cells", 1); ++ + /* "/rom/boot-rom@fff00000" node */ +- brom = OF_node_new(OF_env, OF_node_root, "boot-rom", 0xfff00000); ++ brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000); + if (brom == NULL) { + ERROR("Cannot create 'boot-rom'\n"); + return -1; + } + regs.address = 0xFFF00000; +- regs.size = 0x00010000; ++ regs.size = 0x00100000; + OF_property_new(OF_env, brom, "reg", ®s, sizeof(OF_regprop_t)); + OF_prop_string_new(OF_env, brom, "write-characteristic", "flash"); + OF_prop_string_new(OF_env, brom, "BootROM-build-date", +@@ -1577,7 +1608,7 @@ + OF_prop_string_new(OF_env, brom, "copyright", copyright); + OF_prop_string_new(OF_env, brom, "model", BIOS_str); + OF_prop_int_new(OF_env, brom, "result", 0); +-#if 0 ++#if 1 + { + /* Hack taken 'as-is' from PearPC */ + unsigned char info[] = { +@@ -1596,7 +1627,9 @@ + OF_node_put(OF_env, brom); + OF_node_put(OF_env, rom); + } ++#if 0 + /* From here, hardcoded hacks to get a Mac-like machine */ ++ /* XXX: Core99 does not seem to like this NVRAM tree */ + /* "/nvram@fff04000" node */ + { + OF_regprop_t regs; +@@ -1617,6 +1650,7 @@ + OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr)); + OF_node_put(OF_env, nvr); + } ++#endif + /* "/pseudo-hid" : hid emulation as Apple does */ + { + OF_node_t *hid; +@@ -1663,7 +1697,27 @@ + } + OF_node_put(OF_env, hid); + } ++ if (arch == ARCH_MAC99) { ++ OF_node_t *unin; ++ OF_regprop_t regs; + ++ unin = OF_node_new(OF_env, OF_node_root, ++ "uni-n", 0xf8000000); ++ if (unin == NULL) { ++ ERROR("Cannot create 'uni-n'\n"); ++ return -1; ++ } ++ OF_prop_string_new(OF_env, unin, "device-type", "memory-controller"); ++ OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth"); ++ OF_prop_string_new(OF_env, unin, "compatible", "uni-north"); ++ regs.address = 0xf8000000; ++ regs.size = 0x01000000; ++ OF_property_new(OF_env, unin, "reg", ®s, sizeof(regs)); ++ OF_prop_int_new(OF_env, unin, "#address-cells", 1); ++ OF_prop_int_new(OF_env, unin, "#size-cells", 1); ++ OF_prop_int_new(OF_env, unin, "device-rev", 3); ++ OF_node_put(OF_env, unin); ++ } + + #if 1 /* This is mandatory for claim to work + * but I don't know where it should really be (in cpu ?) +@@ -1693,7 +1747,9 @@ + + /* "/options/boot-args" node */ + { +- const unsigned char *args = "-v rootdev cdrom"; ++ // const unsigned char *args = "-v rootdev cdrom"; ++ //const unsigned char *args = "-v io=0xffffffff"; ++ const unsigned char *args = "-v"; + /* Ask MacOS X to print debug messages */ + // OF_prop_string_new(OF_env, chs, "machargs", args); + // OF_prop_string_new(OF_env, opt, "boot-command", args); +@@ -2013,17 +2069,17 @@ + OF_prop_int_new(OF_env, node, "min-grant", min_grant); + OF_prop_int_new(OF_env, node, "max-latency", max_latency); + if (dev->type != NULL) +- OF_prop_string_new(OF_env, node, "device_type", dev->type); ++ OF_prop_string_new1(OF_env, node, "device_type", dev->type); + if (dev->compat != NULL) +- OF_prop_string_new(OF_env, node, "compatible", dev->compat); ++ OF_prop_string_new1(OF_env, node, "compatible", dev->compat); + if (dev->model != NULL) +- OF_prop_string_new(OF_env, node, "model", dev->model); ++ OF_prop_string_new1(OF_env, node, "model", dev->model); + if (dev->acells != 0) + OF_prop_int_new(OF_env, node, "#address-cells", dev->acells); + if (dev->scells != 0) +- OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->acells); ++ OF_prop_int_new(OF_env, node, "#size-cells", dev->scells); + if (dev->icells != 0) +- OF_prop_int_new(OF_env, node, "#size-cells", dev->acells); ++ OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells); + dprintf("Done %p %p\n", parent, node); + + return node; +@@ -2040,8 +2096,9 @@ + OF_env_t *OF_env; + pci_range_t ranges[3]; + OF_regprop_t regs[1]; +- OF_node_t *pci_host; ++ OF_node_t *pci_host, *als; + int nranges; ++ unsigned char buffer[OF_NAMELEN_MAX]; + + OF_env = OF_env_main; + dprintf("register PCI host '%s' '%s' '%s' '%s'\n", +@@ -2052,6 +2109,17 @@ + ERROR("Cannot create pci host\n"); + return NULL; + } ++ ++ als = OF_node_get(OF_env, "aliases"); ++ if (als == NULL) { ++ ERROR("Cannot get 'aliases'\n"); ++ return NULL; ++ } ++ sprintf(buffer, "/%s", dev->name); ++ OF_prop_string_set(OF_env, als, "pci", buffer); ++ OF_node_put(OF_env, als); ++ ++ + regs[0].address = cfg_base; + regs[0].size = cfg_len; + OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t)); +@@ -2136,6 +2204,11 @@ + return pci_dev; + } + ++/* XXX: suppress that, used for interrupt map init */ ++OF_node_t *pci_host_node; ++uint32_t pci_host_interrupt_map[7 * 32]; ++int pci_host_interrupt_map_len = 0; ++ + void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses) + { + OF_env_t *OF_env; +@@ -2145,10 +2218,12 @@ + regs[0].address = first_bus; + regs[0].size = nb_busses; + OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t)); ++ pci_host_node = dev; + } + + void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn, +- uint32_t *regions, uint32_t *sizes) ++ uint32_t *regions, uint32_t *sizes, ++ int irq_line) + { + OF_env_t *OF_env; + pci_reg_prop_t pregs[6], rregs[6]; +@@ -2156,6 +2231,7 @@ + int i, j, k; + + OF_env = OF_env_main; ++ /* XXX: only useful for VGA card in fact */ + if (regions[0] != 0x00000000) + OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F); + for (i = 0, j = 0, k = 0; i < 6; i++) { +@@ -2222,7 +2298,22 @@ + } else { + OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0); + } +-#if 0 ++ if (irq_line >= 0) { ++ int i; ++ OF_prop_int_new(OF_env, dev, "interrupts", 1); ++ i = pci_host_interrupt_map_len; ++ pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800; ++ pci_host_interrupt_map[i++] = 0; ++ pci_host_interrupt_map[i++] = 0; ++ pci_host_interrupt_map[i++] = 0; ++ pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */ ++ pci_host_interrupt_map[i++] = irq_line; ++ if (arch != ARCH_HEATHROW) { ++ pci_host_interrupt_map[i++] = 1; ++ } ++ pci_host_interrupt_map_len = i; ++ } ++#if 1 + { + OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name; + +@@ -2390,6 +2481,54 @@ + return 0; + } + ++static void keylargo_ata(OF_node_t *mio, uint32_t base_address, ++ uint32_t base, int irq1, int irq2, ++ uint16_t pic_phandle) ++{ ++ OF_env_t *OF_env = OF_env_main; ++ OF_node_t *ata; ++ OF_regprop_t regs[2]; ++ ++ ata = OF_node_new(OF_env, mio, "ata-4", base); ++ if (ata == NULL) { ++ ERROR("Cannot create 'ata-4'\n"); ++ return; ++ } ++ OF_prop_string_new(OF_env, ata, "device_type", "ata"); ++#if 1 ++ OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata"); ++ OF_prop_string_new(OF_env, ata, "model", "ata-4"); ++ OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor"); ++#else ++ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); ++ OF_prop_string_new(OF_env, ata, "model", "ata-4"); ++#endif ++ OF_prop_int_new(OF_env, ata, "#address-cells", 1); ++ OF_prop_int_new(OF_env, ata, "#size-cells", 0); ++ regs[0].address = base; ++ regs[0].size = 0x00001000; ++#if 0 // HACK: Don't set up DMA registers ++ regs[1].address = 0x00008A00; ++ regs[1].size = 0x00001000; ++ OF_property_new(OF_env, ata, "reg", ++ regs, 2 * sizeof(OF_regprop_t)); ++#else ++ OF_property_new(OF_env, ata, "reg", ++ regs, sizeof(OF_regprop_t)); ++#endif ++ OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); ++ regs[0].address = irq1; ++ regs[0].size = 0x00000001; ++ regs[1].address = irq2; ++ regs[1].size = 0x00000000; ++ OF_property_new(OF_env, ata, "interrupts", ++ regs, 2 * sizeof(OF_regprop_t)); ++ if (base == 0x1f000) ++ ide_pci_pmac_register(base_address + base, 0x00000000, ata); ++ else ++ ide_pci_pmac_register(0x00000000, base_address + base, ata); ++} ++ + void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size, + void *private_data) + { +@@ -2398,6 +2537,8 @@ + pci_reg_prop_t pregs[2]; + OF_node_t *mio, *chs, *als; + uint16_t pic_phandle; ++ int rec_len; ++ OF_prop_t *mio_reg; + + OF_DPRINTF("mac-io: %p\n", dev); + OF_env = OF_env_main; +@@ -2416,10 +2557,14 @@ + mio = dev; + mio->private_data = private_data; + pregs[0].addr.hi = 0x00000000; +- pregs[0].addr.mid = 0x82013810; ++ pregs[0].addr.mid = 0x00000000; + pregs[0].addr.lo = 0x00000000; + pregs[0].size_hi = base_address; + pregs[0].size_lo = size; ++ mio_reg = OF_property_get(OF_env, mio, "reg"); ++ if (mio_reg && mio_reg->vlen >= 5 * 4) { ++ pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi; ++ } + OF_property_new(OF_env, mio, "ranges", + &pregs, sizeof(pci_reg_prop_t)); + #if 0 +@@ -2431,8 +2576,32 @@ + OF_property_new(OF_env, mio, "assigned-addresses", + &pregs, sizeof(pci_reg_prop_t)); + #endif ++ ++ if (arch == ARCH_HEATHROW) { ++ /* Heathrow PIC */ ++ OF_regprop_t regs; ++ OF_node_t *mpic; ++ const char compat_str[] = "heathrow\0mac-risc"; ++ ++ mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10); ++ if (mpic == NULL) { ++ ERROR("Cannot create 'mpic'\n"); ++ goto out; ++ } ++ OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller"); ++ OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str)); ++ OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1); ++ regs.address = 0x10; ++ regs.size = 0x20; ++ OF_property_new(OF_env, mpic, "reg", ++ ®s, sizeof(regs)); ++ OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0); ++ pic_phandle = OF_pack_handle(OF_env, mpic); ++ OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); ++ OF_node_put(OF_env, mpic); ++ rec_len = 6; ++ } else { + /* OpenPIC */ +- { + OF_regprop_t regs[4]; + OF_node_t *mpic; + mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000); +@@ -2455,8 +2624,37 @@ + pic_phandle = OF_pack_handle(OF_env, mpic); + OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); + OF_node_put(OF_env, mpic); ++ rec_len = 7; + } +-#if 1 ++ ++ /* patch pci host table */ ++ /* XXX: do it after the PCI init */ ++ { ++ int i; ++ uint32_t tab[4]; ++ ++ for(i = 0; i < pci_host_interrupt_map_len; i += rec_len) ++ pci_host_interrupt_map[i + 4] = pic_phandle; ++#if 0 ++ dprintf("interrupt-map:\n"); ++ for(i = 0; i < pci_host_interrupt_map_len; i++) { ++ dprintf(" %08x", pci_host_interrupt_map[i]); ++ if ((i % rec_len) == (rec_len - 1)) ++ dprintf("\n"); ++ } ++ dprintf("\n"); ++#endif ++ OF_property_new(OF_env, pci_host_node, "interrupt-map", ++ pci_host_interrupt_map, ++ pci_host_interrupt_map_len * sizeof(uint32_t)); ++ tab[0] = 0xf800; ++ tab[1] = 0; ++ tab[2] = 0; ++ tab[3] = 0; ++ OF_property_new(OF_env, pci_host_node, "interrupt-map-mask", ++ tab, 4 * sizeof(uint32_t)); ++ } ++#if 0 + /* escc is usefull to get MacOS X debug messages */ + { + OF_regprop_t regs[8]; +@@ -2645,85 +2843,12 @@ + OF_node_put(OF_env, scc); + } + #endif +- /* IDE controller */ +- { +- OF_node_t *ata; +- OF_regprop_t regs[2]; +- ata = OF_node_new(OF_env, mio, "ata-4", 0x1f000); +- if (ata == NULL) { +- ERROR("Cannot create 'ata-4'\n"); +- goto out; +- } +- OF_prop_string_new(OF_env, ata, "device_type", "ata"); +-#if 1 +- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata"); +- OF_prop_string_new(OF_env, ata, "model", "ata-4"); +-#else +- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); +- OF_prop_string_new(OF_env, ata, "model", "ata-4"); +-#endif +- OF_prop_int_new(OF_env, ata, "#address-cells", 1); +- OF_prop_int_new(OF_env, ata, "#size-cells", 0); +- regs[0].address = 0x0001F000; +- regs[0].size = 0x00001000; +-#if 0 // HACK: Don't set up DMA registers +- regs[1].address = 0x00008A00; +- regs[1].size = 0x00001000; +- OF_property_new(OF_env, ata, "reg", +- regs, 2 * sizeof(OF_regprop_t)); +-#else +- OF_property_new(OF_env, ata, "reg", +- regs, sizeof(OF_regprop_t)); +-#endif +- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); +- regs[0].address = 0x00000013; +- regs[0].size = 0x00000001; +- regs[1].address = 0x0000000B; +- regs[1].size = 0x00000000; +- OF_property_new(OF_env, ata, "interrupts", +- regs, 2 * sizeof(OF_regprop_t)); +- ide_pci_pmac_register(base_address + 0x1f000, 0x00000000, ata); +- +- } +- { +- OF_node_t *ata; +- OF_regprop_t regs[2]; +- ata = OF_node_new(OF_env, mio, "ata-4", 0x20000); +- if (ata == NULL) { +- ERROR("Cannot create 'ata-4'\n"); +- goto out; +- } +- OF_prop_string_new(OF_env, ata, "device_type", "ata"); +-#if 1 +- OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata"); +- OF_prop_string_new(OF_env, ata, "model", "ata-4"); +-#else +- OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); +- OF_prop_string_new(OF_env, ata, "model", "ata-4"); +-#endif +- OF_prop_int_new(OF_env, ata, "#address-cells", 1); +- OF_prop_int_new(OF_env, ata, "#size-cells", 0); +- regs[0].address = 0x00020000; +- regs[0].size = 0x00001000; +-#if 0 // HACK: Don't set up DMA registers +- regs[1].address = 0x00008A00; +- regs[1].size = 0x00001000; +- OF_property_new(OF_env, ata, "reg", +- regs, 2 * sizeof(OF_regprop_t)); +-#else +- OF_property_new(OF_env, ata, "reg", +- regs, sizeof(OF_regprop_t)); +-#endif +- OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); +- regs[0].address = 0x00000014; +- regs[0].size = 0x00000001; +- regs[1].address = 0x0000000B; +- regs[1].size = 0x00000000; +- OF_property_new(OF_env, ata, "interrupts", +- regs, 2 * sizeof(OF_regprop_t)); +- ide_pci_pmac_register(0x00000000, base_address + 0x20000, ata); +- ++ /* Keylargo IDE controller: need some work (DMA problem ?) */ ++ if (arch == ARCH_MAC99) { ++ keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle); ++ keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle); + } ++#if 0 + /* Timer */ + { + OF_node_t *tmr; +@@ -2746,10 +2871,11 @@ + regs, sizeof(OF_regprop_t)); + OF_node_put(OF_env, tmr); + } ++#endif + /* VIA-PMU */ + { + /* Controls adb, RTC and power-mgt (forget it !) */ +- OF_node_t *via, *adb, *rtc; ++ OF_node_t *via, *adb; + OF_regprop_t regs[1]; + #if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD ! + // (but needed has Qemu doesn't emulate via-pmu). +@@ -2773,14 +2899,21 @@ + regs[0].size = 0x00002000; + OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t)); + OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle); ++ if (arch == ARCH_HEATHROW) { ++ OF_prop_int_new(OF_env, via, "interrupts", 0x12); ++ } else { + regs[0].address = 0x00000019; + regs[0].size = 0x00000001; + OF_property_new(OF_env, via, "interrupts", + regs, sizeof(OF_regprop_t)); ++ } ++ /* force usage of OF bus speeds */ ++ OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1); + #if 0 + OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C); + #endif +-#if 1 ++ { ++ OF_node_t *kbd, *mouse; + /* ADB pseudo-device */ + adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE); + if (adb == NULL) { +@@ -2797,9 +2930,26 @@ + OF_prop_int_new(OF_env, adb, "#size-cells", 0); + OF_pack_get_path(OF_env, tmp, 512, adb); + OF_prop_string_new(OF_env, als, "adb", tmp); +- /* XXX: add "keyboard@2" and "mouse@3" */ +- OF_node_put(OF_env, adb); +-#endif ++ ++ kbd = OF_node_new(OF_env, adb, "keyboard", 2); ++ if (kbd == NULL) { ++ ERROR("Cannot create 'kbd'\n"); ++ goto out; ++ } ++ OF_prop_string_new(OF_env, kbd, "device_type", "keyboard"); ++ OF_prop_int_new(OF_env, kbd, "reg", 2); ++ ++ mouse = OF_node_new(OF_env, adb, "mouse", 3); ++ if (mouse == NULL) { ++ ERROR("Cannot create 'mouse'\n"); ++ goto out; ++ } ++ OF_prop_string_new(OF_env, mouse, "device_type", "mouse"); ++ OF_prop_int_new(OF_env, mouse, "reg", 3); ++ OF_prop_int_new(OF_env, mouse, "#buttons", 3); ++ } ++ { ++ OF_node_t *rtc; + + rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE); + if (rtc == NULL) { +@@ -2813,14 +2963,68 @@ + OF_prop_string_new(OF_env, rtc, "compatible", "rtc"); + #endif + OF_node_put(OF_env, rtc); +- OF_node_put(OF_env, via); + } ++ // OF_node_put(OF_env, via); ++ } ++ { ++ OF_node_t *pmgt; ++ pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE); ++ OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt"); ++ OF_prop_string_new(OF_env, pmgt, "compatible", "cuda"); ++ OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led"); ++ OF_node_put(OF_env, pmgt); ++ } ++ ++ if (arch == ARCH_HEATHROW) { ++ /* NVRAM */ ++ OF_node_t *nvr; ++ OF_regprop_t regs; ++ nvr = OF_node_new(OF_env, mio, "nvram", 0x60000); ++ OF_prop_string_new(OF_env, nvr, "device_type", "nvram"); ++ regs.address = 0x60000; ++ regs.size = 0x00020000; ++ OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs)); ++ OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000); ++ OF_node_put(OF_env, nvr); ++ } ++ + out: + // OF_node_put(OF_env, mio); + OF_node_put(OF_env, chs); + OF_node_put(OF_env, als); + } + ++void OF_finalize_pci_ide (void *dev, ++ uint32_t io_base0, uint32_t io_base1, ++ uint32_t io_base2, uint32_t io_base3) ++{ ++ OF_env_t *OF_env = OF_env_main; ++ OF_node_t *pci_ata = dev; ++ OF_node_t *ata, *atas[2]; ++ int i; ++ ++ OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1); ++ OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0); ++ ++ /* XXX: Darwin handles only one device */ ++ for(i = 0; i < 1; i++) { ++ ata = OF_node_new(OF_env, pci_ata, "ata-4", i); ++ if (ata == NULL) { ++ ERROR("Cannot create 'ata-4'\n"); ++ return; ++ } ++ OF_prop_string_new(OF_env, ata, "device_type", "ata"); ++ OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); ++ OF_prop_string_new(OF_env, ata, "model", "ata-4"); ++ OF_prop_int_new(OF_env, ata, "#address-cells", 1); ++ OF_prop_int_new(OF_env, ata, "#size-cells", 0); ++ OF_prop_int_new(OF_env, ata, "reg", i); ++ atas[i] = ata; ++ } ++ ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3, ++ atas[0], atas[1]); ++} ++ + /*****************************************************************************/ + /* Fake package */ + static void OF_method_fake (OF_env_t *OF_env) +@@ -2862,11 +3066,11 @@ + /* As we get a 1:1 mapping, do nothing */ + ihandle = popd(OF_env); + args = (void *)popd(OF_env); +- address = popd(OF_env); +- virt = popd(OF_env); +- size = popd(OF_env); + popd(OF_env); +- OF_DPRINTF("Translate address %0x %0x %0x %0x\n", ihandle, address, ++ size = popd(OF_env); ++ virt = popd(OF_env); ++ address = popd(OF_env); ++ OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address, + virt, size); + pushd(OF_env, 0); + } +@@ -3270,7 +3474,7 @@ + OF_prop_string_new(OF_env, dsk, "device_type", "block"); + OF_prop_string_new(OF_env, dsk, "category", type); + OF_prop_int_new(OF_env, dsk, "device_id", devnum); +- OF_prop_int_new(OF_env, dsk, "reg", 0); ++ OF_prop_int_new(OF_env, dsk, "reg", devnum); + OF_method_new(OF_env, dsk, "open", &OF_blockdev_open); + OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek); + OF_method_new(OF_env, dsk, "read", &OF_blockdev_read); +@@ -3432,7 +3636,8 @@ + } + + void OF_vga_register (const unsigned char *name, unused uint32_t address, +- int width, int height, int depth) ++ int width, int height, int depth, ++ unsigned long vga_bios_addr, unsigned long vga_bios_size) + { + OF_env_t *OF_env; + unsigned char tmp[OF_NAMELEN_MAX]; +@@ -3504,6 +3709,18 @@ + OF_prop_string_new(OF_env, als, "display", tmp); + OF_node_put(OF_env, als); + /* XXX: may also need read-rectangle */ ++ ++ if (vga_bios_size >= 8) { ++ const uint8_t *p; ++ int size; ++ /* check the QEMU VGA BIOS header */ ++ p = (const uint8_t *)vga_bios_addr; ++ if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { ++ size = *(uint32_t *)(p + 4); ++ OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC", ++ p + 8, size); ++ } ++ } + out: + OF_node_put(OF_env, disp); + } +@@ -4451,7 +4668,10 @@ + break; + case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */ + /* Create "memory-map" pseudo device */ +- popd(OF_env); ++ { ++ OF_node_t *map; ++ uint32_t phandle; ++ + /* Find "/packages" */ + chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen"); + if (chs == NULL) { +@@ -4459,10 +4679,6 @@ + ERROR("Cannot get '/chosen'\n"); + break; + } +- { +-#if 1 +- OF_node_t *map; +- uint32_t phandle; + map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE); + if (map == NULL) { + pushd(OF_env, -1); +@@ -4473,11 +4689,8 @@ + OF_node_put(OF_env, map); + OF_node_put(OF_env, chs); + pushd(OF_env, phandle); +- } +-#else +- pushd(OF_env, 0); +-#endif + pushd(OF_env, 0); ++ } + break; + case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */ + /* Return screen ihandle */ +@@ -4540,9 +4753,10 @@ + case 0x4ad41f2d: + /* Yaboot: wait 10 ms: sure ! */ + break; ++ + default: + /* ERROR */ +- printf("Script:\n%s\n", FString); ++ printf("Script: len=%d\n%s\n", (int)strlen(FString), FString); + printf("Call %0x NOT IMPLEMENTED !\n", crc); + bug(); + break; +@@ -4581,6 +4795,7 @@ + { + OF_CHECK_NBARGS(OF_env, 0); + /* Should free all OF resources */ ++ bd_reset_all(); + #if defined (DEBUG_BIOS) + { + uint16_t loglevel = 0x02 | 0x10 | 0x80; +diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/pci.c OpenHackWare-release-0.4/src/pci.c +--- OpenHackWare-release-0.4.org/src/pci.c 2005-03-31 09:23:33.000000000 +0200 ++++ OpenHackWare-release-0.4/src/pci.c 2005-07-07 23:27:37.000000000 +0200 +@@ -99,8 +99,8 @@ + uint16_t min_grant; + uint16_t max_latency; + uint8_t irq_line; +- uint32_t regions[6]; +- uint32_t sizes[6]; ++ uint32_t regions[7]; /* the region 6 is the PCI ROM */ ++ uint32_t sizes[7]; + pci_device_t *next; + }; + +@@ -158,6 +158,7 @@ + + /* IRQ numbers assigned to PCI IRQs */ + static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 }; ++static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 }; + static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 }; + + /* PREP PCI host */ +@@ -399,6 +400,79 @@ + &uninorth_config_readl, &uninorth_config_writel, + }; + ++/* Grackle PCI host */ ++ ++static uint32_t grackle_cfg_address (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset) ++{ ++ uint32_t addr; ++ addr = 0x80000000 | (bus << 16) | (devfn << 8) | (offset & 0xfc); ++ stswap32((uint32_t *)bridge->cfg_addr, addr); ++ return bridge->cfg_data + (offset & 3); ++} ++ ++static uint8_t grackle_config_readb (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset) ++{ ++ uint32_t addr; ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ return *((uint8_t *)addr); ++} ++ ++static void grackle_config_writeb (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset, uint8_t val) ++{ ++ uint32_t addr; ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ *((uint8_t *)addr) = val; ++} ++ ++static uint16_t grackle_config_readw (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset) ++{ ++ uint32_t addr; ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ return ldswap16((uint16_t *)addr); ++} ++ ++static void grackle_config_writew (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset, uint16_t val) ++{ ++ uint32_t addr; ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ stswap16((uint16_t *)addr, val); ++} ++ ++static uint32_t grackle_config_readl (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset) ++{ ++ uint32_t addr; ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ return ldswap32((uint32_t *)addr); ++} ++ ++static void grackle_config_writel (pci_bridge_t *bridge, ++ uint8_t bus, uint8_t devfn, ++ uint8_t offset, uint32_t val) ++{ ++ uint32_t addr; ++ ++ addr = grackle_cfg_address(bridge, bus, devfn, offset); ++ stswap32((uint32_t *)addr, val); ++} ++ ++static pci_ops_t grackle_pci_ops = { ++ &grackle_config_readb, &grackle_config_writeb, ++ &grackle_config_readw, &grackle_config_writew, ++ &grackle_config_readl, &grackle_config_writel, ++}; ++ + static inline uint8_t pci_config_readb (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset) +@@ -466,12 +540,22 @@ + }, + }; + ++static int ide_config_cb2 (pci_device_t *device) ++{ ++ OF_finalize_pci_ide(device->common.OF_private, ++ device->regions[0] & ~0x0000000F, ++ device->regions[1] & ~0x0000000F, ++ device->regions[2] & ~0x0000000F, ++ device->regions[3] & ~0x0000000F); ++ return 0; ++} ++ + static pci_dev_t ide_devices[] = { + { +- 0x8086, 0x0100, +- NULL, "Qemu IDE", "Qemu IDE", "ide", ++ 0x1095, 0x0646, /* CMD646 IDE controller */ ++ "pci-ide", "pci-ata", NULL, NULL, + 0, 0, 0, +- NULL, NULL, ++ ide_config_cb2, NULL, + }, + { + 0xFFFF, 0xFFFF, +@@ -481,7 +565,9 @@ + }, + }; + +-static int ide_config_cb (pci_device_t *device) ++#if 0 ++/* should base it on PCI ID, not on arch */ ++static int ide_config_cb (unused pci_device_t *device) + { + printf("Register IDE controller\n"); + switch (arch) { +@@ -491,14 +577,8 @@ + device->common.OF_private); + break; + default: +- ide_pci_pc_register(device->regions[0] & ~0x0000000F, +- device->regions[1] & ~0x0000000F, +- device->regions[2] & ~0x0000000F, +- device->regions[3] & ~0x0000000F, +- device->common.OF_private); + break; + } +- + return 0; + } + +@@ -512,16 +592,12 @@ + device->common.OF_private); + break; + default: +- ide_pci_pc_register(device->regions[0] & ~0x0000000F, +- device->regions[1] & ~0x0000000F, +- device->regions[2] & ~0x0000000F, +- device->regions[3] & ~0x0000000F, +- device->common.OF_private); + break; + } + + return 0; + } ++#endif + + static pci_subclass_t mass_subclass[] = { + { +@@ -530,7 +606,7 @@ + }, + { + 0x01, "IDE controller", "ide", ide_devices, NULL, +- &ide_config_cb, NULL, ++ NULL, NULL, + }, + { + 0x02, "Floppy disk controller", NULL, NULL, NULL, +@@ -546,7 +622,7 @@ + }, + { + 0x05, "ATA controller", "ata", NULL, NULL, +- &ata_config_cb, NULL, ++ NULL, NULL, + }, + { + 0x80, "misc mass-storage controller", NULL, NULL, NULL, +@@ -646,7 +722,9 @@ + /* VGA 640x480x16 */ + OF_vga_register(device->common.device->name, + device->regions[0] & ~0x0000000F, +- vga_width, vga_height, vga_depth); ++ vga_width, vga_height, vga_depth, ++ device->regions[6] & ~0x0000000F, ++ device->sizes[6]); + } + vga_console_register(); + +@@ -750,6 +828,13 @@ + NULL, &PREP_pci_ops, + }; + ++pci_dev_t grackle_fake_bridge = { ++ 0xFFFF, 0xFFFF, ++ "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge", ++ -1, -1, -1, ++ NULL, &grackle_pci_ops, ++}; ++ + static pci_dev_t hbrg_devices[] = { + { + 0x106B, 0x0020, NULL, +@@ -758,8 +843,8 @@ + NULL, &uninorth_agp_fake_bridge, + }, + { +- 0x106B, 0x001F, +- NULL, "pci", "AAPL,UniNorth", "uni-north", ++ 0x106B, 0x001F, NULL, ++ "pci", "AAPL,UniNorth", "uni-north", + 3, 2, 1, + NULL, &uninorth_fake_bridge, + }, +@@ -770,10 +855,10 @@ + NULL, &uninorth_fake_bridge, + }, + { +- 0x1011, 0x0026, NULL, +- "pci-bridge", NULL, NULL, ++ 0x1057, 0x0002, "pci", ++ "pci", "MOT,MPC106", "grackle", + 3, 2, 1, +- NULL, &PREP_pci_ops, ++ NULL, &grackle_fake_bridge, + }, + { + 0x1057, 0x4801, NULL, +@@ -1443,7 +1528,14 @@ + } + + static const pci_dev_t misc_pci[] = { +- /* Apple Mac-io controller */ ++ /* Paddington Mac I/O */ ++ { ++ 0x106B, 0x0017, ++ "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow", ++ 1, 1, 1, ++ &macio_config_cb, NULL, ++ }, ++ /* KeyLargo Mac I/O */ + { + 0x106B, 0x0022, + "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo", +@@ -1599,7 +1691,7 @@ + uint8_t min_grant, uint8_t max_latency, + int irq_line) + { +- uint32_t cmd; ++ uint32_t cmd, addr; + int i; + + device->min_grant = min_grant; +@@ -1611,22 +1703,28 @@ + printf("MAP PCI device %d:%d to IRQ %d\n", + device->bus, device->devfn, irq_line); + } +- for (i = 0; i < 6; i++) { ++ for (i = 0; i < 7; i++) { + if ((device->regions[i] & ~0xF) != 0x00000000 && + (device->regions[i] & ~0xF) != 0xFFFFFFF0) { + printf("Map PCI device %d:%d %d to %0x %0x (%s)\n", + device->bus, device->devfn, i, + device->regions[i], device->sizes[i], +- device->regions[i] & 0x00000001 ? "I/O" : "memory"); ++ (device->regions[i] & 0x00000001) && i != 6 ? "I/O" : ++ "memory"); ++ if (i != 6) { + cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04); + if (device->regions[i] & 0x00000001) + cmd |= 0x00000001; + else + cmd |= 0x00000002; + pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd); ++ } ++ if (i == 6) ++ addr = 0x30; /* PCI ROM */ ++ else ++ addr = 0x10 + (i * sizeof(uint32_t)); + pci_config_writel(bridge, device->bus, device->devfn, +- 0x10 + (i * sizeof(uint32_t)), +- device->regions[i]); ++ addr, device->regions[i]); + } + } + } +@@ -1900,7 +1998,7 @@ + goto out; + } + ret = (pci_u_t *)newd; +- max_areas = 6; ++ max_areas = 7; + /* register PCI device in OF tree */ + if (bridge->dev.common.type == PCI_FAKE_BRIDGE) { + newd->common.OF_private = +@@ -1927,6 +2025,9 @@ + /* Handle 64 bits memory mapping */ + continue; + } ++ if (i == 6) ++ addr = 0x30; /* PCI ROM */ ++ else + addr = 0x10 + (i * sizeof(uint32_t)); + /* Get region size + * Note: we assume it's always a power of 2 +@@ -1935,7 +2036,7 @@ + smask = pci_config_readl(bridge, bus, devfn, addr); + if (smask == 0x00000000 || smask == 0xFFFFFFFF) + continue; +- if (smask & 0x00000001) { ++ if ((smask & 0x00000001) != 0 && i != 6) { + /* I/O space */ + base = io_base; + /* Align to a minimum of 256 bytes (arbitrary) */ +@@ -1947,6 +2048,8 @@ + /* Align to a minimum of 64 kB (arbitrary) */ + min_align = 1 << 16; + amask = 0x0000000F; ++ if (i == 6) ++ smask |= 1; /* PCI ROM enable */ + } + omask = smask & amask; + smask &= ~amask; +@@ -1980,7 +2083,10 @@ + if (irq_pin > 0) { + /* assign the IRQ */ + irq_pin = ((devfn >> 3) + irq_pin - 1) & 3; +- if (arch == ARCH_PREP) { ++ /* XXX: should base it on the PCI bridge type, not the arch */ ++ switch(arch) { ++ case ARCH_PREP: ++ { + int elcr_port, val; + irq_line = prep_pci_irqs[irq_pin]; + /* set the IRQ to level-sensitive */ +@@ -1988,14 +2094,22 @@ + val = inb(elcr_port); + val |= 1 << (irq_line & 7); + outb(elcr_port, val); +- } else { ++ } ++ break; ++ case ARCH_MAC99: + irq_line = pmac_pci_irqs[irq_pin]; ++ break; ++ case ARCH_HEATHROW: ++ irq_line = heathrow_pci_irqs[irq_pin]; ++ break; ++ default: ++ break; + } + } + update_device: + pci_update_device(bridge, newd, min_grant, max_latency, irq_line); + OF_finalize_pci_device(newd->common.OF_private, bus, devfn, +- newd->regions, newd->sizes); ++ newd->regions, newd->sizes, irq_line); + /* Call special inits if needed */ + if (dev->config_cb != NULL) + (*dev->config_cb)(newd); +@@ -2049,6 +2163,32 @@ + case ARCH_CHRP: + /* TODO */ + break; ++ case ARCH_HEATHROW: ++ dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp); ++ if (dev == NULL) ++ return -1; ++ fake_host = pci_add_host(hostp, dev, ++ (0x06 << 24) | (0x00 << 16) | (0xFF << 8)); ++ if (fake_host == NULL) ++ return -1; ++ fake_host->dev.common.type = PCI_FAKE_HOST; ++ dev = &grackle_fake_bridge; ++ if (dev == NULL) ++ goto free_fake_host; ++ fake_bridge = pci_add_bridge(fake_host, 0, 0, dev, ++ (0x06 << 24) | (0x04 << 16) | (0xFF << 8), ++ cfg_base, cfg_len, ++ cfg_base + 0x7ec00000, ++ cfg_base + 0x7ee00000, ++ mem_base, mem_len, ++ io_base, io_len, ++ rbase, rlen, ++ 0, ++ &grackle_pci_ops); ++ if (fake_bridge == NULL) ++ goto free_fake_host; ++ fake_bridge->dev.common.type = PCI_FAKE_BRIDGE; ++ break; + case ARCH_MAC99: + dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp); + if (dev == NULL) +@@ -2167,6 +2307,30 @@ + case ARCH_CHRP: + /* TODO */ + break; ++ case ARCH_HEATHROW: ++ cfg_base = 0x80000000; ++ cfg_len = 0x7f000000; ++ mem_base = 0x80000000; ++ mem_len = 0x01000000; ++ io_base = 0xfe000000; ++ io_len = 0x00800000; ++#if 1 ++ rbase = 0xfd000000; ++ rlen = 0x01000000; ++#else ++ rbase = 0x00000000; ++ rlen = 0x01000000; ++#endif ++ if (pci_check_host(&pci_main, cfg_base, cfg_len, ++ mem_base, mem_len, io_base, io_len, rbase, rlen, ++ 0x1057, 0x0002) == 0) { ++ isa_io_base = io_base; ++ busnum++; ++ } ++ for (curh = pci_main; curh->next != NULL; curh = curh->next) ++ continue; ++ pci_check_devices(curh); ++ break; + case ARCH_MAC99: + /* We are supposed to have 3 host bridges: + * - the uninorth AGP bridge at 0xF0000000 diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32 new file mode 100644 index 0000000..7a729aa Binary files /dev/null and b/pc-bios/openbios-sparc32 differ diff --git a/pc-bios/ppc_rom.bin b/pc-bios/ppc_rom.bin new file mode 100644 index 0000000..f7cd8a8 Binary files /dev/null and b/pc-bios/ppc_rom.bin differ diff --git a/pc-bios/vgabios-cirrus.bin b/pc-bios/vgabios-cirrus.bin new file mode 100644 index 0000000..34f9a9f Binary files /dev/null and b/pc-bios/vgabios-cirrus.bin differ diff --git a/pc-bios/vgabios.bin b/pc-bios/vgabios.bin new file mode 100644 index 0000000..17cb63f Binary files /dev/null and b/pc-bios/vgabios.bin differ diff --git a/pc-bios/vgabios.diff b/pc-bios/vgabios.diff new file mode 100644 index 0000000..661c032 --- /dev/null +++ b/pc-bios/vgabios.diff @@ -0,0 +1,896 @@ +Index: Makefile +=================================================================== +RCS file: /sources/vgabios/vgabios/Makefile,v +retrieving revision 1.17 +diff -u -w -r1.17 Makefile +--- Makefile 6 Mar 2005 13:06:47 -0000 1.17 ++++ Makefile 14 Jun 2006 00:51:06 -0000 +@@ -22,7 +22,7 @@ + cirrus-bios: vgabios-cirrus.bin vgabios-cirrus.debug.bin + + clean: +- /bin/rm -f biossums *.o *.s *.ld86 \ ++ /bin/rm -f biossums vbetables-gen vbetables.h *.o *.s *.ld86 \ + temp.awk.* vgabios*.orig _vgabios_* _vgabios-debug_* core vgabios*.bin vgabios*.txt $(RELEASE).bin *.bak + + dist-clean: clean +@@ -79,3 +79,9 @@ + + biossums: biossums.c + $(CC) -o biossums biossums.c ++ ++vbetables-gen: vbetables-gen.c ++ $(CC) -o vbetables-gen vbetables-gen.c ++ ++vbetables.h: vbetables-gen ++ ./vbetables-gen > $@ +Index: clext.c +=================================================================== +RCS file: /sources/vgabios/vgabios/clext.c,v +retrieving revision 1.10 +diff -u -w -r1.10 clext.c +--- clext.c 25 Mar 2006 10:19:15 -0000 1.10 ++++ clext.c 14 Jun 2006 00:51:06 -0000 +@@ -544,6 +544,13 @@ + cirrus_set_video_mode_extended: + call cirrus_switch_mode + pop ax ;; mode ++ test al, #0x80 ++ jnz cirrus_set_video_mode_extended_1 ++ push ax ++ mov ax, #0xffff ; set to 0xff to keep win 2K happy ++ call cirrus_clear_vram ++ pop ax ++cirrus_set_video_mode_extended_1: + and al, #0x7f + + push ds +@@ -1011,6 +1018,13 @@ + jnz cirrus_vesa_02h_3 + call cirrus_enable_16k_granularity + cirrus_vesa_02h_3: ++ test bx, #0x8000 ;; no clear ++ jnz cirrus_vesa_02h_4 ++ push ax ++ xor ax,ax ++ call cirrus_clear_vram ++ pop ax ++cirrus_vesa_02h_4: + pop ax + push ds + #ifdef CIRRUS_VESA3_PMINFO +@@ -1479,6 +1493,38 @@ + pop bx + ret + ++cirrus_clear_vram: ++ pusha ++ push es ++ mov si, ax ++ ++ call cirrus_enable_16k_granularity ++ call cirrus_extbios_85h ++ shl al, #2 ++ mov bl, al ++ xor ah,ah ++cirrus_clear_vram_1: ++ mov al, #0x09 ++ mov dx, #0x3ce ++ out dx, ax ++ push ax ++ mov cx, #0xa000 ++ mov es, cx ++ xor di, di ++ mov ax, si ++ mov cx, #8192 ++ cld ++ rep ++ stosw ++ pop ax ++ inc ah ++ cmp ah, bl ++ jne cirrus_clear_vram_1 ++ ++ pop es ++ popa ++ ret ++ + cirrus_extbios_handlers: + ;; 80h + dw cirrus_extbios_80h +Index: vbe.c +=================================================================== +RCS file: /sources/vgabios/vgabios/vbe.c,v +retrieving revision 1.48 +diff -u -w -r1.48 vbe.c +--- vbe.c 26 Dec 2005 19:50:26 -0000 1.48 ++++ vbe.c 14 Jun 2006 00:51:07 -0000 +@@ -118,21 +118,114 @@ + .word VBE_VESA_MODE_END_OF_LIST + #endif + ++ .align 2 + vesa_pm_start: + dw vesa_pm_set_window - vesa_pm_start +- dw vesa_pm_set_display_strt - vesa_pm_start ++ dw vesa_pm_set_display_start - vesa_pm_start + dw vesa_pm_unimplemented - vesa_pm_start +- dw 0 ++ dw vesa_pm_io_ports_table - vesa_pm_start ++vesa_pm_io_ports_table: ++ dw VBE_DISPI_IOPORT_INDEX ++ dw VBE_DISPI_IOPORT_INDEX + 1 ++ dw VBE_DISPI_IOPORT_DATA ++ dw VBE_DISPI_IOPORT_DATA + 1 ++ dw 0xffff ++ dw 0xffff + + USE32 + vesa_pm_set_window: +- mov ax, #0x4f05 +- int #0x10 ++ cmp bx, #0x00 ++ je vesa_pm_set_display_window1 ++ mov ax, #0x0100 ++ ret ++vesa_pm_set_display_window1: ++ mov ax, dx ++ push dx ++ push ax ++ mov dx, # VBE_DISPI_IOPORT_INDEX ++ mov ax, # VBE_DISPI_INDEX_BANK ++ out dx, ax ++ pop ax ++ mov dx, # VBE_DISPI_IOPORT_DATA ++ out dx, ax ++ pop dx ++ mov ax, #0x004f + ret + + vesa_pm_set_display_start: +- mov ax, #0x4f07 +- int #0x10 ++ cmp bl, #0x80 ++ je vesa_pm_set_display_start1 ++ cmp bl, #0x00 ++ je vesa_pm_set_display_start1 ++ mov ax, #0x0100 ++ ret ++vesa_pm_set_display_start1: ++; convert offset to (X, Y) coordinate ++; (would be simpler to change Bochs VBE API...) ++ push eax ++ push ecx ++ push edx ++ push esi ++ push edi ++ shl edx, #16 ++ and ecx, #0xffff ++ or ecx, edx ++ shl ecx, #2 ++ mov eax, ecx ++ ++ push eax ++ mov dx, # VBE_DISPI_IOPORT_INDEX ++ mov ax, # VBE_DISPI_INDEX_VIRT_WIDTH ++ out dx, ax ++ mov dx, # VBE_DISPI_IOPORT_DATA ++ in ax, dx ++ movzx ecx, ax ++ ++ mov dx, # VBE_DISPI_IOPORT_INDEX ++ mov ax, # VBE_DISPI_INDEX_BPP ++ out dx, ax ++ mov dx, # VBE_DISPI_IOPORT_DATA ++ in ax, dx ++ movzx esi, ax ++ pop eax ++ ++ add esi, #7 ++ shr esi, #3 ++ imul ecx, esi ++ xor edx, edx ++ div ecx ++ mov edi, eax ++ mov eax, edx ++ xor edx, edx ++ div esi ++ ++ push dx ++ push ax ++ mov dx, # VBE_DISPI_IOPORT_INDEX ++ mov ax, # VBE_DISPI_INDEX_X_OFFSET ++ out dx, ax ++ pop ax ++ mov dx, # VBE_DISPI_IOPORT_DATA ++ out dx, ax ++ pop dx ++ ++ mov ax, di ++ push dx ++ push ax ++ mov dx, # VBE_DISPI_IOPORT_INDEX ++ mov ax, # VBE_DISPI_INDEX_Y_OFFSET ++ out dx, ax ++ pop ax ++ mov dx, # VBE_DISPI_IOPORT_DATA ++ out dx, ax ++ pop dx ++ ++ pop edi ++ pop esi ++ pop edx ++ pop ecx ++ pop eax ++ mov ax, #0x004f + ret + + vesa_pm_unimplemented: +@@ -835,6 +928,64 @@ + ASM_END + + ++Bit16u vbe_biosfn_read_video_state_size() ++{ ++ return 9 * 2; ++} ++ ++void vbe_biosfn_save_video_state(ES, BX) ++ Bit16u ES; Bit16u BX; ++{ ++ Bit16u enable, i; ++ ++ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ++ enable = inw(VBE_DISPI_IOPORT_DATA); ++ write_word(ES, BX, enable); ++ BX += 2; ++ if (!(enable & VBE_DISPI_ENABLED)) ++ return; ++ for(i = VBE_DISPI_INDEX_XRES; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { ++ if (i != VBE_DISPI_INDEX_ENABLE) { ++ outw(VBE_DISPI_IOPORT_INDEX, i); ++ write_word(ES, BX, inw(VBE_DISPI_IOPORT_DATA)); ++ BX += 2; ++ } ++ } ++} ++ ++ ++void vbe_biosfn_restore_video_state(ES, BX) ++ Bit16u ES; Bit16u BX; ++{ ++ Bit16u enable, i; ++ ++ enable = read_word(ES, BX); ++ BX += 2; ++ ++ if (!(enable & VBE_DISPI_ENABLED)) { ++ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ++ outw(VBE_DISPI_IOPORT_DATA, enable); ++ } else { ++ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_XRES); ++ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ++ BX += 2; ++ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_YRES); ++ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ++ BX += 2; ++ outw(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_BPP); ++ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ++ BX += 2; ++ outw(VBE_DISPI_IOPORT_INDEX,VBE_DISPI_INDEX_ENABLE); ++ outw(VBE_DISPI_IOPORT_DATA, enable); ++ ++ for(i = VBE_DISPI_INDEX_BANK; i <= VBE_DISPI_INDEX_Y_OFFSET; i++) { ++ outw(VBE_DISPI_IOPORT_INDEX, i); ++ outw(VBE_DISPI_IOPORT_DATA, read_word(ES, BX)); ++ BX += 2; ++ } ++ } ++} ++ + /** Function 04h - Save/Restore State + * + * Input: +@@ -849,10 +1000,48 @@ + * BX = Number of 64-byte blocks to hold the state buffer (if DL=00h) + * + */ +-void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX) ++void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX) ++Bit16u *AX; Bit16u CX; Bit16u DX; Bit16u ES; Bit16u *BX; + { +-} ++ Bit16u ss=get_SS(); ++ Bit16u result, val; + ++ result = 0x4f; ++ switch(GET_DL()) { ++ case 0x00: ++ val = biosfn_read_video_state_size2(CX); ++#ifdef DEBUG ++ printf("VGA state size=%x\n", val); ++#endif ++ if (CX & 8) ++ val += vbe_biosfn_read_video_state_size(); ++ write_word(ss, BX, val); ++ break; ++ case 0x01: ++ val = read_word(ss, BX); ++ val = biosfn_save_video_state(CX, ES, val); ++#ifdef DEBUG ++ printf("VGA save_state offset=%x\n", val); ++#endif ++ if (CX & 8) ++ vbe_biosfn_save_video_state(ES, val); ++ break; ++ case 0x02: ++ val = read_word(ss, BX); ++ val = biosfn_restore_video_state(CX, ES, val); ++#ifdef DEBUG ++ printf("VGA restore_state offset=%x\n", val); ++#endif ++ if (CX & 8) ++ vbe_biosfn_restore_video_state(ES, val); ++ break; ++ default: ++ // function failed ++ result = 0x100; ++ break; ++ } ++ write_word(ss, AX, result); ++} + + /** Function 05h - Display Window Control + * +@@ -1090,7 +1279,7 @@ + */ + ASM_START + vbe_biosfn_return_protected_mode_interface: +- test bx, bx ++ test bl, bl + jnz _fail + mov di, #0xc000 + mov es, di +Index: vbe.h +=================================================================== +RCS file: /sources/vgabios/vgabios/vbe.h,v +retrieving revision 1.24 +diff -u -w -r1.24 vbe.h +--- vbe.h 9 May 2004 20:31:31 -0000 1.24 ++++ vbe.h 14 Jun 2006 00:51:07 -0000 +@@ -14,7 +14,7 @@ + void vbe_biosfn_return_controller_information(AX, ES, DI); + void vbe_biosfn_return_mode_information(AX, CX, ES, DI); + void vbe_biosfn_set_mode(AX, BX, ES, DI); +-void vbe_biosfn_save_restore_state(AX, DL, CX, ES, BX); ++void vbe_biosfn_save_restore_state(AX, CX, DX, ES, BX); + void vbe_biosfn_set_get_palette_data(AX); + void vbe_biosfn_return_protected_mode_interface(AX); + +@@ -151,6 +151,12 @@ + Bit8u Reserved[189]; + } ModeInfoBlock; + ++typedef struct ModeInfoListItem ++{ ++ Bit16u mode; ++ ModeInfoBlockCompact info; ++} ModeInfoListItem; ++ + // VBE Return Status Info + // AL + #define VBE_RETURN_STATUS_SUPPORTED 0x4F +@@ -193,6 +199,10 @@ + #define VBE_VESA_MODE_1280X1024X1555 0x119 + #define VBE_VESA_MODE_1280X1024X565 0x11A + #define VBE_VESA_MODE_1280X1024X888 0x11B ++#define VBE_VESA_MODE_1600X1200X8 0x11C ++#define VBE_VESA_MODE_1600X1200X1555 0x11D ++#define VBE_VESA_MODE_1600X1200X565 0x11E ++#define VBE_VESA_MODE_1600X1200X888 0x11F + + // BOCHS/PLEX86 'own' mode numbers + #define VBE_OWN_MODE_320X200X8888 0x140 +@@ -202,6 +212,12 @@ + #define VBE_OWN_MODE_1024X768X8888 0x144 + #define VBE_OWN_MODE_1280X1024X8888 0x145 + #define VBE_OWN_MODE_320X200X8 0x146 ++#define VBE_OWN_MODE_1600X1200X8888 0x147 ++#define VBE_OWN_MODE_1152X864X8 0x148 ++#define VBE_OWN_MODE_1152X864X1555 0x149 ++#define VBE_OWN_MODE_1152X864X565 0x14a ++#define VBE_OWN_MODE_1152X864X888 0x14b ++#define VBE_OWN_MODE_1152X864X8888 0x14c + + #define VBE_VESA_MODE_END_OF_LIST 0xFFFF + +@@ -259,7 +275,7 @@ + // like 0xE0000000 + + +- #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 4 ++ #define VBE_DISPI_TOTAL_VIDEO_MEMORY_MB 8 + + #define VBE_DISPI_BANK_ADDRESS 0xA0000 + #define VBE_DISPI_BANK_SIZE_KB 64 +Index: vgabios.c +=================================================================== +RCS file: /sources/vgabios/vgabios/vgabios.c,v +retrieving revision 1.64 +diff -u -w -r1.64 vgabios.c +--- vgabios.c 25 Mar 2006 10:19:16 -0000 1.64 ++++ vgabios.c 14 Jun 2006 00:51:07 -0000 +@@ -109,8 +109,8 @@ + static void biosfn_write_string(); + static void biosfn_read_state_info(); + static void biosfn_read_video_state_size(); +-static void biosfn_save_video_state(); +-static void biosfn_restore_video_state(); ++static Bit16u biosfn_save_video_state(); ++static Bit16u biosfn_restore_video_state(); + extern Bit8u video_save_pointer_table[]; + + // This is for compiling with gcc2 and gcc3 +@@ -748,12 +748,7 @@ + vbe_biosfn_set_mode(&AX,BX,ES,DI); + break; + case 0x04: +- //FIXME +-#ifdef DEBUG +- unimplemented(); +-#endif +- // function failed +- AX=0x100; ++ vbe_biosfn_save_restore_state(&AX, CX, DX, ES, &BX); + break; + case 0x09: + //FIXME +@@ -3138,23 +3133,215 @@ + } + + // -------------------------------------------------------------------------------------------- +-static void biosfn_read_video_state_size (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX; ++// -------------------------------------------------------------------------------------------- ++static Bit16u biosfn_read_video_state_size2 (CX) ++ Bit16u CX; + { +-#ifdef DEBUG +- unimplemented(); +-#endif ++ Bit16u size; ++ size = 0; ++ if (CX & 1) { ++ size += 0x46; ++ } ++ if (CX & 2) { ++ size += (5 + 8 + 5) * 2 + 6; ++ } ++ if (CX & 4) { ++ size += 3 + 256 * 3 + 1; + } +-static void biosfn_save_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX; ++ return size; ++} ++ ++static void biosfn_read_video_state_size (CX, BX) ++ Bit16u CX; Bit16u *BX; + { +-#ifdef DEBUG +- unimplemented(); +-#endif ++ Bit16u ss=get_SS(); ++ write_word(ss, BX, biosfn_read_video_state_size2(CX)); + } +-static void biosfn_restore_video_state (CX,ES,BX) Bit16u CX;Bit16u ES;Bit16u BX; ++ ++static Bit16u biosfn_save_video_state (CX,ES,BX) ++ Bit16u CX;Bit16u ES;Bit16u BX; + { +-#ifdef DEBUG +- unimplemented(); +-#endif ++ Bit16u i, v, crtc_addr, ar_index; ++ ++ crtc_addr = read_word(BIOSMEM_SEG, BIOSMEM_CRTC_ADDRESS); ++ if (CX & 1) { ++ write_byte(ES, BX, inb(VGAREG_SEQU_ADDRESS)); BX++; ++ write_byte(ES, BX, inb(crtc_addr)); BX++; ++ write_byte(ES, BX, inb(VGAREG_GRDC_ADDRESS)); BX++; ++ inb(VGAREG_ACTL_RESET); ++ ar_index = inb(VGAREG_ACTL_ADDRESS); ++ write_byte(ES, BX, ar_index); BX++; ++ write_byte(ES, BX, inb(VGAREG_READ_FEATURE_CTL)); BX++; ++ ++ for(i=1;i<=4;i++){ ++ outb(VGAREG_SEQU_ADDRESS, i); ++ write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; ++ } ++ outb(VGAREG_SEQU_ADDRESS, 0); ++ write_byte(ES, BX, inb(VGAREG_SEQU_DATA)); BX++; ++ ++ for(i=0;i<=0x18;i++) { ++ outb(crtc_addr,i); ++ write_byte(ES, BX, inb(crtc_addr+1)); BX++; ++ } ++ ++ for(i=0;i<=0x13;i++) { ++ inb(VGAREG_ACTL_RESET); ++ outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); ++ write_byte(ES, BX, inb(VGAREG_ACTL_READ_DATA)); BX++; ++ } ++ inb(VGAREG_ACTL_RESET); ++ ++ for(i=0;i<=8;i++) { ++ outb(VGAREG_GRDC_ADDRESS,i); ++ write_byte(ES, BX, inb(VGAREG_GRDC_DATA)); BX++; ++ } ++ ++ write_word(ES, BX, crtc_addr); BX+= 2; ++ ++ /* XXX: read plane latches */ ++ write_byte(ES, BX, 0); BX++; ++ write_byte(ES, BX, 0); BX++; ++ write_byte(ES, BX, 0); BX++; ++ write_byte(ES, BX, 0); BX++; ++ } ++ if (CX & 2) { ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE)); BX++; ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_NB_COLS)); BX += 2; ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE)); BX += 2; ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)); BX += 2; ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS)); BX++; ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT)); BX += 2; ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL)); BX++; ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES)); BX++; ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)); BX++; ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE)); BX += 2; ++ for(i=0;i<8;i++) { ++ write_word(ES, BX, read_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i)); ++ BX += 2; ++ } ++ write_word(ES, BX, read_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START)); BX += 2; ++ write_byte(ES, BX, read_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE)); BX++; ++ /* current font */ ++ write_word(ES, BX, read_word(0, 0x1f * 4)); BX += 2; ++ write_word(ES, BX, read_word(0, 0x1f * 4 + 2)); BX += 2; ++ write_word(ES, BX, read_word(0, 0x43 * 4)); BX += 2; ++ write_word(ES, BX, read_word(0, 0x43 * 4 + 2)); BX += 2; ++ } ++ if (CX & 4) { ++ /* XXX: check this */ ++ write_byte(ES, BX, inb(VGAREG_DAC_STATE)); BX++; /* read/write mode dac */ ++ write_byte(ES, BX, inb(VGAREG_DAC_WRITE_ADDRESS)); BX++; /* pix address */ ++ write_byte(ES, BX, inb(VGAREG_PEL_MASK)); BX++; ++ // Set the whole dac always, from 0 ++ outb(VGAREG_DAC_WRITE_ADDRESS,0x00); ++ for(i=0;i<256*3;i++) { ++ write_byte(ES, BX, inb(VGAREG_DAC_DATA)); BX++; ++ } ++ write_byte(ES, BX, 0); BX++; /* color select register */ ++ } ++ return BX; ++} ++ ++static Bit16u biosfn_restore_video_state (CX,ES,BX) ++ Bit16u CX;Bit16u ES;Bit16u BX; ++{ ++ Bit16u i, crtc_addr, v, addr1, ar_index; ++ ++ if (CX & 1) { ++ // Reset Attribute Ctl flip-flop ++ inb(VGAREG_ACTL_RESET); ++ ++ crtc_addr = read_word(ES, BX + 0x40); ++ addr1 = BX; ++ BX += 5; ++ ++ for(i=1;i<=4;i++){ ++ outb(VGAREG_SEQU_ADDRESS, i); ++ outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; ++ } ++ outb(VGAREG_SEQU_ADDRESS, 0); ++ outb(VGAREG_SEQU_DATA, read_byte(ES, BX)); BX++; ++ ++ // Disable CRTC write protection ++ outw(crtc_addr,0x0011); ++ // Set CRTC regs ++ for(i=0;i<=0x18;i++) { ++ if (i != 0x11) { ++ outb(crtc_addr,i); ++ outb(crtc_addr+1, read_byte(ES, BX)); ++ } ++ BX++; ++ } ++ // select crtc base address ++ v = inb(VGAREG_READ_MISC_OUTPUT) & ~0x01; ++ if (crtc_addr = 0x3d4) ++ v |= 0x01; ++ outb(VGAREG_WRITE_MISC_OUTPUT, v); ++ ++ // enable write protection if needed ++ outb(crtc_addr, 0x11); ++ outb(crtc_addr+1, read_byte(ES, BX - 0x18 + 0x11)); ++ ++ // Set Attribute Ctl ++ ar_index = read_byte(ES, addr1 + 0x03); ++ inb(VGAREG_ACTL_RESET); ++ for(i=0;i<=0x13;i++) { ++ outb(VGAREG_ACTL_ADDRESS, i | (ar_index & 0x20)); ++ outb(VGAREG_ACTL_WRITE_DATA, read_byte(ES, BX)); BX++; ++ } ++ outb(VGAREG_ACTL_ADDRESS, ar_index); ++ inb(VGAREG_ACTL_RESET); ++ ++ for(i=0;i<=8;i++) { ++ outb(VGAREG_GRDC_ADDRESS,i); ++ outb(VGAREG_GRDC_DATA, read_byte(ES, BX)); BX++; ++ } ++ BX += 2; /* crtc_addr */ ++ BX += 4; /* plane latches */ ++ ++ outb(VGAREG_SEQU_ADDRESS, read_byte(ES, addr1)); addr1++; ++ outb(crtc_addr, read_byte(ES, addr1)); addr1++; ++ outb(VGAREG_GRDC_ADDRESS, read_byte(ES, addr1)); addr1++; ++ addr1++; ++ outb(crtc_addr - 0x4 + 0xa, read_byte(ES, addr1)); addr1++; ++ } ++ if (CX & 2) { ++ write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE, read_byte(ES, BX)); BX++; ++ write_word(BIOSMEM_SEG,BIOSMEM_NB_COLS, read_word(ES, BX)); BX += 2; ++ write_word(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE, read_word(ES, BX)); BX += 2; ++ write_word(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS, read_word(ES, BX)); BX += 2; ++ write_byte(BIOSMEM_SEG,BIOSMEM_NB_ROWS, read_byte(ES, BX)); BX++; ++ write_word(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT, read_word(ES, BX)); BX += 2; ++ write_byte(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL, read_byte(ES, BX)); BX++; ++ write_byte(BIOSMEM_SEG,BIOSMEM_SWITCHES, read_byte(ES, BX)); BX++; ++ write_byte(BIOSMEM_SEG,BIOSMEM_MODESET_CTL, read_byte(ES, BX)); BX++; ++ write_word(BIOSMEM_SEG,BIOSMEM_CURSOR_TYPE, read_word(ES, BX)); BX += 2; ++ for(i=0;i<8;i++) { ++ write_word(BIOSMEM_SEG, BIOSMEM_CURSOR_POS+2*i, read_word(ES, BX)); ++ BX += 2; ++ } ++ write_word(BIOSMEM_SEG,BIOSMEM_CURRENT_START, read_word(ES, BX)); BX += 2; ++ write_byte(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE, read_byte(ES, BX)); BX++; ++ /* current font */ ++ write_word(0, 0x1f * 4, read_word(ES, BX)); BX += 2; ++ write_word(0, 0x1f * 4 + 2, read_word(ES, BX)); BX += 2; ++ write_word(0, 0x43 * 4, read_word(ES, BX)); BX += 2; ++ write_word(0, 0x43 * 4 + 2, read_word(ES, BX)); BX += 2; ++ } ++ if (CX & 4) { ++ BX++; ++ v = read_byte(ES, BX); BX++; ++ outb(VGAREG_PEL_MASK, read_byte(ES, BX)); BX++; ++ // Set the whole dac always, from 0 ++ outb(VGAREG_DAC_WRITE_ADDRESS,0x00); ++ for(i=0;i<256*3;i++) { ++ outb(VGAREG_DAC_DATA, read_byte(ES, BX)); BX++; ++ } ++ BX++; ++ outb(VGAREG_DAC_WRITE_ADDRESS, v); ++ } ++ return BX; + } + + // ============================================================================================ +diff -u -w vbetables-gen.c +--- vbetables-gen.c 1970-01-01 01:00:00.000000000 +0100 ++++ vbetables-gen.c 2006-06-14 00:52:18.000000000 +0200 +@@ -0,0 +1,217 @@ ++/* Generate the VGABIOS VBE Tables */ ++#include ++#include ++ ++typedef struct { ++ int width; ++ int height; ++ int depth; ++ int mode; ++} ModeInfo; ++ ++ModeInfo modes[] = { ++ /* standard VESA modes */ ++{ 640, 400, 8 , 0x100}, ++{ 640, 480, 8 , 0x101}, ++{ 800, 600, 4 , 0x102}, ++{ 800, 600, 8 , 0x103}, ++ //{ 1024, 768, 4 , 0x104}, ++{ 1024, 768, 8 , 0x105}, ++ //{ 1280, 1024, 4 , 0x106}, ++{ 1280, 1024, 8 , 0x107}, ++{ 320, 200, 15 , 0x10D}, ++{ 320, 200, 16 , 0x10E}, ++{ 320, 200, 24 , 0x10F}, ++{ 640, 480, 15 , 0x110}, ++{ 640, 480, 16 , 0x111}, ++{ 640, 480, 24 , 0x112}, ++{ 800, 600, 15 , 0x113}, ++{ 800, 600, 16 , 0x114}, ++{ 800, 600, 24 , 0x115}, ++{ 1024, 768, 15 , 0x116}, ++{ 1024, 768, 16 , 0x117}, ++{ 1024, 768, 24 , 0x118}, ++{ 1280, 1024, 15 , 0x119}, ++{ 1280, 1024, 16 , 0x11A}, ++{ 1280, 1024, 24 , 0x11B}, ++{ 1600, 1200, 8 , 0x11C}, ++{ 1600, 1200, 15 , 0x11D}, ++{ 1600, 1200, 16 , 0x11E}, ++{ 1600, 1200, 24 , 0x11F}, ++ ++ /* BOCHS/PLE, 86 'own' mode numbers */ ++{ 320, 200, 32 , 0x140}, ++{ 640, 400, 32 , 0x141}, ++{ 640, 480, 32 , 0x142}, ++{ 800, 600, 32 , 0x143}, ++{ 1024, 768, 32 , 0x144}, ++{ 1280, 1024, 32 , 0x145}, ++{ 320, 200, 8 , 0x146}, ++{ 1600, 1200, 32 , 0x147}, ++{ 1152, 864, 8 , 0x148}, ++{ 1152, 864, 15 , 0x149}, ++{ 1152, 864, 16 , 0x14a}, ++{ 1152, 864, 24 , 0x14b}, ++{ 1152, 864, 32 , 0x14c}, ++{ 0, }, ++}; ++ ++int main(int argc, char **argv) ++{ ++ const ModeInfo *pm; ++ int pitch, r_size, r_pos, g_size, g_pos, b_size, b_pos, a_size, a_pos; ++ const char *str; ++ ++ printf("/* THIS FILE IS AUTOMATICALLY GENERATED - DO NOT EDIT */\n"); ++ printf("static ModeInfoListItem mode_info_list[]=\n"); ++ printf("{\n"); ++ for(pm = modes; pm->mode != 0; pm++) { ++ printf("{ 0x%04x, /* %dx%dx%d */\n", ++ pm->mode, pm->width, pm->height, pm->depth); ++ printf("{ /*Bit16u ModeAttributes*/ %s,\n", ++ "VBE_MODE_ATTRIBUTE_SUPPORTED | " ++ "VBE_MODE_ATTRIBUTE_EXTENDED_INFORMATION_AVAILABLE | " ++ "VBE_MODE_ATTRIBUTE_COLOR_MODE | " ++ "VBE_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER_MODE | " ++ "VBE_MODE_ATTRIBUTE_GRAPHICS_MODE"); ++ ++ printf("/*Bit8u WinAAttributes*/ %s,\n", ++ "VBE_WINDOW_ATTRIBUTE_RELOCATABLE | " ++ "VBE_WINDOW_ATTRIBUTE_READABLE | " ++ "VBE_WINDOW_ATTRIBUTE_WRITEABLE"); ++ ++ printf("/*Bit8u WinBAttributes*/ %d,\n", 0); ++ ++ printf("/*Bit16u WinGranularity*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); ++ ++ printf("/*Bit16u WinSize*/ %s,\n", "VBE_DISPI_BANK_SIZE_KB"); ++ ++ printf("/*Bit16u WinASegment*/ %s,\n", "VGAMEM_GRAPH"); ++ ++ printf("/*Bit16u WinBSegment*/ 0x%04x,\n", 0); ++ ++ printf("/*Bit32u WinFuncPtr*/ %d,\n", 0); ++ ++ if (pm->depth == 4) ++ pitch = (pm->width + 7) / 8; ++ else ++ pitch = pm->width * ((pm->depth + 7) / 8); ++ printf("/*Bit16u BytesPerScanLine*/ %d,\n", pitch); ++ ++ // Mandatory information for VBE 1.2 and above ++ printf("/*Bit16u XResolution*/ %d,\n", pm->width); ++ printf("/*Bit16u YResolution*/ %d,\n", pm->height); ++ printf("/*Bit8u XCharSize*/ %d,\n", 8); ++ printf("/*Bit8u YCharSize*/ %d,\n", 16); ++ if (pm->depth == 4) { ++ printf("/*Bit8u NumberOfPlanes*/ %d,\n", 4); ++ printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth); ++ } else { ++ printf("/*Bit8u NumberOfPlanes*/ %d,\n", 1); ++ printf("/*Bit8u BitsPerPixel*/ %d,\n", pm->depth); ++ } ++ printf("/*Bit8u NumberOfBanks*/ %d,\n", ++ (pm->height * pitch + 65535) / 65536); ++ ++ if (pm->depth == 4) ++ str = "VBE_MEMORYMODEL_PLANAR"; ++ else if (pm->depth == 8) ++ str = "VBE_MEMORYMODEL_PACKED_PIXEL"; ++ else ++ str = "VBE_MEMORYMODEL_DIRECT_COLOR"; ++ printf("/*Bit8u MemoryModel*/ %s,\n", str); ++ printf("/*Bit8u BankSize*/ %d,\n", 0); ++ /* XXX: check */ ++ printf("/*Bit8u NumberOfImagePages*/ %d,\n", 0); ++ printf("/*Bit8u Reserved_page*/ %d,\n", 0); ++ ++ // Direct Color fields (required for direct/6 and YUV/7 memory models) ++ switch(pm->depth) { ++ case 15: ++ r_size = 5; ++ r_pos = 10; ++ g_size = 5; ++ g_pos = 5; ++ b_size = 5; ++ b_pos = 0; ++ a_size = 1; ++ a_pos = 15; ++ break; ++ case 16: ++ r_size = 5; ++ r_pos = 11; ++ g_size = 6; ++ g_pos = 5; ++ b_size = 5; ++ b_pos = 0; ++ a_size = 0; ++ a_pos = 0; ++ break; ++ case 24: ++ r_size = 8; ++ r_pos = 16; ++ g_size = 8; ++ g_pos = 8; ++ b_size = 8; ++ b_pos = 0; ++ a_size = 0; ++ a_pos = 0; ++ break; ++ case 32: ++ r_size = 8; ++ r_pos = 16; ++ g_size = 8; ++ g_pos = 8; ++ b_size = 8; ++ b_pos = 0; ++ a_size = 8; ++ a_pos = 24; ++ break; ++ default: ++ r_size = 0; ++ r_pos = 0; ++ g_size = 0; ++ g_pos = 0; ++ b_size = 0; ++ b_pos = 0; ++ a_size = 0; ++ a_pos = 0; ++ break; ++ } ++ ++ printf("/*Bit8u RedMaskSize*/ %d,\n", r_size); ++ printf("/*Bit8u RedFieldPosition*/ %d,\n", r_pos); ++ printf("/*Bit8u GreenMaskSize*/ %d,\n", g_size); ++ printf("/*Bit8u GreenFieldPosition*/ %d,\n", g_pos); ++ printf("/*Bit8u BlueMaskSize*/ %d,\n", b_size); ++ printf("/*Bit8u BlueFieldPosition*/ %d,\n", b_pos); ++ printf("/*Bit8u RsvdMaskSize*/ %d,\n", a_size); ++ printf("/*Bit8u RsvdFieldPosition*/ %d,\n", a_pos); ++ printf("/*Bit8u DirectColorModeInfo*/ %d,\n", 0); ++ ++// Mandatory information for VBE 2.0 and above ++ printf("/*Bit32u PhysBasePtr*/ %s,\n", ++ "VBE_DISPI_LFB_PHYSICAL_ADDRESS"); ++ printf("/*Bit32u OffScreenMemOffset*/ %d,\n", 0); ++ printf("/*Bit16u OffScreenMemSize*/ %d,\n", 0); ++ // Mandatory information for VBE 3.0 and above ++ printf("/*Bit16u LinBytesPerScanLine*/ %d,\n", pitch); ++ printf("/*Bit8u BnkNumberOfPages*/ %d,\n", 0); ++ printf("/*Bit8u LinNumberOfPages*/ %d,\n", 0); ++ printf("/*Bit8u LinRedMaskSize*/ %d,\n", r_size); ++ printf("/*Bit8u LinRedFieldPosition*/ %d,\n", r_pos); ++ printf("/*Bit8u LinGreenMaskSize*/ %d,\n", g_size); ++ printf("/*Bit8u LinGreenFieldPosition*/ %d,\n", g_pos); ++ printf("/*Bit8u LinBlueMaskSize*/ %d,\n", b_size); ++ printf("/*Bit8u LinBlueFieldPosition*/ %d,\n", b_pos); ++ printf("/*Bit8u LinRsvdMaskSize*/ %d,\n", a_size); ++ printf("/*Bit8u LinRsvdFieldPosition*/ %d,\n", a_pos); ++ printf("/*Bit32u MaxPixelClock*/ %d,\n", 0); ++ printf("} },\n"); ++ } ++ printf("{ VBE_VESA_MODE_END_OF_LIST,\n"); ++ printf("{ 0,\n"); ++ printf("} },\n"); ++ printf("};\n"); ++ return 0; ++} diff --git a/pc-bios/video.x b/pc-bios/video.x new file mode 100644 index 0000000..761aa0c Binary files /dev/null and b/pc-bios/video.x differ -- cgit v1.1