[coreboot] Patch set updated for coreboot: 6d79142 MPTAPLE: generate from devicetree.cb

Sven Schnelle (svens@stackframe.org) gerrit at coreboot.org
Thu Jul 12 11:03:41 CEST 2012


Sven Schnelle (svens at stackframe.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/1138

-gerrit

commit 6d7914267d7a4e1bc4b66b3567f4cc3ad304bb59
Author: Sven Schnelle <svens at stackframe.org>
Date:   Thu Jun 21 22:19:48 2012 +0200

    MPTAPLE: generate from devicetree.cb
    
    This patch adds support for autogenerating the MPTABLE from
    devicetree.cb. This is done by a write_smp_table() declared
    weak in mpspec.c. If the mainboard doesn't provide it's own
    function, this generic implementation is called.
    
    Syntax in devicetree.cb:
    
    ioapic_irq <APICID> <INTA|INTB|INTC|INTD> <INTPIN>
    
    The ioapic_irq directive can be used in pci and pci_domain
    devices. If there's no directive, the autogen code traverses
    the tree back to the pci_domain and stops at the first device
    which such a directive, and use that information to generate the
    entry according to PCI IRQ routing rules.
    
    Change-Id: I4df5b198e8430f939d477c14c798414e398a2027
    Signed-off-by: Sven Schnelle <svens at stackframe.org>
---
 src/arch/x86/boot/mpspec.c         |  101 +++++++
 src/devices/device_util.c          |    4 +
 src/include/device/device.h        |    9 +-
 src/include/device/path.h          |    7 +
 util/sconfig/lex.yy.c_shipped      |  207 +++++++------
 util/sconfig/main.c                |   72 ++++-
 util/sconfig/sconfig.h             |    5 +
 util/sconfig/sconfig.l             |    3 +
 util/sconfig/sconfig.tab.c_shipped |  576 ++++++++++++++++++++----------------
 util/sconfig/sconfig.tab.h_shipped |   13 +-
 util/sconfig/sconfig.y             |    7 +-
 11 files changed, 628 insertions(+), 376 deletions(-)

diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c
index e7d767b..44236f1 100644
--- a/src/arch/x86/boot/mpspec.c
+++ b/src/arch/x86/boot/mpspec.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <arch/cpu.h>
 #include <cpu/x86/lapic.h>
+#include <drivers/generic/ioapic/chip.h>
 
 /* Initialize the specified "mc" struct with initial values. */
 void mptable_init(struct mp_config_table *mc, u32 lapic_addr)
@@ -410,3 +411,103 @@ void *mptable_finalize(struct mp_config_table *mc)
 	printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
 	return smp_next_mpe_entry(mc);
 }
+
+unsigned long __attribute__((weak)) write_smp_table(unsigned long addr)
+{
+	struct drivers_generic_ioapic_config *ioapic_config;
+        struct mp_config_table *mc;
+	int isa_bus, pin, parentpin;
+	device_t dev, parent, oldparent;
+	void *tmp, *v;
+	int isaioapic = -1;
+
+	v = smp_write_floating_table(addr, 0);
+        mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
+
+	mptable_init(mc, LOCAL_APIC_ADDR);
+
+        smp_write_processors(mc);
+
+	mptable_write_buses(mc, NULL, &isa_bus);
+
+	for(dev = all_devices; dev; dev = dev->next) {
+		if (dev->path.type != DEVICE_PATH_IOAPIC)
+			continue;
+
+		if (!(ioapic_config = dev->chip_info)) {
+			printk(BIOS_ERR, "%s has no config, ignoring\n", dev_path(dev));
+			continue;
+		}
+		smp_write_ioapic(mc, dev->path.ioapic.ioapic_id,
+				     ioapic_config->version,
+				     ioapic_config->base);
+
+		if (ioapic_config->have_isa_interrupts) {
+			if (isaioapic > 1)
+				printk(BIOS_ERR, "More than one IOAPIC with ISA interrupts?\n");
+			else
+				isaioapic = dev->path.ioapic.ioapic_id;;
+		}
+	}
+
+	if (isaioapic >= 0) {
+		/* Legacy Interrupts */
+		printk(BIOS_DEBUG, "writing ISA IRQs\n");
+		mptable_add_isa_interrupts(mc, isa_bus, isaioapic, 0);
+	}
+
+	for(dev = all_devices; dev; dev = dev->next) {
+
+		if (dev->path.type != DEVICE_PATH_PCI)
+			continue;
+
+		pin = (dev->path.pci.devfn & 7) % 4;
+
+		if (dev->pci_irq_info[pin].ioapic_dst_id) {
+			printk(BIOS_DEBUG, "fixed IRQ entry for: %s: INT%c# -> IOAPIC %d PIN %d\n", dev_path(dev),
+			       pin + 'A',
+			       dev->pci_irq_info[pin].ioapic_dst_id,
+			       dev->pci_irq_info[pin].ioapic_irq_pin);
+			smp_write_intsrc(mc, mp_INT,
+					 dev->pci_irq_info[pin].ioapic_flags,
+					 dev->bus->secondary,
+					 ((dev->path.pci.devfn & 0xf8) >> 1) | pin,
+					 dev->pci_irq_info[pin].ioapic_dst_id,
+					 dev->pci_irq_info[pin].ioapic_irq_pin);
+		} else {
+				oldparent = parent = dev;
+				while((parent = parent->bus->dev)) {
+					parentpin = (oldparent->path.pci.devfn >> 3) + (oldparent->path.pci.devfn & 7);
+					parentpin += dev->path.pci.devfn & 7;
+					parentpin += dev->path.pci.devfn >> 3;
+					parentpin %= 4;
+
+					if (parent->pci_irq_info[parentpin].ioapic_dst_id) {
+						printk(BIOS_DEBUG, "automatic IRQ entry for %s: INT%c# -> IOAPIC %d PIN %d\n",
+						       dev_path(dev), pin + 'A',
+						       parent->pci_irq_info[parentpin].ioapic_dst_id,
+						       parent->pci_irq_info[parentpin].ioapic_irq_pin);
+						smp_write_intsrc(mc, mp_INT,
+								 parent->pci_irq_info[parentpin].ioapic_flags,
+								 dev->bus->secondary,
+								 ((dev->path.pci.devfn & 0xf8) >> 1) | pin,
+								 parent->pci_irq_info[parentpin].ioapic_dst_id,
+								 parent->pci_irq_info[parentpin].ioapic_irq_pin);
+
+						break;
+					}
+
+					if (parent->path.type == DEVICE_PATH_PCI_DOMAIN) {
+						printk(BIOS_WARNING, "no IRQ found for %s\n", dev_path(dev));
+						break;
+					}
+					oldparent = parent;
+				}
+		}
+	}
+
+	mptable_lintsrc(mc, isa_bus);
+	tmp = mptable_finalize(mc);
+	printk(BIOS_INFO, "MPTABLE len: %d\n", (unsigned int)tmp - (unsigned int)v);
+	return (unsigned long)tmp;
+}
diff --git a/src/devices/device_util.c b/src/devices/device_util.c
index ecc2c13..7c1cde9 100644
--- a/src/devices/device_util.c
+++ b/src/devices/device_util.c
@@ -201,6 +201,10 @@ const char *dev_path(device_t dev)
 			sprintf(buffer, "APIC: %02x",
 				dev->path.apic.apic_id);
 			break;
+		case DEVICE_PATH_IOAPIC:
+			sprintf(buffer, "IOAPIC: %02x",
+				dev->path.ioapic.ioapic_id);
+			break;
 		case DEVICE_PATH_PCI_DOMAIN:
 			sprintf(buffer, "PCI_DOMAIN: %04x",
 				dev->path.pci_domain.domain);
diff --git a/src/include/device/device.h b/src/include/device/device.h
index 0aea1d6..f36710a 100644
--- a/src/include/device/device.h
+++ b/src/include/device/device.h
@@ -61,6 +61,13 @@ struct bus {
  * combination:
  */
 
+struct pci_irq_info {
+	unsigned int	ioapic_irq_pin;
+	unsigned int	ioapic_src_pin;
+	unsigned int	ioapic_dst_id;
+	unsigned int    ioapic_flags;
+};
+
 struct device {
 	struct bus *	bus;		/* bus this device is on, for bridge
 					 * devices, it is the up stream bus */
@@ -77,7 +84,7 @@ struct device {
 	unsigned int    enabled : 1;	/* set if we should enable the device */
 	unsigned int    initialized : 1; /* set if we have initialized the device */
 	unsigned int    on_mainboard : 1;
-
+	struct pci_irq_info pci_irq_info[4];
 	u8 command;
 
 	/* Base registers for this device. I/O, MEM and Expansion ROM */
diff --git a/src/include/device/path.h b/src/include/device/path.h
index 018fb93..3dc7625 100644
--- a/src/include/device/path.h
+++ b/src/include/device/path.h
@@ -12,6 +12,7 @@ enum device_path_type {
 	DEVICE_PATH_APIC_CLUSTER,
 	DEVICE_PATH_CPU,
 	DEVICE_PATH_CPU_BUS,
+	DEVICE_PATH_IOAPIC,
 };
 
 struct pci_domain_path
@@ -43,6 +44,11 @@ struct apic_path
 	unsigned index;
 };
 
+struct ioapic_path
+{
+	unsigned ioapic_id;
+};
+
 struct apic_cluster_path
 {
 	unsigned cluster;
@@ -66,6 +72,7 @@ struct device_path {
 		struct pnp_path          pnp;
 		struct i2c_path          i2c;
 		struct apic_path         apic;
+		struct ioapic_path	 ioapic;
 		struct pci_domain_path   pci_domain;
 		struct apic_cluster_path apic_cluster;
 		struct cpu_path          cpu;
diff --git a/util/sconfig/lex.yy.c_shipped b/util/sconfig/lex.yy.c_shipped
index 5b02db8..a955e2e 100644
--- a/util/sconfig/lex.yy.c_shipped
+++ b/util/sconfig/lex.yy.c_shipped
@@ -1,5 +1,5 @@
 
-#line 3 "/home/svens/coreboot/coreboot-svn/util/sconfig/lex.yy.c_shipped"
+#line 3 "/home/svens/coreboot/coreboot-i5000-latest/util/sconfig/lex.yy.c_shipped"
 
 #define  YY_INT_ALIGNED short int
 
@@ -368,8 +368,8 @@ static void yy_fatal_error (yyconst char msg[]  );
 	*yy_cp = '\0'; \
 	(yy_c_buf_p) = yy_cp;
 
-#define YY_NUM_RULES 27
-#define YY_END_OF_BUFFER 28
+#define YY_NUM_RULES 29
+#define YY_END_OF_BUFFER 30
 /* This struct is not used in this scanner,
    but its presence is necessary. */
 struct yy_trans_info
@@ -377,20 +377,21 @@ struct yy_trans_info
 	flex_int32_t yy_verify;
 	flex_int32_t yy_nxt;
 	};
-static yyconst flex_int16_t yy_accept[104] =
+static yyconst flex_int16_t yy_accept[112] =
     {   0,
-        0,    0,   28,   26,    1,    3,   26,   26,   26,   23,
-       23,   21,   24,   24,   24,   24,   26,   26,   26,   26,
-       26,   26,   26,    1,    3,   26,    0,   26,    0,    2,
-       23,   24,   26,   26,   24,   26,   26,   26,   26,   17,
-       26,   26,   26,    7,   26,   26,   26,   26,   25,   25,
-       22,   26,   26,   16,   20,   11,   26,   15,   26,    8,
-        9,   10,   26,   26,    4,   26,   26,   26,   26,   26,
-       26,   26,   26,   12,   26,   26,   26,    5,   26,   26,
-       26,   26,   26,   18,   26,   26,   26,   26,   26,   26,
-        6,   26,   26,   26,   26,   26,   14,   26,   26,   19,
-
-       26,   13,    0
+        0,    0,   30,   28,    1,    3,   28,   28,   28,   25,
+       25,   23,   26,   26,   26,   26,   28,   28,   28,   28,
+       28,   28,   28,    1,    3,   28,    0,   28,    0,    2,
+       25,   26,   28,   28,   26,   28,   28,   28,   28,   18,
+       28,   28,   28,    7,   28,   28,   28,   28,   27,   27,
+       24,   28,   28,   17,   22,   12,   28,   28,   16,   28,
+        8,    9,   11,   28,   28,    4,   28,   28,   28,   28,
+       28,   28,   28,   28,   28,   28,   13,   28,   28,   28,
+        5,   28,   10,   28,   28,   28,   28,   20,   28,   28,
+       28,   28,   28,   28,   28,   28,    6,   28,   28,   28,
+
+       28,   28,   19,   28,   15,   28,   28,   21,   28,   14,
+        0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -433,39 +434,41 @@ static yyconst flex_int32_t yy_meta[35] =
         1,    1,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[109] =
+static yyconst flex_int16_t yy_base[117] =
     {   0,
-        0,    0,  164,    0,  161,  165,  159,   33,   37,   34,
-      128,    0,   46,   49,   53,   56,   50,  147,   48,   22,
-      142,  127,    0,  155,  165,   74,  151,   65,  152,  165,
-        0,   75,   78,  133,   90,  126,  136,  136,  130,    0,
-      122,  122,  129,    0,  125,  119,  125,  129,    0,  165,
-        0,  116,  120,    0,    0,    0,  123,    0,  118,    0,
-      126,    0,  116,  107,    0,  120,  106,  118,  116,  102,
-       87,  103,   98,  106,   92,   86,   86,    0,   84,   98,
-       89,   94,   80,    0,   87,   95,   79,   89,   74,   83,
-        0,   80,   73,   77,   79,   60,    0,   72,   56,    0,
-
-       43,    0,  165,   43,  122,  124,  126,  128
+        0,    0,  172,    0,  169,  173,  167,   33,   37,   34,
+      136,    0,   46,   49,   53,   56,   50,  155,   48,   22,
+      150,  135,    0,  163,  173,   74,  159,   65,  160,  173,
+        0,   75,   78,  141,   90,  134,  144,  144,  138,  144,
+      129,  129,  136,    0,  132,  126,  132,  136,    0,  173,
+        0,  123,  127,    0,    0,    0,  130,  120,    0,  124,
+        0,  132,    0,  122,  113,    0,  126,  112,  118,  123,
+      121,  107,  101,  117,  112,  117,  119,   96,   90,   90,
+        0,   88,  105,  101,   92,   97,   83,    0,   91,   89,
+       97,   81,   91,   79,   75,   84,    0,   81,   76,   73,
+
+       77,   79,    0,   60,    0,   72,   56,    0,   43,    0,
+      173,   43,  122,  124,  126,  128
     } ;
 
-static yyconst flex_int16_t yy_def[109] =
+static yyconst flex_int16_t yy_def[117] =
     {   0,
-      103,    1,  103,  104,  103,  103,  104,  105,  106,  104,
-       10,  104,   10,   10,   10,   10,  104,  104,  104,  104,
-      104,  104,  104,  103,  103,  105,  107,  106,  108,  103,
-       10,   10,   10,  104,   10,  104,  104,  104,  104,  104,
-      104,  104,  104,  104,  104,  104,  104,  104,  104,  103,
-       33,  104,  104,  104,  104,  104,  104,  104,  104,  104,
-      104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
-      104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
-      104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
-      104,  104,  104,  104,  104,  104,  104,  104,  104,  104,
-
-      104,  104,    0,  103,  103,  103,  103,  103
+      111,    1,  111,  112,  111,  111,  112,  113,  114,  112,
+       10,  112,   10,   10,   10,   10,  112,  112,  112,  112,
+      112,  112,  112,  111,  111,  113,  115,  114,  116,  111,
+       10,   10,   10,  112,   10,  112,  112,  112,  112,  112,
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  111,
+       33,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+
+      112,  112,  112,  112,  112,  112,  112,  112,  112,  112,
+        0,  111,  111,  111,  111,  111
     } ;
 
-static yyconst flex_int16_t yy_nxt[200] =
+static yyconst flex_int16_t yy_nxt[208] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   10,   12,
        13,    4,   13,   13,   14,   15,   16,   13,    4,    4,
@@ -474,47 +477,49 @@ static yyconst flex_int16_t yy_nxt[200] =
        31,   31,   31,   23,   32,   46,   32,   32,   32,   32,
        32,   32,   32,   32,   32,   32,   32,   32,   38,   32,
        32,   32,   32,   32,   32,   43,   29,   30,   34,   35,
-      102,   44,  101,   39,   40,   27,   27,   41,   49,   37,
-       36,   32,   32,   32,   51,   51,   51,  100,   51,   99,
-       51,   51,   51,   51,   51,   51,   32,   32,   32,   98,
-
-       97,   96,   95,   94,   93,   92,   91,   90,   89,   88,
-       87,   86,   85,   84,   83,   82,   81,   80,   79,   78,
-       77,   53,   26,   26,   28,   28,   27,   27,   29,   29,
-       76,   75,   74,   73,   72,   71,   70,   69,   68,   67,
-       66,   65,   64,   63,   62,   61,   60,   59,   58,   57,
-       56,   55,   54,   52,   30,   50,   24,   48,   47,   42,
-       33,   25,   24,  103,    3,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103
-
+      110,   44,  109,   39,   40,   27,   27,   41,   49,   37,
+       36,   32,   32,   32,   51,   51,   51,  108,   51,  107,
+       51,   51,   51,   51,   51,   51,   32,   32,   32,  106,
+
+      105,  104,  103,  102,  101,  100,   99,   98,   97,   96,
+       95,   94,   93,   92,   91,   90,   89,   88,   87,   86,
+       85,   53,   26,   26,   28,   28,   27,   27,   29,   29,
+       84,   83,   82,   81,   80,   79,   78,   77,   76,   75,
+       74,   73,   72,   71,   70,   69,   68,   67,   66,   65,
+       64,   63,   62,   61,   60,   59,   58,   57,   56,   55,
+       54,   52,   30,   50,   24,   48,   47,   42,   33,   25,
+       24,  111,    3,  111,  111,  111,  111,  111,  111,  111,
+      111,  111,  111,  111,  111,  111,  111,  111,  111,  111,
+      111,  111,  111,  111,  111,  111,  111,  111,  111,  111,
+
+      111,  111,  111,  111,  111,  111,  111
     } ;
 
-static yyconst flex_int16_t yy_chk[200] =
+static yyconst flex_int16_t yy_chk[208] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    8,    8,   20,    8,    9,    9,
-       10,   10,   10,  104,   10,   20,   10,   10,   10,   10,
+       10,   10,   10,  112,   10,   20,   10,   10,   10,   10,
        10,   10,   13,   13,   13,   14,   14,   14,   17,   15,
        15,   15,   16,   16,   16,   19,   28,   28,   14,   15,
-      101,   19,   99,   17,   17,   26,   26,   17,   26,   16,
-       15,   32,   32,   32,   33,   33,   33,   98,   33,   96,
-       33,   33,   33,   33,   33,   33,   35,   35,   35,   95,
-
-       94,   93,   92,   90,   89,   88,   87,   86,   85,   83,
-       82,   81,   80,   79,   77,   76,   75,   74,   73,   72,
-       71,   35,  105,  105,  106,  106,  107,  107,  108,  108,
-       70,   69,   68,   67,   66,   64,   63,   61,   59,   57,
-       53,   52,   48,   47,   46,   45,   43,   42,   41,   39,
-       38,   37,   36,   34,   29,   27,   24,   22,   21,   18,
-       11,    7,    5,    3,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103,  103,
-      103,  103,  103,  103,  103,  103,  103,  103,  103
-
+      109,   19,  107,   17,   17,   26,   26,   17,   26,   16,
+       15,   32,   32,   32,   33,   33,   33,  106,   33,  104,
+       33,   33,   33,   33,   33,   33,   35,   35,   35,  102,
+
+      101,  100,   99,   98,   96,   95,   94,   93,   92,   91,
+       90,   89,   87,   86,   85,   84,   83,   82,   80,   79,
+       78,   35,  113,  113,  114,  114,  115,  115,  116,  116,
+       77,   76,   75,   74,   73,   72,   71,   70,   69,   68,
+       67,   65,   64,   62,   60,   58,   57,   53,   52,   48,
+       47,   46,   45,   43,   42,   41,   40,   39,   38,   37,
+       36,   34,   29,   27,   24,   22,   21,   18,   11,    7,
+        5,    3,  111,  111,  111,  111,  111,  111,  111,  111,
+      111,  111,  111,  111,  111,  111,  111,  111,  111,  111,
+      111,  111,  111,  111,  111,  111,  111,  111,  111,  111,
+
+      111,  111,  111,  111,  111,  111,  111
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -791,13 +796,13 @@ yy_match:
 			while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 				{
 				yy_current_state = (int) yy_def[yy_current_state];
-				if ( yy_current_state >= 104 )
+				if ( yy_current_state >= 112 )
 					yy_c = yy_meta[(unsigned int) yy_c];
 				}
 			yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
 			++yy_cp;
 			}
-		while ( yy_base[yy_current_state] != 165 );
+		while ( yy_base[yy_current_state] != 173 );
 
 yy_find_action:
 		yy_act = yy_accept[yy_current_state];
@@ -861,74 +866,82 @@ YY_RULE_SETUP
 	YY_BREAK
 case 10:
 YY_RULE_SETUP
-{yylval.number=PNP; return(BUS);}
+{yylval.number=IOAPIC; return(BUS);}
 	YY_BREAK
 case 11:
 YY_RULE_SETUP
-{yylval.number=I2C; return(BUS);}
+{yylval.number=PNP; return(BUS);}
 	YY_BREAK
 case 12:
 YY_RULE_SETUP
-{yylval.number=APIC; return(BUS);}
+{yylval.number=I2C; return(BUS);}
 	YY_BREAK
 case 13:
 YY_RULE_SETUP
-{yylval.number=APIC_CLUSTER; return(BUS);}
+{yylval.number=APIC; return(BUS);}
 	YY_BREAK
 case 14:
 YY_RULE_SETUP
-{yylval.number=PCI_DOMAIN; return(BUS);}
+{yylval.number=APIC_CLUSTER; return(BUS);}
 	YY_BREAK
 case 15:
 YY_RULE_SETUP
-{yylval.number=IRQ; return(RESOURCE);}
+{yylval.number=PCI_DOMAIN; return(BUS);}
 	YY_BREAK
 case 16:
 YY_RULE_SETUP
-{yylval.number=DRQ; return(RESOURCE);}
+{yylval.number=IRQ; return(RESOURCE);}
 	YY_BREAK
 case 17:
 YY_RULE_SETUP
-{yylval.number=IO; return(RESOURCE);}
+{yylval.number=DRQ; return(RESOURCE);}
 	YY_BREAK
 case 18:
 YY_RULE_SETUP
-{return(INHERIT);}
+{yylval.number=IO; return(RESOURCE);}
 	YY_BREAK
 case 19:
 YY_RULE_SETUP
-{return(SUBSYSTEMID);}
+{return(IOAPIC_IRQ);}
 	YY_BREAK
 case 20:
 YY_RULE_SETUP
-{return(END);}
+{return(INHERIT);}
 	YY_BREAK
 case 21:
 YY_RULE_SETUP
-{return(EQUALS);}
+{return(SUBSYSTEMID);}
 	YY_BREAK
 case 22:
 YY_RULE_SETUP
-{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
+{return(END);}
 	YY_BREAK
 case 23:
 YY_RULE_SETUP
-{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
+{return(EQUALS);}
 	YY_BREAK
 case 24:
 YY_RULE_SETUP
 {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
 	YY_BREAK
 case 25:
-/* rule 25 can match eol */
 YY_RULE_SETUP
-{yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);}
+{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
 	YY_BREAK
 case 26:
 YY_RULE_SETUP
-{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);}
+{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
 	YY_BREAK
 case 27:
+/* rule 27 can match eol */
+YY_RULE_SETUP
+{yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);}
+	YY_BREAK
+case 28:
+YY_RULE_SETUP
+{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);}
+	YY_BREAK
+case 29:
 YY_RULE_SETUP
 ECHO;
 	YY_BREAK
@@ -1223,7 +1236,7 @@ static int yy_get_next_buffer (void)
 		while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 			{
 			yy_current_state = (int) yy_def[yy_current_state];
-			if ( yy_current_state >= 104 )
+			if ( yy_current_state >= 112 )
 				yy_c = yy_meta[(unsigned int) yy_c];
 			}
 		yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1251,11 +1264,11 @@ static int yy_get_next_buffer (void)
 	while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
 		{
 		yy_current_state = (int) yy_def[yy_current_state];
-		if ( yy_current_state >= 104 )
+		if ( yy_current_state >= 112 )
 			yy_c = yy_meta[(unsigned int) yy_c];
 		}
 	yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-	yy_is_jam = (yy_current_state == 103);
+	yy_is_jam = (yy_current_state == 111);
 
 	return yy_is_jam ? 0 : yy_current_state;
 }
diff --git a/util/sconfig/main.c b/util/sconfig/main.c
index 5d97274..ca8c3c5 100644
--- a/util/sconfig/main.c
+++ b/util/sconfig/main.c
@@ -226,23 +226,35 @@ struct device *new_device(struct device *parent, struct device *busdev, const in
 
 	lastdev->nextdev = new_d;
 	lastdev = new_d;
-	if (bus == PCI) {
+
+	switch(bus) {
+	case PCI:
 		new_d->path = ".type=DEVICE_PATH_PCI,{.pci={ .devfn = PCI_DEVFN(0x%x,%d)}}";
-	}
-	if (bus == PNP) {
+		break;
+
+	case PNP:
 		new_d->path = ".type=DEVICE_PATH_PNP,{.pnp={ .port = 0x%x, .device = 0x%x }}";
-	}
-	if (bus == I2C) {
+		break;
+
+	case I2C:
 		new_d->path = ".type=DEVICE_PATH_I2C,{.i2c={ .device = 0x%x }}";
-	}
-	if (bus == APIC) {
+		break;
+
+	case APIC:
 		new_d->path = ".type=DEVICE_PATH_APIC,{.apic={ .apic_id = 0x%x }}";
-	}
-	if (bus == APIC_CLUSTER) {
+		break;
+
+	case APIC_CLUSTER:
 		new_d->path = ".type=DEVICE_PATH_APIC_CLUSTER,{.apic_cluster={ .cluster = 0x%x }}";
-	}
-	if (bus == PCI_DOMAIN) {
+		break;
+
+	case PCI_DOMAIN:
 		new_d->path = ".type=DEVICE_PATH_PCI_DOMAIN,{.pci_domain={ .domain = 0x%x }}";
+		break;
+
+	case IOAPIC:
+		new_d->path = ".type=DEVICE_PATH_IOAPIC,{.ioapic={ .ioapic_id = 0x%x }}";
+		break;
 	}
 	return new_d;
 }
@@ -322,6 +334,32 @@ void add_pci_subsystem_ids(struct device *dev, int vendor, int device, int inher
 	dev->inherit_subsystem = inherit;
 }
 
+void add_ioapic_info(struct device *dev, int apicid, const char *_srcpin, int irqpin)
+{
+
+	int srcpin;
+
+	if (!_srcpin || strlen(_srcpin) < 4 ||strncasecmp(_srcpin, "INT", 3) ||
+		   _srcpin[3] < 'A' || _srcpin[3] > 'D') {
+		printf("ERROR: malformed ioapic_irq args: %s\n", _srcpin);
+		exit(1);
+	}
+
+	srcpin = _srcpin[3] - 'A';
+
+	if (dev->bustype != PCI && dev->bustype != PCI_DOMAIN) {
+		printf("ERROR: ioapic config only allowed for PCI devices\n");
+		exit(1);
+	}
+
+	if (srcpin > 3) {
+		printf("ERROR: srcpin '%d' invalid\n");
+		exit(1);
+	}
+	dev->pci_irq_info[srcpin].ioapic_irq_pin = irqpin;
+	dev->pci_irq_info[srcpin].ioapic_dst_id = apicid;
+}
+
 static void pass0(FILE *fil, struct device *ptr) {
 	if (ptr->type == device && ptr->id == 0)
 		fprintf(fil, "struct bus %s_links[];\n", ptr->name);
@@ -334,7 +372,9 @@ static void pass0(FILE *fil, struct device *ptr) {
 	}
 }
 
-static void pass1(FILE *fil, struct device *ptr) {
+static void pass1(FILE *fil, struct device *ptr)
+{
+	int pin;
 	if (!ptr->used && (ptr->type == device)) {
 		if (ptr->id != 0)
 			fprintf(fil, "static ");
@@ -349,6 +389,14 @@ static void pass1(FILE *fil, struct device *ptr) {
 		if (ptr->subsystem_vendor > 0)
 			fprintf(fil, "\t.subsystem_vendor = 0x%04x,\n", ptr->subsystem_vendor);
 
+		for(pin = 0; pin < 4; pin++) {
+			if (ptr->pci_irq_info[pin].ioapic_irq_pin > 0)
+				fprintf(fil, "\t.pci_irq_info[%d].ioapic_irq_pin = %d,\n", pin, ptr->pci_irq_info[pin].ioapic_irq_pin);
+
+			if (ptr->pci_irq_info[pin].ioapic_dst_id > 0)
+				fprintf(fil, "\t.pci_irq_info[%d].ioapic_dst_id = %d,\n", pin, ptr->pci_irq_info[pin].ioapic_dst_id);
+		}
+
 		if (ptr->subsystem_device > 0)
 			fprintf(fil, "\t.subsystem_device = 0x%04x,\n", ptr->subsystem_device);
 
diff --git a/util/sconfig/sconfig.h b/util/sconfig/sconfig.h
index d893c05..1576600 100644
--- a/util/sconfig/sconfig.h
+++ b/util/sconfig/sconfig.h
@@ -43,6 +43,10 @@ struct reg {
 	struct reg *next;
 };
 
+struct pci_irq_info {
+	int ioapic_irq_pin;
+	int ioapic_dst_id;
+};
 struct device;
 struct device {
 	int id;
@@ -62,6 +66,7 @@ struct device {
 	int path_a;
 	int path_b;
 	int bustype;
+	struct pci_irq_info pci_irq_info[4];
 	enum devtype type;
 	struct device *parent;
 	struct device *bus;
diff --git a/util/sconfig/sconfig.l b/util/sconfig/sconfig.l
index 50c315b..3f3ac5c 100755
--- a/util/sconfig/sconfig.l
+++ b/util/sconfig/sconfig.l
@@ -34,6 +34,7 @@ register	{return(REGISTER);}
 on		{yylval.number=1; return(BOOL);}
 off		{yylval.number=0; return(BOOL);}
 pci		{yylval.number=PCI; return(BUS);}
+ioapic          {yylval.number=IOAPIC; return(BUS);}
 pnp		{yylval.number=PNP; return(BUS);}
 i2c		{yylval.number=I2C; return(BUS);}
 lapic		{yylval.number=APIC; return(BUS);}
@@ -42,6 +43,7 @@ pci_domain	{yylval.number=PCI_DOMAIN; return(BUS);}
 irq		{yylval.number=IRQ; return(RESOURCE);}
 drq		{yylval.number=DRQ; return(RESOURCE);}
 io		{yylval.number=IO; return(RESOURCE);}
+ioapic_irq      {return(IOAPIC_IRQ);}
 inherit		{return(INHERIT);}
 subsystemid	{return(SUBSYSTEMID);}
 end		{return(END);}
@@ -49,6 +51,7 @@ end		{return(END);}
 0x[0-9a-fA-F.]+	{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
 [0-9.]+		{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
 [0-9a-fA-F.]+	{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(NUMBER);}
+INT[A-D]        {yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(PCIINT);}
 \"[^\"]+\"	{yylval.string = malloc(yyleng-1); strncpy(yylval.string, yytext+1, yyleng-2); yylval.string[yyleng-2]='\0'; return(STRING);}
 [^ \n\t]+	{yylval.string = malloc(yyleng+1); strncpy(yylval.string, yytext, yyleng); yylval.string[yyleng]='\0'; return(STRING);}
 %%
diff --git a/util/sconfig/sconfig.tab.c_shipped b/util/sconfig/sconfig.tab.c_shipped
index dbefe06..170ae74 100644
--- a/util/sconfig/sconfig.tab.c_shipped
+++ b/util/sconfig/sconfig.tab.c_shipped
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton implementation for Bison's Yacc-like parsers in C
+/* Bison implementation for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -46,7 +44,7 @@
 #define YYBISON 1
 
 /* Bison version.  */
-#define YYBISON_VERSION "2.4.1"
+#define YYBISON_VERSION "2.5"
 
 /* Skeleton name.  */
 #define YYSKELETON_NAME "yacc.c"
@@ -141,7 +139,10 @@ static struct device *cur_parent, *cur_bus;
      IO = 276,
      NUMBER = 277,
      SUBSYSTEMID = 278,
-     INHERIT = 279
+     INHERIT = 279,
+     IOAPIC_IRQ = 280,
+     IOAPIC = 281,
+     PCIINT = 282
    };
 #endif
 
@@ -217,7 +218,7 @@ typedef short int yytype_int16;
 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
 
 #ifndef YY_
-# if YYENABLE_NLS
+# if defined YYENABLE_NLS && YYENABLE_NLS
 #  if ENABLE_NLS
 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
@@ -270,11 +271,11 @@ YYID (yyi)
 #    define alloca _alloca
 #   else
 #    define YYSTACK_ALLOC alloca
-#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#    if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#     ifndef _STDLIB_H
-#      define _STDLIB_H 1
+#     ifndef EXIT_SUCCESS
+#      define EXIT_SUCCESS 0
 #     endif
 #    endif
 #   endif
@@ -297,24 +298,24 @@ YYID (yyi)
 #  ifndef YYSTACK_ALLOC_MAXIMUM
 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
 #  endif
-#  if (defined __cplusplus && ! defined _STDLIB_H \
+#  if (defined __cplusplus && ! defined EXIT_SUCCESS \
        && ! ((defined YYMALLOC || defined malloc) \
 	     && (defined YYFREE || defined free)))
 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
-#   ifndef _STDLIB_H
-#    define _STDLIB_H 1
+#   ifndef EXIT_SUCCESS
+#    define EXIT_SUCCESS 0
 #   endif
 #  endif
 #  ifndef YYMALLOC
 #   define YYMALLOC malloc
-#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
 #   endif
 #  endif
 #  ifndef YYFREE
 #   define YYFREE free
-#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+#   if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \
      || defined __cplusplus || defined _MSC_VER)
 void free (void *); /* INFRINGES ON USER NAME SPACE */
 #   endif
@@ -343,23 +344,7 @@ union yyalloc
      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
       + YYSTACK_GAP_MAXIMUM)
 
-/* Copy COUNT objects from FROM to TO.  The source and destination do
-   not overlap.  */
-# ifndef YYCOPY
-#  if defined __GNUC__ && 1 < __GNUC__
-#   define YYCOPY(To, From, Count) \
-      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
-#  else
-#   define YYCOPY(To, From, Count)		\
-      do					\
-	{					\
-	  YYSIZE_T yyi;				\
-	  for (yyi = 0; yyi < (Count); yyi++)	\
-	    (To)[yyi] = (From)[yyi];		\
-	}					\
-      while (YYID (0))
-#  endif
-# endif
+# define YYCOPY_NEEDED 1
 
 /* Relocate STACK from its old location to the new one.  The
    local variables YYSIZE and YYSTACKSIZE give the old and new number of
@@ -379,23 +364,43 @@ union yyalloc
 
 #endif
 
+#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+#endif /* !YYCOPY_NEEDED */
+
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  3
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   34
+#define YYLAST   37
 
 /* YYNTOKENS -- Number of terminals.  */
-#define YYNTOKENS  25
+#define YYNTOKENS  28
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  12
+#define YYNNTS  13
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  20
+#define YYNRULES  22
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  36
+#define YYNSTATES  41
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   279
+#define YYMAXUTOK   282
 
 #define YYTRANSLATE(YYX)						\
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -430,7 +435,8 @@ static const yytype_uint8 yytranslate[] =
        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
-      15,    16,    17,    18,    19,    20,    21,    22,    23,    24
+      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27
 };
 
 #if YYDEBUG
@@ -439,28 +445,29 @@ static const yytype_uint8 yytranslate[] =
 static const yytype_uint8 yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    13,    16,    17,    20,
-      23,    26,    29,    30,    31,    37,    38,    46,    51,    56,
-      60
+      23,    26,    29,    32,    33,    34,    40,    41,    49,    54,
+      59,    63,    68
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
 static const yytype_int8 yyrhs[] =
 {
-      26,     0,    -1,    -1,    27,    30,    -1,    28,    32,    -1,
-      28,    30,    -1,    28,    35,    -1,    -1,    29,    32,    -1,
-      29,    30,    -1,    29,    34,    -1,    29,    36,    -1,    -1,
-      -1,     3,    12,    31,    28,     9,    -1,    -1,     4,     7,
-      22,     6,    33,    29,     9,    -1,     8,    22,    10,    22,
-      -1,     5,    12,    10,    12,    -1,    23,    22,    22,    -1,
-      23,    22,    22,    24,    -1
+      29,     0,    -1,    -1,    30,    33,    -1,    31,    35,    -1,
+      31,    33,    -1,    31,    38,    -1,    -1,    32,    35,    -1,
+      32,    33,    -1,    32,    37,    -1,    32,    39,    -1,    32,
+      40,    -1,    -1,    -1,     3,    12,    34,    31,     9,    -1,
+      -1,     4,     7,    22,     6,    36,    32,     9,    -1,     8,
+      22,    10,    22,    -1,     5,    12,    10,    12,    -1,    23,
+      22,    22,    -1,    23,    22,    22,    24,    -1,    25,    22,
+      27,    22,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint8 yyrline[] =
 {
        0,    35,    35,    35,    37,    37,    37,    37,    39,    39,
-      39,    39,    39,    41,    41,    51,    51,    63,    66,    69,
-      72
+      39,    39,    39,    39,    41,    41,    51,    51,    63,    66,
+      69,    72,    75
 };
 #endif
 
@@ -472,9 +479,9 @@ static const char *const yytname[] =
   "$end", "error", "$undefined", "CHIP", "DEVICE", "REGISTER", "BOOL",
   "BUS", "RESOURCE", "END", "EQUALS", "HEX", "STRING", "PCI", "PNP", "I2C",
   "APIC", "APIC_CLUSTER", "PCI_DOMAIN", "IRQ", "DRQ", "IO", "NUMBER",
-  "SUBSYSTEMID", "INHERIT", "$accept", "devtree", "$@1", "chipchildren",
-  "devicechildren", "chip", "@2", "device", "@3", "resource", "registers",
-  "subsystemid", 0
+  "SUBSYSTEMID", "INHERIT", "IOAPIC_IRQ", "IOAPIC", "PCIINT", "$accept",
+  "devtree", "$@1", "chipchildren", "devicechildren", "chip", "@2",
+  "device", "@3", "resource", "registers", "subsystemid", "ioapic_irq", 0
 };
 #endif
 
@@ -485,42 +492,43 @@ static const yytype_uint16 yytoknum[] =
 {
        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
-     275,   276,   277,   278,   279
+     275,   276,   277,   278,   279,   280,   281,   282
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    25,    27,    26,    28,    28,    28,    28,    29,    29,
-      29,    29,    29,    31,    30,    33,    32,    34,    35,    36,
-      36
+       0,    28,    30,    29,    31,    31,    31,    31,    32,    32,
+      32,    32,    32,    32,    34,    33,    36,    35,    37,    38,
+      39,    39,    40
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
        0,     2,     0,     2,     2,     2,     2,     0,     2,     2,
-       2,     2,     0,     0,     5,     0,     7,     4,     4,     3,
-       4
+       2,     2,     2,     0,     0,     5,     0,     7,     4,     4,
+       3,     4,     4
 };
 
-/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
-   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM.
+   Performed when YYTABLE doesn't specify something else to do.  Zero
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     0,     0,     1,     0,     3,    13,     7,     0,     0,
-       0,    14,     5,     4,     6,     0,     0,     0,     0,    15,
-      18,    12,     0,     0,    16,     0,     9,     8,    10,    11,
-       0,     0,     0,    19,    17,    20
+       2,     0,     0,     1,     0,     3,    14,     7,     0,     0,
+       0,    15,     5,     4,     6,     0,     0,     0,     0,    16,
+      19,    13,     0,     0,    17,     0,     0,     9,     8,    10,
+      11,    12,     0,     0,     0,     0,    20,     0,    18,    21,
+      22
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int8 yydefgoto[] =
 {
-      -1,     1,     2,     8,    22,     5,     7,    13,    21,    28,
-      14,    29
+      -1,     1,     2,     8,    22,     5,     7,    13,    21,    29,
+      14,    30,    31
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -530,46 +538,53 @@ static const yytype_int8 yypact[] =
 {
       -9,     3,     1,    -9,    -2,    -9,    -9,    -9,     4,     5,
       -1,    -9,    -9,    -9,    -9,    -8,     7,     9,     6,    -9,
-      -9,    -9,    -3,     0,    -9,     2,    -9,    -9,    -9,    -9,
-      11,     8,    10,    -5,    -9,    -9
+      -9,    -9,    -3,     2,    -9,     8,    10,    -9,    -9,    -9,
+      -9,    -9,    11,    12,    -4,    13,    -5,    14,    -9,    -9,
+      -9
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int8 yypgoto[] =
 {
-      -9,    -9,    -9,    -9,    -9,    -6,    -9,    12,    -9,    -9,
-      -9,    -9
+      -9,    -9,    -9,    -9,    -9,    -6,    -9,    15,    -9,    -9,
+      -9,    -9,    -9
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
-   number is the opposite.  If zero, do what YYDEFACT says.
-   If YYTABLE_NINF, syntax error.  */
+   number is the opposite.  If YYTABLE_NINF, syntax error.  */
 #define YYTABLE_NINF -1
 static const yytype_uint8 yytable[] =
 {
        4,     9,    12,     3,     4,    23,    24,     4,     9,    10,
-       6,    16,    15,    11,    17,    19,    26,    18,    20,    35,
-      25,    32,    30,     0,    31,     0,     0,     0,     0,     0,
-      33,     0,    34,     0,    27
+       6,    16,    15,    11,    17,    19,    27,    18,    20,    39,
+      25,    35,    26,    37,    32,     0,     0,     0,     0,     0,
+      33,     0,    34,     0,    36,    38,    40,    28
 };
 
+#define yypact_value_is_default(yystate) \
+  ((yystate) == (-9))
+
+#define yytable_value_is_error(yytable_value) \
+  YYID (0)
+
 static const yytype_int8 yycheck[] =
 {
        3,     4,     8,     0,     3,     8,     9,     3,     4,     5,
       12,    12,     7,     9,    22,     6,    22,    10,    12,    24,
-      23,    10,    22,    -1,    22,    -1,    -1,    -1,    -1,    -1,
-      22,    -1,    22,    -1,    22
+      23,    10,    25,    27,    22,    -1,    -1,    -1,    -1,    -1,
+      22,    -1,    22,    -1,    22,    22,    22,    22
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    26,    27,     0,     3,    30,    12,    31,    28,     4,
-       5,     9,    30,    32,    35,     7,    12,    22,    10,     6,
-      12,    33,    29,     8,     9,    23,    30,    32,    34,    36,
-      22,    22,    10,    22,    22,    24
+       0,    29,    30,     0,     3,    33,    12,    34,    31,     4,
+       5,     9,    33,    35,    38,     7,    12,    22,    10,     6,
+      12,    36,    32,     8,     9,    23,    25,    33,    35,    37,
+      39,    40,    22,    22,    22,    10,    22,    27,    22,    24,
+      22
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -584,9 +599,18 @@ static const yytype_uint8 yystos[] =
 
 /* Like YYERROR except do call yyerror.  This remains here temporarily
    to ease the transition to the new meaning of YYERROR, for GCC.
-   Once GCC version 2 has supplanted version 1, this can go.  */
+   Once GCC version 2 has supplanted version 1, this can go.  However,
+   YYFAIL appears to be in use.  Nevertheless, it is formally deprecated
+   in Bison 2.4.2's NEWS entry, where a plan to phase it out is
+   discussed.  */
 
 #define YYFAIL		goto yyerrlab
+#if defined YYFAIL
+  /* This is here to suppress warnings from the GCC cpp's
+     -Wunused-macros.  Normally we don't worry about that warning, but
+     some users do, and we want to make it easy for users to remove
+     YYFAIL uses, which will produce warnings from Bison 2.5.  */
+#endif
 
 #define YYRECOVERING()  (!!yyerrstatus)
 
@@ -596,7 +620,6 @@ do								\
     {								\
       yychar = (Token);						\
       yylval = (Value);						\
-      yytoken = YYTRANSLATE (yychar);				\
       YYPOPSTACK (1);						\
       goto yybackup;						\
     }								\
@@ -638,19 +661,10 @@ while (YYID (0))
 #endif
 
 
-/* YY_LOCATION_PRINT -- Print the location on the stream.
-   This macro was not mandated originally: define only if we know
-   we won't break user code: when these are the locations we know.  */
+/* This macro is provided for backward compatibility. */
 
 #ifndef YY_LOCATION_PRINT
-# if YYLTYPE_IS_TRIVIAL
-#  define YY_LOCATION_PRINT(File, Loc)			\
-     fprintf (File, "%d.%d-%d.%d",			\
-	      (Loc).first_line, (Loc).first_column,	\
-	      (Loc).last_line,  (Loc).last_column)
-# else
-#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
-# endif
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
 #endif
 
 
@@ -842,7 +856,6 @@ int yydebug;
 # define YYMAXDEPTH 10000
 #endif
 
-

 
 #if YYERROR_VERBOSE
 
@@ -945,115 +958,142 @@ yytnamerr (char *yyres, const char *yystr)
 }
 # endif
 
-/* Copy into YYRESULT an error message about the unexpected token
-   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
-   including the terminating null byte.  If YYRESULT is null, do not
-   copy anything; just return the number of bytes that would be
-   copied.  As a special case, return 0 if an ordinary "syntax error"
-   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
-   size calculation.  */
-static YYSIZE_T
-yysyntax_error (char *yyresult, int yystate, int yychar)
-{
-  int yyn = yypact[yystate];
+/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
+   about the unexpected token YYTOKEN for the state stack whose top is
+   YYSSP.
 
-  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
-    return 0;
-  else
+   Return 0 if *YYMSG was successfully written.  Return 1 if *YYMSG is
+   not large enough to hold the message.  In that case, also set
+   *YYMSG_ALLOC to the required number of bytes.  Return 2 if the
+   required number of bytes is too large to store.  */
+static int
+yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
+                yytype_int16 *yyssp, int yytoken)
+{
+  YYSIZE_T yysize0 = yytnamerr (0, yytname[yytoken]);
+  YYSIZE_T yysize = yysize0;
+  YYSIZE_T yysize1;
+  enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+  /* Internationalized format string. */
+  const char *yyformat = 0;
+  /* Arguments of yyformat. */
+  char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+  /* Number of reported tokens (one for the "unexpected", one per
+     "expected"). */
+  int yycount = 0;
+
+  /* There are many possibilities here to consider:
+     - Assume YYFAIL is not used.  It's too flawed to consider.  See
+       <http://lists.gnu.org/archive/html/bison-patches/2009-12/msg00024.html>
+       for details.  YYERROR is fine as it does not invoke this
+       function.
+     - If this state is a consistent state with a default action, then
+       the only way this function was invoked is if the default action
+       is an error action.  In that case, don't check for expected
+       tokens because there are none.
+     - The only way there can be no lookahead present (in yychar) is if
+       this state is a consistent state with a default action.  Thus,
+       detecting the absence of a lookahead is sufficient to determine
+       that there is no unexpected or expected token to report.  In that
+       case, just report a simple "syntax error".
+     - Don't assume there isn't a lookahead just because this state is a
+       consistent state with a default action.  There might have been a
+       previous inconsistent state, consistent state with a non-default
+       action, or user semantic action that manipulated yychar.
+     - Of course, the expected token list depends on states to have
+       correct lookahead information, and it depends on the parser not
+       to perform extra reductions after fetching a lookahead from the
+       scanner and before detecting a syntax error.  Thus, state merging
+       (from LALR or IELR) and default reductions corrupt the expected
+       token list.  However, the list is correct for canonical LR with
+       one exception: it will still contain any token that will not be
+       accepted due to an error action in a later state.
+  */
+  if (yytoken != YYEMPTY)
     {
-      int yytype = YYTRANSLATE (yychar);
-      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
-      YYSIZE_T yysize = yysize0;
-      YYSIZE_T yysize1;
-      int yysize_overflow = 0;
-      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
-      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
-      int yyx;
-
-# if 0
-      /* This is so xgettext sees the translatable formats that are
-	 constructed on the fly.  */
-      YY_("syntax error, unexpected %s");
-      YY_("syntax error, unexpected %s, expecting %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
-      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
-# endif
-      char *yyfmt;
-      char const *yyf;
-      static char const yyunexpected[] = "syntax error, unexpected %s";
-      static char const yyexpecting[] = ", expecting %s";
-      static char const yyor[] = " or %s";
-      char yyformat[sizeof yyunexpected
-		    + sizeof yyexpecting - 1
-		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
-		       * (sizeof yyor - 1))];
-      char const *yyprefix = yyexpecting;
-
-      /* Start YYX at -YYN if negative to avoid negative indexes in
-	 YYCHECK.  */
-      int yyxbegin = yyn < 0 ? -yyn : 0;
-
-      /* Stay within bounds of both yycheck and yytname.  */
-      int yychecklim = YYLAST - yyn + 1;
-      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-      int yycount = 1;
-
-      yyarg[0] = yytname[yytype];
-      yyfmt = yystpcpy (yyformat, yyunexpected);
-
-      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
-	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
-	  {
-	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
-	      {
-		yycount = 1;
-		yysize = yysize0;
-		yyformat[sizeof yyunexpected - 1] = '\0';
-		break;
-	      }
-	    yyarg[yycount++] = yytname[yyx];
-	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
-	    yysize_overflow |= (yysize1 < yysize);
-	    yysize = yysize1;
-	    yyfmt = yystpcpy (yyfmt, yyprefix);
-	    yyprefix = yyor;
-	  }
+      int yyn = yypact[*yyssp];
+      yyarg[yycount++] = yytname[yytoken];
+      if (!yypact_value_is_default (yyn))
+        {
+          /* Start YYX at -YYN if negative to avoid negative indexes in
+             YYCHECK.  In other words, skip the first -YYN actions for
+             this state because they are default actions.  */
+          int yyxbegin = yyn < 0 ? -yyn : 0;
+          /* Stay within bounds of both yycheck and yytname.  */
+          int yychecklim = YYLAST - yyn + 1;
+          int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+          int yyx;
+
+          for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+            if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
+                && !yytable_value_is_error (yytable[yyx + yyn]))
+              {
+                if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                  {
+                    yycount = 1;
+                    yysize = yysize0;
+                    break;
+                  }
+                yyarg[yycount++] = yytname[yyx];
+                yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+                if (! (yysize <= yysize1
+                       && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+                  return 2;
+                yysize = yysize1;
+              }
+        }
+    }
 
-      yyf = YY_(yyformat);
-      yysize1 = yysize + yystrlen (yyf);
-      yysize_overflow |= (yysize1 < yysize);
-      yysize = yysize1;
+  switch (yycount)
+    {
+# define YYCASE_(N, S)                      \
+      case N:                               \
+        yyformat = S;                       \
+      break
+      YYCASE_(0, YY_("syntax error"));
+      YYCASE_(1, YY_("syntax error, unexpected %s"));
+      YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
+      YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
+      YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
+      YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
+# undef YYCASE_
+    }
 
-      if (yysize_overflow)
-	return YYSIZE_MAXIMUM;
+  yysize1 = yysize + yystrlen (yyformat);
+  if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
+    return 2;
+  yysize = yysize1;
 
-      if (yyresult)
-	{
-	  /* Avoid sprintf, as that infringes on the user's name space.
-	     Don't have undefined behavior even if the translation
-	     produced a string with the wrong number of "%s"s.  */
-	  char *yyp = yyresult;
-	  int yyi = 0;
-	  while ((*yyp = *yyf) != '\0')
-	    {
-	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
-		{
-		  yyp += yytnamerr (yyp, yyarg[yyi++]);
-		  yyf += 2;
-		}
-	      else
-		{
-		  yyp++;
-		  yyf++;
-		}
-	    }
-	}
-      return yysize;
+  if (*yymsg_alloc < yysize)
+    {
+      *yymsg_alloc = 2 * yysize;
+      if (! (yysize <= *yymsg_alloc
+             && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
+        *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
+      return 1;
     }
+
+  /* Avoid sprintf, as that infringes on the user's name space.
+     Don't have undefined behavior even if the translation
+     produced a string with the wrong number of "%s"s.  */
+  {
+    char *yyp = *yymsg;
+    int yyi = 0;
+    while ((*yyp = *yyformat) != '\0')
+      if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
+        {
+          yyp += yytnamerr (yyp, yyarg[yyi++]);
+          yyformat += 2;
+        }
+      else
+        {
+          yyp++;
+          yyformat++;
+        }
+  }
+  return 0;
 }
 #endif /* YYERROR_VERBOSE */
-

 
 /*-----------------------------------------------.
 | Release the memory associated to this symbol.  |
@@ -1086,6 +1126,7 @@ yydestruct (yymsg, yytype, yyvaluep)
     }
 }
 
+
 /* Prevent warnings from -Wmissing-prototypes.  */
 #ifdef YYPARSE_PARAM
 #if defined __STDC__ || defined __cplusplus
@@ -1112,10 +1153,9 @@ YYSTYPE yylval;
 int yynerrs;
 
 
-
-/*-------------------------.
-| yyparse or yypush_parse.  |
-`-------------------------*/
+/*----------.
+| yyparse.  |
+`----------*/
 
 #ifdef YYPARSE_PARAM
 #if (defined __STDC__ || defined __C99__FUNC__ \
@@ -1139,8 +1179,6 @@ yyparse ()
 #endif
 #endif
 {
-
-
     int yystate;
     /* Number of tokens to shift before error messages enabled.  */
     int yyerrstatus;
@@ -1295,7 +1333,7 @@ yybackup:
 
   /* First try to decide what to do without reference to lookahead token.  */
   yyn = yypact[yystate];
-  if (yyn == YYPACT_NINF)
+  if (yypact_value_is_default (yyn))
     goto yydefault;
 
   /* Not known => get a lookahead token if don't already have one.  */
@@ -1326,8 +1364,8 @@ yybackup:
   yyn = yytable[yyn];
   if (yyn <= 0)
     {
-      if (yyn == 0 || yyn == YYTABLE_NINF)
-	goto yyerrlab;
+      if (yytable_value_is_error (yyn))
+        goto yyerrlab;
       yyn = -yyn;
       goto yyreduce;
     }
@@ -1382,74 +1420,90 @@ yyreduce:
     {
         case 2:
 
-    { cur_parent = cur_bus = head; ;}
+    { cur_parent = cur_bus = head; }
     break;
 
   case 3:
 
-    { postprocess_devtree(); ;}
+    { postprocess_devtree(); }
     break;
 
-  case 13:
+  case 14:
 
     {
 	(yyval.device) = new_chip(cur_parent, cur_bus, (yyvsp[(2) - (2)].string));
 	cur_parent = (yyval.device);
-;}
+}
     break;
 
-  case 14:
+  case 15:
 
     {
 	cur_parent = (yyvsp[(3) - (5)].device)->parent;
 	fold_in((yyvsp[(3) - (5)].device));
 	add_header((yyvsp[(3) - (5)].device));
-;}
+}
     break;
 
-  case 15:
+  case 16:
 
     {
 	(yyval.device) = new_device(cur_parent, cur_bus, (yyvsp[(2) - (4)].number), (yyvsp[(3) - (4)].string), (yyvsp[(4) - (4)].number));
 	cur_parent = (yyval.device);
 	cur_bus = (yyval.device);
-;}
+}
     break;
 
-  case 16:
+  case 17:
 
     {
 	cur_parent = (yyvsp[(5) - (7)].device)->parent;
 	cur_bus = (yyvsp[(5) - (7)].device)->bus;
 	fold_in((yyvsp[(5) - (7)].device));
 	alias_siblings((yyvsp[(5) - (7)].device)->children);
-;}
-    break;
-
-  case 17:
-
-    { add_resource(cur_parent, (yyvsp[(1) - (4)].number), strtol((yyvsp[(2) - (4)].string), NULL, 0), strtol((yyvsp[(4) - (4)].string), NULL, 0)); ;}
+}
     break;
 
   case 18:
 
-    { add_register(cur_parent, (yyvsp[(2) - (4)].string), (yyvsp[(4) - (4)].string)); ;}
+    { add_resource(cur_parent, (yyvsp[(1) - (4)].number), strtol((yyvsp[(2) - (4)].string), NULL, 0), strtol((yyvsp[(4) - (4)].string), NULL, 0)); }
     break;
 
   case 19:
 
-    { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[(2) - (3)].string), NULL, 16), strtol((yyvsp[(3) - (3)].string), NULL, 16), 0); ;}
+    { add_register(cur_parent, (yyvsp[(2) - (4)].string), (yyvsp[(4) - (4)].string)); }
     break;
 
   case 20:
 
-    { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[(2) - (4)].string), NULL, 16), strtol((yyvsp[(3) - (4)].string), NULL, 16), 1); ;}
+    { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[(2) - (3)].string), NULL, 16), strtol((yyvsp[(3) - (3)].string), NULL, 16), 0); }
+    break;
+
+  case 21:
+
+    { add_pci_subsystem_ids(cur_parent, strtol((yyvsp[(2) - (4)].string), NULL, 16), strtol((yyvsp[(3) - (4)].string), NULL, 16), 1); }
+    break;
+
+  case 22:
+
+    { add_ioapic_info(cur_parent, strtol((yyvsp[(2) - (4)].string), NULL, 16), (yyvsp[(3) - (4)].string), strtol((yyvsp[(4) - (4)].string), NULL, 16)); }
     break;
 
 
 
       default: break;
     }
+  /* User semantic actions sometimes alter yychar, and that requires
+     that yytoken be updated with the new translation.  We take the
+     approach of translating immediately before every use of yytoken.
+     One alternative is translating here after every semantic action,
+     but that translation would be missed if the semantic action invokes
+     YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
+     if it invokes YYBACKUP.  In the case of YYABORT or YYACCEPT, an
+     incorrect destructor might then be invoked immediately.  In the
+     case of YYERROR or YYBACKUP, subsequent parser actions might lead
+     to an incorrect destructor call or verbose syntax error message
+     before the lookahead is translated.  */
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
 
   YYPOPSTACK (yylen);
@@ -1477,6 +1531,10 @@ yyreduce:
 | yyerrlab -- here on detecting error |
 `------------------------------------*/
 yyerrlab:
+  /* Make sure we have latest lookahead translation.  See comments at
+     user semantic actions for why this is necessary.  */
+  yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
+
   /* If not already recovering from an error, report this error.  */
   if (!yyerrstatus)
     {
@@ -1484,37 +1542,36 @@ yyerrlab:
 #if ! YYERROR_VERBOSE
       yyerror (YY_("syntax error"));
 #else
+# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
+                                        yyssp, yytoken)
       {
-	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
-	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
-	  {
-	    YYSIZE_T yyalloc = 2 * yysize;
-	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
-	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
-	    if (yymsg != yymsgbuf)
-	      YYSTACK_FREE (yymsg);
-	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
-	    if (yymsg)
-	      yymsg_alloc = yyalloc;
-	    else
-	      {
-		yymsg = yymsgbuf;
-		yymsg_alloc = sizeof yymsgbuf;
-	      }
-	  }
-
-	if (0 < yysize && yysize <= yymsg_alloc)
-	  {
-	    (void) yysyntax_error (yymsg, yystate, yychar);
-	    yyerror (yymsg);
-	  }
-	else
-	  {
-	    yyerror (YY_("syntax error"));
-	    if (yysize != 0)
-	      goto yyexhaustedlab;
-	  }
+        char const *yymsgp = YY_("syntax error");
+        int yysyntax_error_status;
+        yysyntax_error_status = YYSYNTAX_ERROR;
+        if (yysyntax_error_status == 0)
+          yymsgp = yymsg;
+        else if (yysyntax_error_status == 1)
+          {
+            if (yymsg != yymsgbuf)
+              YYSTACK_FREE (yymsg);
+            yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
+            if (!yymsg)
+              {
+                yymsg = yymsgbuf;
+                yymsg_alloc = sizeof yymsgbuf;
+                yysyntax_error_status = 2;
+              }
+            else
+              {
+                yysyntax_error_status = YYSYNTAX_ERROR;
+                yymsgp = yymsg;
+              }
+          }
+        yyerror (yymsgp);
+        if (yysyntax_error_status == 2)
+          goto yyexhaustedlab;
       }
+# undef YYSYNTAX_ERROR
 #endif
     }
 
@@ -1573,7 +1630,7 @@ yyerrlab1:
   for (;;)
     {
       yyn = yypact[yystate];
-      if (yyn != YYPACT_NINF)
+      if (!yypact_value_is_default (yyn))
 	{
 	  yyn += YYTERROR;
 	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
@@ -1632,8 +1689,13 @@ yyexhaustedlab:
 
 yyreturn:
   if (yychar != YYEMPTY)
-     yydestruct ("Cleanup: discarding lookahead",
-		 yytoken, &yylval);
+    {
+      /* Make sure we have latest lookahead translation.  See comments at
+         user semantic actions for why this is necessary.  */
+      yytoken = YYTRANSLATE (yychar);
+      yydestruct ("Cleanup: discarding lookahead",
+                  yytoken, &yylval);
+    }
   /* Do not reclaim the symbols of the rule which action triggered
      this YYABORT or YYACCEPT.  */
   YYPOPSTACK (yylen);
diff --git a/util/sconfig/sconfig.tab.h_shipped b/util/sconfig/sconfig.tab.h_shipped
index fc101c2..3b45778 100644
--- a/util/sconfig/sconfig.tab.h_shipped
+++ b/util/sconfig/sconfig.tab.h_shipped
@@ -1,10 +1,8 @@
+/* A Bison parser, made by GNU Bison 2.5.  */
 
-/* A Bison parser, made by GNU Bison 2.4.1.  */
-
-/* Skeleton interface for Bison's Yacc-like parsers in C
+/* Bison interface for Yacc-like parsers in C
    
-      Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
-   Free Software Foundation, Inc.
+      Copyright (C) 1984, 1989-1990, 2000-2011 Free Software Foundation, Inc.
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -60,7 +58,10 @@
      IO = 276,
      NUMBER = 277,
      SUBSYSTEMID = 278,
-     INHERIT = 279
+     INHERIT = 279,
+     IOAPIC_IRQ = 280,
+     IOAPIC = 281,
+     PCIINT = 282
    };
 #endif
 
diff --git a/util/sconfig/sconfig.y b/util/sconfig/sconfig.y
index f97850f..12573a7 100755
--- a/util/sconfig/sconfig.y
+++ b/util/sconfig/sconfig.y
@@ -30,13 +30,13 @@ static struct device *cur_parent, *cur_bus;
 	int number;
 }
 
-%token CHIP DEVICE REGISTER BOOL BUS RESOURCE END EQUALS HEX STRING PCI PNP I2C APIC APIC_CLUSTER PCI_DOMAIN IRQ DRQ IO NUMBER SUBSYSTEMID INHERIT
+%token CHIP DEVICE REGISTER BOOL BUS RESOURCE END EQUALS HEX STRING PCI PNP I2C APIC APIC_CLUSTER PCI_DOMAIN IRQ DRQ IO NUMBER SUBSYSTEMID INHERIT IOAPIC_IRQ IOAPIC PCIINT
 %%
 devtree: { cur_parent = cur_bus = head; } chip { postprocess_devtree(); } ;
 
 chipchildren: chipchildren device | chipchildren chip | chipchildren registers | /* empty */ ;
 
-devicechildren: devicechildren device | devicechildren chip | devicechildren resource | devicechildren subsystemid | /* empty */ ;
+devicechildren: devicechildren device | devicechildren chip | devicechildren resource | devicechildren subsystemid | devicechildren ioapic_irq | /* empty */ ;
 
 chip: CHIP STRING /* == path */ {
 	$<device>$ = new_chip(cur_parent, cur_bus, $<string>2);
@@ -72,5 +72,6 @@ subsystemid: SUBSYSTEMID NUMBER NUMBER
 subsystemid: SUBSYSTEMID NUMBER NUMBER INHERIT
 	{ add_pci_subsystem_ids(cur_parent, strtol($<string>2, NULL, 16), strtol($<string>3, NULL, 16), 1); };
 
-
+ioapic_irq: IOAPIC_IRQ NUMBER PCIINT NUMBER
+	{ add_ioapic_info(cur_parent, strtol($<string>2, NULL, 16), $<string>3, strtol($<string>4, NULL, 16)); };
 %%




More information about the coreboot mailing list