[SeaBIOS] [PATCH] POST: Move QEMU specific ramsize and BIOS table setup to paravirt.c.

2013-01-21 Thread Kevin O'Connor
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-01-21 Thread Christian Gmeiner
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

2013-01-21 Thread David Woodhouse

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.

2013-01-21 Thread Kevin O'Connor
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

2013-01-21 Thread Kevin O'Connor
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().

2013-01-21 Thread Kevin O'Connor
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.

2013-01-21 Thread Kevin O'Connor
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

2013-01-21 Thread Alex Williamson
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

2013-01-21 Thread Alex Williamson
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

2013-01-21 Thread Alex Williamson
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

2013-01-21 Thread Alex Williamson
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(