From patchwork Tue Oct 27 11:34:35 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Various x86emu fixes Date: Tue, 27 Oct 2009 11:34:35 -0000 From: Mark Marshall X-Patchwork-Id: 495 Message-Id: To: coreboot@coreboot.org Below are three small patches, they all seemed useful while I have been working with VGA option ROMs. Thanks for the great work. MM Use more care when implimenting the PCI BIOS functions. The 'CHECK' function seemed to be both wrong code and the wrong number, so I have just added the corrct code in parallel. The READ_CONF and WRITE_CONF functions would both do the wrong thing if the passed in BDF was not found. We should return and error to the caller, but not stop running the option ROM. Signed-off-by: Mark Marshall When loading an option ROM use the class stored in the device to decide whether the option ROM is a special VGA type. An S3 card that I've got has the wrong class in the VGA BIOS. (A Stealth 64 DRAM T PCI, from 1994 - BIOS V2.02) Signed-off-by: Mark Marshall Index: src/devices/pci_rom.c =================================================================== --- src/devices/pci_rom.c (revision 4822) +++ src/devices/pci_rom.c (working copy) @@ -116,7 +116,10 @@ rom_size = rom_header->size * 512; - if (PCI_CLASS_DISPLAY_VGA == rom_data->class_hi) { + // We check to see if the device thinks it is a VGA device not + // whether the ROM image is for a VGA device because some + // devices have a mismatch between the hardware and the ROM + if (PCI_CLASS_DISPLAY_VGA == (dev->class >> 8)) { #if CONFIG_CONSOLE_VGA == 1 && CONFIG_CONSOLE_VGA_MULTI == 0 extern device_t vga_pri; // the primary vga device, defined in device.c if (dev != vga_pri) return NULL; // only one VGA supported Get the passed in Bus/Device/Function from the correct location on the stack. Signed-off-by: Mark Marshall Index: util/x86emu/x86_asm.S =================================================================== --- util/x86emu/x86_asm.S (revision 4855) +++ util/x86emu/x86_asm.S (working copy) @@ -68,8 +68,8 @@ /* Get devfn into %ecx */ movl %esp, %ebp - // FIXME: Should this function be called with regparm=0? - movl 8(%ebp), %ecx + /* This function is now called with regparm=0. */ + movl 36(%ebp), %ecx /* Activate the right segment descriptor real mode. */ ljmp $0x28, $RELOCATED(1f) Index: util/x86emu/x86_interrupts.c =================================================================== --- util/x86emu/x86_interrupts.c (revision 4855) +++ util/x86emu/x86_interrupts.c (working copy) @@ -35,13 +35,14 @@ enum { CHECK = 0xb001, - FINDDEV = 0xb102, - READCONFBYTE = 0xb108, - READCONFWORD = 0xb109, - READCONFDWORD = 0xb10a, - WRITECONFBYTE = 0xb10b, - WRITECONFWORD = 0xb10c, - WRITECONFDWORD = 0xb10d + PCIBIOS_CHECK = 0xb101, + PCIBIOS_FINDDEV = 0xb102, + PCIBIOS_READCONFBYTE = 0xb108, + PCIBIOS_READCONFWORD = 0xb109, + PCIBIOS_READCONFDWORD = 0xb10a, + PCIBIOS_WRITECONFBYTE = 0xb10b, + PCIBIOS_WRITECONFWORD = 0xb10c, + PCIBIOS_WRITECONFDWORD = 0xb10d }; // errors go in AH. Just set these up so that word assigns @@ -73,7 +74,12 @@ regs->ecx = 0x2049; retval = 0; break; - case FINDDEV: + case PCIBIOS_CHECK: + regs->edx = 0x20494350; /* ' ICP' */ + regs->edi = 0x00000000; /* protected mode entry */ + retval = 0; + break; + case PCIBIOS_FINDDEV: { devid = regs->ecx; vendorid = regs->edx; @@ -104,12 +110,12 @@ } } break; - case READCONFDWORD: - case READCONFWORD: - case READCONFBYTE: - case WRITECONFDWORD: - case WRITECONFWORD: - case WRITECONFBYTE: + case PCIBIOS_READCONFDWORD: + case PCIBIOS_READCONFWORD: + case PCIBIOS_READCONFBYTE: + case PCIBIOS_WRITECONFDWORD: + case PCIBIOS_WRITECONFWORD: + case PCIBIOS_WRITECONFBYTE: { unsigned long dword; unsigned short word; @@ -126,39 +132,39 @@ regs->eax = PCIBIOS_BADREG; retval = -1; } - switch(func) { - case READCONFBYTE: - byte = pci_read_config8(dev, reg); - regs->ecx = byte; - break; - case READCONFWORD: - word = pci_read_config16(dev, reg); - regs->ecx = word; - break; - case READCONFDWORD: - dword = pci_read_config32(dev, reg); - regs->ecx = dword; - break; - case WRITECONFBYTE: - byte = regs->ecx; - pci_write_config8(dev, reg, byte); - break; - case WRITECONFWORD: - word = regs->ecx; - pci_write_config16(dev, reg, word); - break; - case WRITECONFDWORD: - dword = regs->ecx; - pci_write_config32(dev, reg, dword); - break; + else { + switch(func) { + case PCIBIOS_READCONFBYTE: + byte = pci_read_config8(dev, reg); + regs->ecx = byte; + break; + case PCIBIOS_READCONFWORD: + word = pci_read_config16(dev, reg); + regs->ecx = word; + break; + case PCIBIOS_READCONFDWORD: + dword = pci_read_config32(dev, reg); + regs->ecx = dword; + break; + case PCIBIOS_WRITECONFBYTE: + byte = regs->ecx; + pci_write_config8(dev, reg, byte); + break; + case PCIBIOS_WRITECONFWORD: + word = regs->ecx; + pci_write_config16(dev, reg, word); + break; + case PCIBIOS_WRITECONFDWORD: + dword = regs->ecx; + pci_write_config32(dev, reg, dword); + break; + } + + printk(BIOS_DEBUG, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", + func, bus, devfn, reg, regs->ecx); + regs->eax = 0; + retval = 0; } - - if (retval) - retval = PCIBIOS_BADREG; - printk(BIOS_DEBUG, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n", - func, bus, devfn, reg, regs->ecx); - regs->eax = 0; - retval = 0; } break; default: