Generate PIR table at post time.

Move the predefined PIR table (only useful on emulators) to its own
    file - pirtable.c.
Have the pcibios code inspect the pre-built PIR table on 1ab10e
    calls.
diff --git a/Makefile b/Makefile
index 1392108..b89170d 100644
--- a/Makefile
+++ b/Makefile
@@ -11,7 +11,7 @@
 SRCBOTH=output.c util.c floppy.c ata.c kbd.c pci.c boot.c serial.c clock.c
 SRC16=$(SRCBOTH) disk.c system.c mouse.c cdrom.c apm.c pcibios.c
 SRC32=$(SRCBOTH) post.c shadow.c rombios32.c post_menu.c memmap.c coreboot.c \
-      acpi.c
+      acpi.c pirtable.c
 TABLESRC=font.c cbt.c floppy_dbt.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
diff --git a/src/biosvar.h b/src/biosvar.h
index 177656e..348161d 100644
--- a/src/biosvar.h
+++ b/src/biosvar.h
@@ -262,6 +262,7 @@
     u32 ram_size;
     u16 e820_count;
     u32 e820_loc;
+    u32 pir_loc;
 
     // ATA Driver data
     struct ata_s   ata;
diff --git a/src/pci.h b/src/pci.h
index 7dc038e..e37326d 100644
--- a/src/pci.h
+++ b/src/pci.h
@@ -25,6 +25,9 @@
 int pci_find_device(u16 vendid, u16 devid, int index, PCIDevice *dev);
 int pci_find_class(u32 classid, int index, PCIDevice *dev);
 
+// pirtable.c
+void create_pirtable();
+
 
 /****************************************************************
  * PCI definitions
@@ -46,21 +49,6 @@
  * PIR table
  ****************************************************************/
 
-struct pir_header {
-    u32 signature;
-    u16 version;
-    u16 size;
-    u8 router_bus;
-    u8 router_devfunc;
-    u16 exclusive_irqs;
-    u32 compatible_devid;
-    u32 miniport_data;
-    u8 reserved[11];
-    u8 checksum;
-} PACKED;
-
-#define PIR_SIGNATURE 0x52495024 // $PIR
-
 struct link_info {
     u8 link;
     u16 bitmap;
@@ -74,5 +62,21 @@
     u8 reserved;
 } PACKED;
 
+struct pir_header {
+    u32 signature;
+    u16 version;
+    u16 size;
+    u8 router_bus;
+    u8 router_devfunc;
+    u16 exclusive_irqs;
+    u32 compatible_devid;
+    u32 miniport_data;
+    u8 reserved[11];
+    u8 checksum;
+    struct pir_slot slots[0];
+} PACKED;
+
+#define PIR_SIGNATURE 0x52495024 // $PIR
+
 
 #endif
diff --git a/src/pcibios.c b/src/pcibios.c
index 6a83b83..1ab72f4 100644
--- a/src/pcibios.c
+++ b/src/pcibios.c
@@ -1,4 +1,4 @@
-// Low level ATA disk access
+// PCI BIOS (int 1a/b1) calls
 //
 // Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
 // Copyright (C) 2002  MandrakeSoft S.A.
@@ -9,95 +9,6 @@
 #include "util.h" // handle_1ab1
 #include "pci.h" // pci_config_readl
 
-
-/****************************************************************
- * PIR table
- ****************************************************************/
-
-struct pir_table {
-    struct pir_header pir;
-    struct pir_slot slots[6];
-} PACKED PIR_TABLE VISIBLE16 __attribute__((aligned(16))) = {
-#if CONFIG_PIRTABLE
-    .pir = {
-        .signature = PIR_SIGNATURE,
-        .version = 0x0100,
-        .size = sizeof(struct pir_table),
-        .router_devfunc = 0x08,
-        .compatible_devid = 0x122e8086,
-        .checksum = 0x37, // XXX - should auto calculate
-    },
-    .slots = {
-        {
-            // first slot entry PCI-to-ISA (embedded)
-            .dev = 1<<3,
-            .links = {
-                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 0, // embedded
-        }, {
-            // second slot entry: 1st PCI slot
-            .dev = 2<<3,
-            .links = {
-                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 1,
-        }, {
-            // third slot entry: 2nd PCI slot
-            .dev = 3<<3,
-            .links = {
-                {.link = 0x62, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 2,
-        }, {
-            // 4th slot entry: 3rd PCI slot
-            .dev = 4<<3,
-            .links = {
-                {.link = 0x63, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 3,
-        }, {
-            // 5th slot entry: 4rd PCI slot
-            .dev = 5<<3,
-            .links = {
-                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 4,
-        }, {
-            // 6th slot entry: 5rd PCI slot
-            .dev = 6<<3,
-            .links = {
-                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
-                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
-                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
-                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
-            },
-            .slot_nr = 5,
-        },
-    }
-#endif // CONFIG_PIRTABLE
-};
-
-
-/****************************************************************
- * Helper functions
- ****************************************************************/
-
 #define RET_FUNC_NOT_SUPPORTED 0x81
 #define RET_BAD_VENDOR_ID      0x83
 #define RET_DEVICE_NOT_FOUND   0x86
@@ -198,14 +109,16 @@
 static void
 handle_1ab10e(struct bregs *regs)
 {
-    if (! CONFIG_PIRTABLE) {
+    struct pir_header *pirtable_far = (struct pir_header*)GET_EBDA(pir_loc);
+    if (! pirtable_far) {
         set_code_fail(regs, RET_FUNC_NOT_SUPPORTED);
         return;
     }
 
     // Validate and update size.
     u16 size = GET_FARVAR(regs->es, *(u16*)(regs->di+0));
-    u32 pirsize = sizeof(PIR_TABLE.slots);
+    u16 pirsize = (GET_FARPTR(pirtable_far->size)
+                   - sizeof(struct pir_header));
     SET_FARVAR(regs->es, *(u16*)(regs->di+0), pirsize);
     if (size < pirsize) {
         set_code_fail(regs, RET_BUFFER_TOO_SMALL);
@@ -213,19 +126,14 @@
     }
 
     // Get dest buffer.
-    u8 *d = (u8*)(GET_FARVAR(regs->es, *(u16*)(regs->di+2)) + 0);
+    u16 d = (GET_FARVAR(regs->es, *(u16*)(regs->di+2)) + 0);
     u16 destseg = GET_FARVAR(regs->es, *(u16*)(regs->di+4));
 
     // Memcpy pir table slots to dest buffer.
-    u8 *p = (u8*)PIR_TABLE.slots;
-    u8 *end = p + pirsize;
-    for (; p<end; p++, d++) {
-        u8 c = GET_VAR(CS, *p);
-        SET_FARVAR(destseg, *d, c);
-    }
+    memcpy(MAKE_FARPTR(destseg, d), pirtable_far, pirsize);
 
     // XXX - bochs bios sets bx to (1 << 9) | (1 << 11)
-    regs->bx = GET_VAR(CS, PIR_TABLE.pir.exclusive_irqs);
+    regs->bx = GET_FARPTR(pirtable_far->exclusive_irqs);
     set_code_success(regs);
 }
 
diff --git a/src/pirtable.c b/src/pirtable.c
new file mode 100644
index 0000000..c20a169
--- /dev/null
+++ b/src/pirtable.c
@@ -0,0 +1,98 @@
+// PIR table generation (for emulators)
+//
+// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
+// Copyright (C) 2002  MandrakeSoft S.A.
+//
+// This file may be distributed under the terms of the GNU GPLv3 license.
+
+#include "pci.h" // struct pir_header
+#include "util.h" // checksum
+
+struct pir_table {
+    struct pir_header pir;
+    struct pir_slot slots[6];
+} PACKED PIR_TABLE VISIBLE16 __attribute__((aligned(16))) = {
+#if CONFIG_PIRTABLE
+    .pir = {
+        .signature = PIR_SIGNATURE,
+        .version = 0x0100,
+        .size = sizeof(struct pir_table),
+        .router_devfunc = 0x08,
+        .compatible_devid = 0x122e8086,
+        .checksum = 0x37, // XXX - should auto calculate
+    },
+    .slots = {
+        {
+            // first slot entry PCI-to-ISA (embedded)
+            .dev = 1<<3,
+            .links = {
+                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 0, // embedded
+        }, {
+            // second slot entry: 1st PCI slot
+            .dev = 2<<3,
+            .links = {
+                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 1,
+        }, {
+            // third slot entry: 2nd PCI slot
+            .dev = 3<<3,
+            .links = {
+                {.link = 0x62, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 2,
+        }, {
+            // 4th slot entry: 3rd PCI slot
+            .dev = 4<<3,
+            .links = {
+                {.link = 0x63, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 3,
+        }, {
+            // 5th slot entry: 4rd PCI slot
+            .dev = 5<<3,
+            .links = {
+                {.link = 0x60, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x61, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 4,
+        }, {
+            // 6th slot entry: 5rd PCI slot
+            .dev = 6<<3,
+            .links = {
+                {.link = 0x61, .bitmap = 0xdef8}, // INTA#
+                {.link = 0x62, .bitmap = 0xdef8}, // INTB#
+                {.link = 0x63, .bitmap = 0xdef8}, // INTC#
+                {.link = 0x60, .bitmap = 0xdef8}, // INTD#
+            },
+            .slot_nr = 5,
+        },
+    }
+#endif // CONFIG_PIRTABLE
+};
+
+void
+create_pirtable()
+{
+    if (! CONFIG_PIRTABLE)
+        return;
+
+    PIR_TABLE.pir.checksum = -checksum((u8*)&PIR_TABLE, sizeof(PIR_TABLE));
+    SET_EBDA(pir_loc, (u32)&PIR_TABLE);
+}
diff --git a/src/rombios32.c b/src/rombios32.c
index a56539d..cf39a6b 100644
--- a/src/rombios32.c
+++ b/src/rombios32.c
@@ -1173,6 +1173,8 @@
 
     pci_bios_init();
 
+    create_pirtable();
+
     if (bios_table_cur_addr != 0) {
 
         mptable_init();