[SeaBIOS] [PATCH] POST: Move QEMU specific ramsize and BIOS table setup to paravirt.c.
Don't clutter post.c with the gory details of QEMU memory sizing and BIOS table creation. Instead, move that code to paravirt.c. Signed-off-by: Kevin O'Connor --- src/paravirt.c | 56 ++ src/paravirt.h | 2 ++ src/post.c | 77 -- 3 files changed, 68 insertions(+), 67 deletions(-) diff --git a/src/paravirt.c b/src/paravirt.c index f180261..9022186 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -13,9 +13,65 @@ #include "ioport.h" // outw #include "paravirt.h" // qemu_cfg_preinit #include "smbios.h" // struct smbios_structure_header +#include "memmap.h" // add_e820 +#include "cmos.h" // CMOS_* +#include "acpi.h" // acpi_setup +#include "mptable.h" // mptable_setup +#include "pci.h" // create_pirtable int qemu_cfg_present; +void +qemu_ramsize_preinit(void) +{ +// On emulators, get memory size from nvram. +u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) + | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); +if (rs) +rs += 16 * 1024 * 1024; +else +rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) + | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) + + 1 * 1024 * 1024); +RamSize = rs; +add_e820(0, rs, E820_RAM); + +// Check for memory over 4Gig +u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) +| ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) +| ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); +RamSizeOver4G = high; +add_e820(0x1ull, high, E820_RAM); + +/* reserve 256KB BIOS area at the end of 4 GB */ +add_e820(0xfffc, 256*1024, E820_RESERVED); + +u32 count = qemu_cfg_e820_entries(); +if (count) { +struct e820_reservation entry; +int i; + +for (i = 0; i < count; i++) { +qemu_cfg_e820_load_next(&entry); +add_e820(entry.address, entry.length, entry.type); +} +} else if (kvm_para_available()) { +// Backwards compatibility - provide hard coded range. +// 4 pages before the bios, 3 pages for vmx tss pages, the +// other page for EPT real mode pagetable +add_e820(0xfffbc000, 4*4096, E820_RESERVED); +} +} + +void +qemu_biostable_setup(void) +{ +pirtable_setup(); +mptable_setup(); +smbios_setup(); +acpi_setup(); +} + static void qemu_cfg_select(u16 f) { diff --git a/src/paravirt.h b/src/paravirt.h index 765a6c1..4f2d5b8 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -43,6 +43,8 @@ static inline int kvm_para_available(void) extern int qemu_cfg_present; +void qemu_ramsize_preinit(void); +void qemu_biostable_setup(void); void qemu_cfg_preinit(void); int qemu_cfg_show_boot_menu(void); void qemu_cfg_get_uuid(u8 *uuid); diff --git a/src/post.c b/src/post.c index dbf4944..33b51b7 100644 --- a/src/post.c +++ b/src/post.c @@ -15,13 +15,9 @@ #include "ahci.h" // ahci_setup #include "memmap.h" // add_e820 #include "pic.h" // pic_setup -#include "pci.h" // create_pirtable -#include "acpi.h" // acpi_bios_init #include "bregs.h" // struct bregs -#include "mptable.h" // mptable_init #include "boot.h" // IPL #include "usb.h" // usb_setup -#include "smbios.h" // smbios_init #include "paravirt.h" // qemu_cfg_port_probe #include "xen.h" // xen_preinit #include "ps2port.h" // ps2port_setup @@ -40,33 +36,12 @@ static void ramsize_preinit(void) { dprintf(3, "Find memory size\n"); -if (CONFIG_COREBOOT) { +if (CONFIG_COREBOOT) coreboot_preinit(); -} else if (usingXen()) { +else if (usingXen()) xen_ramsize_preinit(); -} else { -// On emulators, get memory size from nvram. -u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) - | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); -if (rs) -rs += 16 * 1024 * 1024; -else -rs = (((inb_cmos(CMOS_MEM_EXTMEM_LOW) << 10) - | (inb_cmos(CMOS_MEM_EXTMEM_HIGH) << 18)) - + 1 * 1024 * 1024); -RamSize = rs; -add_e820(0, rs, E820_RAM); - -// Check for memory over 4Gig -u64 high = ((inb_cmos(CMOS_MEM_HIGHMEM_LOW) << 16) -| ((u32)inb_cmos(CMOS_MEM_HIGHMEM_MID) << 24) -| ((u64)inb_cmos(CMOS_MEM_HIGHMEM_HIGH) << 32)); -RamSizeOver4G = high; -add_e820(0x1ull, high, E820_RAM); - -/* reserve 256KB BIOS area at the end of 4 GB */ -add_e820(0xfffc, 256*1024, E820_RESERVED); -} +else +qemu_ramsize_preinit(); // Don't declare any memory between 0xa and 0x10 add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); @@ -74,22 +49,6 @@ ramsize_preinit(void) // Mark known areas as reserved. add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); -u32 count = qemu_cfg_e820_entries(); -if (count) { -struct e820_res
Re: [SeaBIOS] [PATCH RFC] Quite hacky patch to get USB ehci working on bare metal.
2013/1/16 Nils : > Hello Christian, > > Op dinsdag 15-01-2013 om 08:16 uur [tijdzone +0100], schreef Christian > Gmeiner: >> This RFC version works better... with the old one every 3rd boot some >> ehci bulk transfers timed out. Verified >> with my ellisys usb explorer. I will spend 1-3 hours today to get some >> sort of OS booting via USB. >> >> > >> > BTW, the current usb-ehci code does work on "bare metal" on several >> > different boards. What board(s) did this help on? >> >> This patch helps on a lx800 platform with a cs5536. As this patch is >> RFC I am quite happy if some USB >> expert can share his/her thoughts. >> -- >> Christian Gmeiner, MSc > > Nice to see that you are making progress. > I would like to test your patch but unfortunately i don`t have a geode > board at the moment. > I hope to get some back in a few weeks. > I am happy for every tester I can find. I really want to get USB working on the geode. -- Christian Gmeiner, MSc ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
Re: [SeaBIOS] [PATCH 0/3][RFC] POST changes to help with CSM
Looks good, thanks. I've updated the tree at git:// and http://git.infradead.org/users/dwmw2/seabios.git/ to be based on it. My build now only has 480 bytes of '32bit flat init size'; I suspect I need to mark a whole bunch of functions as VISIBLE32INIT as well as just making them non-static. I'm still having to hack platform_hardware_setup() somewhat — although I could probably get away with just calling timer_setup() and pci_probe_devices() instead of using it at all. But we're getting there... -- dwmw2 smime.p7s Description: S/MIME cryptographic signature ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 3/3] POST: Merge platform preinit() calls.
Xen and QEMU had multiple platform preinit() calls that were invoked right after each other. Merge these together. This simplifies the preinit code. Signed-off-by: Kevin O'Connor --- src/coreboot.c | 6 ++ src/paravirt.c | 10 -- src/paravirt.h | 3 +-- src/post.c | 38 ++ src/xen.c | 57 - src/xen.h | 1 - 6 files changed, 53 insertions(+), 62 deletions(-) diff --git a/src/coreboot.c b/src/coreboot.c index 5d013cf..9f695ad 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -125,6 +125,8 @@ const char *CBvendor = "", *CBpart = ""; void coreboot_preinit(void) { +if (!CONFIG_COREBOOT) +return; dprintf(3, "Attempting to find coreboot table\n"); // Find coreboot table. @@ -165,10 +167,6 @@ coreboot_preinit(void) RamSize = maxram; RamSizeOver4G = maxram_over4G; -// Ughh - coreboot likes to set a map at 0x-0x1000, but this -// confuses grub. So, override it. -add_e820(0, 16*1024, E820_RAM); - struct cb_mainboard *cbmb = find_cb_subtable(cbh, CB_TAG_MAINBOARD); if (cbmb) { CBvendor = &cbmb->strings[cbmb->vendor_idx]; diff --git a/src/paravirt.c b/src/paravirt.c index 9022186..5cfda66 100644 --- a/src/paravirt.c +++ b/src/paravirt.c @@ -18,12 +18,16 @@ #include "acpi.h" // acpi_setup #include "mptable.h" // mptable_setup #include "pci.h" // create_pirtable +#include "xen.h" // usingXen int qemu_cfg_present; -void +static void qemu_ramsize_preinit(void) { +if (CONFIG_COREBOOT || usingXen()) +return; + // On emulators, get memory size from nvram. u32 rs = ((inb_cmos(CMOS_MEM_EXTMEM2_LOW) << 16) | (inb_cmos(CMOS_MEM_EXTMEM2_HIGH) << 24)); @@ -98,7 +102,7 @@ qemu_cfg_read_entry(void *buf, int e, int len) qemu_cfg_read(buf, len); } -void qemu_cfg_preinit(void) +void qemu_preinit(void) { char *sig = "QEMU"; int i; @@ -116,6 +120,8 @@ void qemu_cfg_preinit(void) break; } dprintf(4, "qemu_cfg_present=%d\n", qemu_cfg_present); + +qemu_ramsize_preinit(); } void qemu_cfg_get_uuid(u8 *uuid) diff --git a/src/paravirt.h b/src/paravirt.h index 4f2d5b8..04ebde5 100644 --- a/src/paravirt.h +++ b/src/paravirt.h @@ -43,9 +43,8 @@ static inline int kvm_para_available(void) extern int qemu_cfg_present; -void qemu_ramsize_preinit(void); void qemu_biostable_setup(void); -void qemu_cfg_preinit(void); +void qemu_preinit(void); int qemu_cfg_show_boot_menu(void); void qemu_cfg_get_uuid(u8 *uuid); int qemu_cfg_irq0_override(void); diff --git a/src/post.c b/src/post.c index e5435b1..ef67743 100644 --- a/src/post.c +++ b/src/post.c @@ -234,26 +234,6 @@ maininit(void) * Early initialization (preinit) and code relocation / -static void -ramsize_preinit(void) -{ -dprintf(3, "Find memory size\n"); -if (CONFIG_COREBOOT) -coreboot_preinit(); -else if (usingXen()) -xen_ramsize_preinit(); -else -qemu_ramsize_preinit(); - -// Don't declare any memory between 0xa and 0x10 -add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); - -// Mark known areas as reserved. -add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); - -dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); -} - // Update given relocs for the code at 'dest' with a given 'delta' static void updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) @@ -310,12 +290,22 @@ preinit(void) HaveRunPost = 1; outb_cmos(0, CMOS_RESET_CODE); -// Check if we are running under Xen. +// Run platform preinit calls. +coreboot_preinit(); xen_preinit(); +qemu_preinit(); +dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); + +// The first 1 megabyte of the e820 map is "magic". Various +// programs expect to see (and will crash if they don't): +// 0-9fc00=RAM, 9fc00-a=RESERVED, f-10=RESERVED. +// Force the e820 map to show this (the ebda e820 entry is added +// in init_bda). +add_e820(0, BUILD_LOWRAM_END, E820_RAM); +add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); +add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); -// Detect ram and setup internal malloc. -qemu_cfg_preinit(); -ramsize_preinit(); +// Setup malloc. malloc_preinit(); // Relocate initialization code. diff --git a/src/xen.c b/src/xen.c index c9759f0..525039d 100644 --- a/src/xen.c +++ b/src/xen.c @@ -76,8 +76,35 @@ void xen_preinit(void) break; } } -if (!xen_cpuid_base) +if (!xen_cpuid_base) { dprintf(1, "No Xen hypervisor found.\n"); +return; +} + +u64 maxram = 0, maxram_over4G = 0; +struct xen_seabios_info *info = (void *)INF
[SeaBIOS] [PATCH 0/3][RFC] More post init order reorg
Additional changes intended to clarify the early initialization ("preinit") order. -Kevin Kevin O'Connor (3): POST: Reorganize post entry and "preinit" functions. POST: Move cpu caching and dma setup to platform_hardware_setup(). POST: Merge platform preinit() calls. src/coreboot.c | 6 +-- src/paravirt.c | 10 +++- src/paravirt.h | 3 +- src/post.c | 152 +++- src/resume.c| 4 +- src/romlayout.S | 2 +- src/util.h | 2 +- src/xen.c | 57 +++-- src/xen.h | 1 - 9 files changed, 127 insertions(+), 110 deletions(-) -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 2/3] POST: Move cpu caching and dma setup to platform_hardware_setup().
The CPU cache is enabled and DMA is disabled on all real-world POST entry situations, so no need to do this in the low-level "pre-init" phase. Instead, move it to the platform hardware setup stage. Signed-off-by: Kevin O'Connor --- src/post.c | 12 ++-- src/resume.c | 4 ++-- src/util.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/post.c b/src/post.c index 56df90c..e5435b1 100644 --- a/src/post.c +++ b/src/post.c @@ -144,6 +144,12 @@ device_hardware_setup(void) static void platform_hardware_setup(void) { +// Enable CPU caching +setcr0(getcr0() & ~(CR0_CD|CR0_NW)); + +// Make sure legacy DMA isn't running. +dma_setup(); + // Init base pc hardware. pic_setup(); timer_setup(); @@ -304,12 +310,6 @@ preinit(void) HaveRunPost = 1; outb_cmos(0, CMOS_RESET_CODE); -// Enable CPU caching -setcr0(getcr0() & ~(CR0_CD|CR0_NW)); - -// Make sure legacy DMA isn't running. -dma_preinit(); - // Check if we are running under Xen. xen_preinit(); diff --git a/src/resume.c b/src/resume.c index 99265cd..ffc84fc 100644 --- a/src/resume.c +++ b/src/resume.c @@ -19,7 +19,7 @@ int HaveRunPost VAR16VISIBLE; // Reset DMA controller void -dma_preinit(void) +dma_setup(void) { // first reset the DMA controllers outb(0, PORT_DMA1_MASTER_CLEAR); @@ -40,7 +40,7 @@ handle_resume(void) outb_cmos(0, CMOS_RESET_CODE); dprintf(1, "In resume (status=%d)\n", status); -dma_preinit(); +dma_setup(); switch (status) { case 0x01 ... 0x04: diff --git a/src/util.h b/src/util.h index eb35d02..88f5905 100644 --- a/src/util.h +++ b/src/util.h @@ -354,7 +354,7 @@ void disable_bootsplash(void); // resume.c extern int HaveRunPost; -void dma_preinit(void); +void dma_setup(void); // pnpbios.c #define PNP_SIGNATURE 0x506e5024 // $PnP -- 1.7.11.7 ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [PATCH 1/3] POST: Reorganize post entry and "preinit" functions.
Unlocking ram in handle_post() is tricky and only needed under qemu. Separate out that logic from the coreboot/xen paths by invoking handle_elf_post separately. This simplifies both the qemu and non-qemu code paths. Also, organize all the "pre-init" functions into one section of the file. Signed-off-by: Kevin O'Connor --- src/post.c | 152 +--- src/romlayout.S | 2 +- 2 files changed, 90 insertions(+), 64 deletions(-) diff --git a/src/post.c b/src/post.c index 33b51b7..56df90c 100644 --- a/src/post.c +++ b/src/post.c @@ -1,24 +1,23 @@ // 32bit code to Power On Self Test (POST) a machine. // -// Copyright (C) 2008-2010 Kevin O'Connor +// Copyright (C) 2008-2013 Kevin O'Connor // Copyright (C) 2002 MandrakeSoft S.A. // // This file may be distributed under the terms of the GNU LGPLv3 license. -#include "ioport.h" // PORT_* #include "config.h" // CONFIG_* #include "cmos.h" // CMOS_* #include "util.h" // memset #include "biosvar.h" // struct bios_data_area_s -#include "disk.h" // floppy_drive_setup +#include "disk.h" // floppy_setup #include "ata.h" // ata_setup #include "ahci.h" // ahci_setup #include "memmap.h" // add_e820 #include "pic.h" // pic_setup #include "bregs.h" // struct bregs -#include "boot.h" // IPL +#include "boot.h" // boot_init #include "usb.h" // usb_setup -#include "paravirt.h" // qemu_cfg_port_probe +#include "paravirt.h" // qemu_cfg_preinit #include "xen.h" // xen_preinit #include "ps2port.h" // ps2port_setup #include "virtio-blk.h" // virtio_blk_setup @@ -29,30 +28,10 @@ / - * BIOS init + * BIOS initialization and hardware setup / static void -ramsize_preinit(void) -{ -dprintf(3, "Find memory size\n"); -if (CONFIG_COREBOOT) -coreboot_preinit(); -else if (usingXen()) -xen_ramsize_preinit(); -else -qemu_ramsize_preinit(); - -// Don't declare any memory between 0xa and 0x10 -add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); - -// Mark known areas as reserved. -add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); - -dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); -} - -static void ivt_init(void) { dprintf(3, "init ivt\n"); @@ -244,24 +223,30 @@ maininit(void) make_bios_readonly(); } -// Begin the boot process by invoking an int0x19 in 16bit mode. + +/ + * Early initialization (preinit) and code relocation + / + static void -startBoot(void) +ramsize_preinit(void) { -// Clear low-memory allocations (required by PMM spec). -memset((void*)BUILD_STACK_ADDR, 0, BUILD_EBDA_MINIMUM - BUILD_STACK_ADDR); +dprintf(3, "Find memory size\n"); +if (CONFIG_COREBOOT) +coreboot_preinit(); +else if (usingXen()) +xen_ramsize_preinit(); +else +qemu_ramsize_preinit(); -dprintf(3, "Jump to int19\n"); -struct bregs br; -memset(&br, 0, sizeof(br)); -br.flags = F_IF; -call16_int(0x19, &br); -} +// Don't declare any memory between 0xa and 0x10 +add_e820(BUILD_LOWRAM_END, BUILD_BIOS_ADDR-BUILD_LOWRAM_END, E820_HOLE); +// Mark known areas as reserved. +add_e820(BUILD_BIOS_ADDR, BUILD_BIOS_SIZE, E820_RESERVED); -/ - * POST entry and code relocation - / +dprintf(1, "Ram Size=0x%08x (0x%016llx high)\n", RamSize, RamSizeOver4G); +} // Update given relocs for the code at 'dest' with a given 'delta' static void @@ -272,7 +257,7 @@ updateRelocs(void *dest, u32 *rstart, u32 *rend, u32 delta) *((u32*)(dest + *reloc)) += delta; } -// Relocate init code and then call maininit() at new address. +// Relocate init code. static void reloc_preinit(void) { @@ -311,11 +296,22 @@ reloc_preinit(void) barrier(); } -// Setup for code relocation and then call reloc_init +// Setup for code relocation and then relocate. void VISIBLE32INIT -doreloc(void) +preinit(void) { +// Set reboot flags. HaveRunPost = 1; +outb_cmos(0, CMOS_RESET_CODE); + +// Enable CPU caching +setcr0(getcr0() & ~(CR0_CD|CR0_NW)); + +// Make sure legacy DMA isn't running. +dma_preinit(); + +// Check if we are running under Xen. +xen_preinit(); // Detect ram and setup internal malloc. qemu_cfg_preinit(); @@ -326,32 +322,31 @@ doreloc(void) reloc_preinit(); } -// Entry point for Power On Self Test (POST) - the BIOS initilization -// phase. This function makes the memory at 0xc-0xf -// read/writable and then calls dopost(). -void VISIBLE32FLAT -handle_post(void) -{ -d
[SeaBIOS] [RFC PATCH 0/2] Q35/ICH9 interrupt routing
I was trying to revive the patch to add Qemu INTx routing support for Q35 and stumbled on some rather broken interrupt routing problems. Sadly a seabios release claiming Q35 support snuck out already, but I'd like to at least discuss these before Qemu 1.4 even though they may not get fixed for that release either. ICH9 adds 4 more PCI interrupt routing registers, so in addition to the previous PIRQ[A:D], we now also have PIRQ[E:H]. AIUI, each pin can operate in either PIC or APIC mode based on whether the IRQEN bit of each register is clear or set respectively. In PIC mode bits 3:0 of the PIRQn register identifiy the ISA compatible interrupt to trigger. In APIC mode each PIRQn is statically mapped to an APIC pin, where PIRQA->16, PIRQB->17, ..., PIRQH->23. The first problem we encounter is that the system boots into PIC mode but we're programming the PIRQn registers into APIC mode. After fixing that, we quickly notice that seabios has a single function for programming PCI interrupt line registers based on the PIIX mapping of PIRQn registers. A comment in the Qemu source indicates the slot:pin to PIRQn mapping is arbitrary so long as Qemu and ACPI match, disregarding that boot ROMs may also use interrupts and have no ACPI support. Solutions to this are either to create an ICH9 specific mapping function or to adjust slot:pin mappings to match PIIX. I've done the latter here, but it's incomplete as slots 25-31 have directly programmable mappings. I'm looking for comments on how to proceed. Do we want to try to meld ICH9 to be more PIIX compatible or do we want to do our own thing. I suspect there are still a number of holes in ICH9 irq programming no matter which path we take and these in particular are likely to be challenging for migration compatibility. Thanks, Alex --- Alex Williamson (2): q35: Fix PIC-mode interrupt setup q35: Fix ACPI _PRT routing to match PIIX src/pciinit.c |6 +-- src/q35-acpi-dsdt.dsl | 100 + 2 files changed, 52 insertions(+), 54 deletions(-) ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [RFC PATCH 1/2] q35: Fix PIC-mode interrupt setup
We're initializing the ICH9 PIRQn registers with the IRQEN bit set, which actuall makes them operate in APIC mode rather than PIC mode (see 13.1.17 & 13.1.9). AFAICT, the system boots up in PIC mode and trying to make use of APIC IRQs in boot ROMs does not work. Fix this to use the ISA compatible IRQs. Signed-off-by: Alex Williamson --- src/pciinit.c |6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/pciinit.c b/src/pciinit.c index a406bbd..857e8af 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -143,11 +143,9 @@ void mch_isa_bridge_init(struct pci_device *dev, void *arg) /* activate irq remapping in LPC */ /* PIRQ[A-D] routing */ -pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i, - irq | ICH9_LPC_PIRQ_ROUT_IRQEN); +pci_config_writeb(bdf, ICH9_LPC_PIRQA_ROUT + i, irq); /* PIRQ[E-H] routing */ -pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i, - irq | ICH9_LPC_PIRQ_ROUT_IRQEN); +pci_config_writeb(bdf, ICH9_LPC_PIRQE_ROUT + i, irq); } outb(elcr[0], ICH9_LPC_PORT_ELCR1); outb(elcr[1], ICH9_LPC_PORT_ELCR2); ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [RFC PATCH] ich9: Fix interrupt routing
It's really not that arbitrary how we translate slot:pin to pirq register. We not only need to match the ACPI table we provide to the guest, but the BIOS has dependencies for programming PCI interrupt line registers for boot ROMs that use interrupts. If we don't match the slot:pin to pirq of PIIX then we need to come up with our own mapping function. NB. We might need our own map function anyway because slots 25-31 do their own thing so BIOS interrupt line mapping will still fail (no interrupt mode boot ROMs below express ports). Signed-off-by: Alex Williamson --- hw/lpc_ich9.c |9 - pc-bios/q35-acpi-dsdt.aml | Bin 2 files changed, 4 insertions(+), 5 deletions(-) Binary not included. This includes the required Qemu changes to match the slot:pin updates in seabios. diff --git a/hw/lpc_ich9.c b/hw/lpc_ich9.c index 16843d7..7b9e348 100644 --- a/hw/lpc_ich9.c +++ b/hw/lpc_ich9.c @@ -109,17 +109,16 @@ static void ich9_cc_init(ICH9LPCState *lpc) int intx; /* the default irq routing is arbitrary as long as it matches with - * acpi irq routing table. - * The one that is incompatible with piix_pci(= bochs) one is - * intentionally chosen to let the users know that the different - * board is used. + * acpi irq routing table and BIOS. * * int[A-D] -> pirq[E-F] * avoid pirq A-D because they are used for pci express port + * Keep the same slot rotation as piix or the bios won't know + * how to program PCI interrupt line registers for boot ROMs. */ for (slot = 0; slot < PCI_SLOT_MAX; slot++) { for (intx = 0; intx < PCI_NUM_PINS; intx++) { -lpc->irr[slot][intx] = (slot + intx) % 4 + 4; +lpc->irr[slot][intx] = ((slot + intx - 1) & 3) + 4; } } ich9_cc_update(lpc); ___ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios
[SeaBIOS] [RFC PATCH 2/2] q35: Fix ACPI _PRT routing to match PIIX
When seabios programs PCI interrupt line registers it expects a specific slot:pin to PIRQ mapping (see pci_slot_get_irq). If we want to re-use this function between both PIIX and ICH9, then the _PRT exposed to the guest needs to change. NB. slots 25-31 on ICH9 don't follow this routing pattern and can be changed independently, so even with this boot ROMs behind express ports may not work correctly with interrupts. We can possibly make them follow this pattern or come up with a new mch_pci_slot_get_irq() function, in which case we don't need to match PIIX. PIIX slot:pin array - D/A/B/C, A/B/C/D, B/C/D/A, C/D/A/B Current ICH9 -E/F/G/H, F/G/H/E, G/H/E/F, H/E/F/G Revised ICH9 -H/E/F/G, E/F/G/H, F/G/H/E, G/H/E/F Signed-off-by: Alex Williamson --- src/q35-acpi-dsdt.dsl | 100 + 1 file changed, 50 insertions(+), 50 deletions(-) diff --git a/src/q35-acpi-dsdt.dsl b/src/q35-acpi-dsdt.dsl index c031d83..ebb9349 100644 --- a/src/q35-acpi-dsdt.dsl +++ b/src/q35-acpi-dsdt.dsl @@ -201,31 +201,31 @@ DefinitionBlock ( #define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG) Name(PRTP, package() { -prt_slot_lnkE(0x), -prt_slot_lnkF(0x0001), -prt_slot_lnkG(0x0002), -prt_slot_lnkH(0x0003), -prt_slot_lnkE(0x0004), -prt_slot_lnkF(0x0005), -prt_slot_lnkG(0x0006), -prt_slot_lnkH(0x0007), -prt_slot_lnkE(0x0008), -prt_slot_lnkF(0x0009), -prt_slot_lnkG(0x000a), -prt_slot_lnkH(0x000b), -prt_slot_lnkE(0x000c), -prt_slot_lnkF(0x000d), -prt_slot_lnkG(0x000e), -prt_slot_lnkH(0x000f), -prt_slot_lnkE(0x0010), -prt_slot_lnkF(0x0011), -prt_slot_lnkG(0x0012), -prt_slot_lnkH(0x0013), -prt_slot_lnkE(0x0014), -prt_slot_lnkF(0x0015), -prt_slot_lnkG(0x0016), -prt_slot_lnkH(0x0017), -prt_slot_lnkE(0x0018), +prt_slot_lnkH(0x), +prt_slot_lnkE(0x0001), +prt_slot_lnkF(0x0002), +prt_slot_lnkG(0x0003), +prt_slot_lnkH(0x0004), +prt_slot_lnkE(0x0005), +prt_slot_lnkF(0x0006), +prt_slot_lnkG(0x0007), +prt_slot_lnkH(0x0008), +prt_slot_lnkE(0x0009), +prt_slot_lnkF(0x000a), +prt_slot_lnkG(0x000b), +prt_slot_lnkH(0x000c), +prt_slot_lnkE(0x000d), +prt_slot_lnkF(0x000e), +prt_slot_lnkG(0x000f), +prt_slot_lnkH(0x0010), +prt_slot_lnkE(0x0011), +prt_slot_lnkF(0x0012), +prt_slot_lnkG(0x0013), +prt_slot_lnkH(0x0014), +prt_slot_lnkE(0x0015), +prt_slot_lnkF(0x0016), +prt_slot_lnkG(0x0017), +prt_slot_lnkH(0x0018), /* INTA -> PIRQA for slot 25 - 31 see the default value of DIR */ @@ -258,31 +258,31 @@ DefinitionBlock ( #define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG) Name(PRTA, package() { -prt_slot_gsiE(0x), -prt_slot_gsiF(0x0001), -prt_slot_gsiG(0x0002), -prt_slot_gsiH(0x0003), -prt_slot_gsiE(0x0004), -prt_slot_gsiF(0x0005), -prt_slot_gsiG(0x0006), -prt_slot_gsiH(0x0007), -prt_slot_gsiE(0x0008), -prt_slot_gsiF(0x0009), -prt_slot_gsiG(0x000a), -prt_slot_gsiH(0x000b), -prt_slot_gsiE(0x000c), -prt_slot_gsiF(0x000d), -prt_slot_gsiG(0x000e), -prt_slot_gsiH(0x000f), -prt_slot_gsiE(0x0010), -prt_slot_gsiF(0x0011), -prt_slot_gsiG(0x0012), -prt_slot_gsiH(0x0013), -prt_slot_gsiE(0x0014), -prt_slot_gsiF(0x0015), -prt_slot_gsiG(0x0016), -prt_slot_gsiH(0x0017), -prt_slot_gsiE(0x0018), +prt_slot_gsiH(0x), +prt_slot_gsiE(0x0001), +prt_slot_gsiF(0x0002), +prt_slot_gsiG(0x0003), +prt_slot_gsiH(0x0004), +prt_slot_gsiE(0x0005), +prt_slot_gsiF(0x0006), +prt_slot_gsiG(0x0007), +prt_slot_gsiH(0x0008), +prt_slot_gsiE(0x0009), +prt_slot_gsiF(0x000a), +prt_slot_gsiG(0x000b), +prt_slot_gsiH(0x000c), +prt_slot_gsiE(