From 0fa50a1990fcdfca6a9f75a68f8e4ed22ddd6949 Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Thu, 21 Jun 2012 22:19:48 +0200 Subject: [PATCH] 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 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 Reviewed-on: http://review.coreboot.org/1138 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi --- 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 | 193 +++++----- util/sconfig/main.c | 72 +++- util/sconfig/sconfig.h | 5 + util/sconfig/sconfig.l | 3 + util/sconfig/sconfig.tab.c_shipped | 596 ++++++++++++++++------------- util/sconfig/sconfig.tab.h_shipped | 13 +- util/sconfig/sconfig.y | 7 +- 11 files changed, 631 insertions(+), 379 deletions(-) diff --git a/src/arch/x86/boot/mpspec.c b/src/arch/x86/boot/mpspec.c index e7d767b7ac..44236f1cca 100644 --- a/src/arch/x86/boot/mpspec.c +++ b/src/arch/x86/boot/mpspec.c @@ -6,6 +6,7 @@ #include #include #include +#include /* 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 ecc2c13659..7c1cde9895 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 0aea1d6087..f36710ae0a 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 018fb9313f..3dc7625029 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 5b02db843c..a955e2ecf2 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, + 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, - 26, 13, 0 + 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, + 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, - 43, 0, 165, 43, 122, 124, 126, 128 + 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, + 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, - 104, 104, 0, 103, 103, 103, 103, 103 + 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, + 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, - 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 + 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, + 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, - 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 + 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 5d97274ebf..ca8c3c5c4c 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 d893c05395..15766006a7 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 50c315b0c3..3f3ac5c874 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 dbefe06405..170ae74390 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 /* 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 /* 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 /* 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) +/* 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. + + 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) { - int yyn = yypact[yystate]; + 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; - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else + /* There are many possibilities here to consider: + - Assume YYFAIL is not used. It's too flawed to consider. See + + 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; + 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; -# 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; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - 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; + 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; + } + } } + + 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_ + } + + yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + + 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(); ;} - break; - - case 13: - - { - (yyval.device) = new_chip(cur_parent, cur_bus, (yyvsp[(2) - (2)].string)); - cur_parent = (yyval.device); -;} + { postprocess_devtree(); } break; case 14: { - cur_parent = (yyvsp[(3) - (5)].device)->parent; - fold_in((yyvsp[(3) - (5)].device)); - add_header((yyvsp[(3) - (5)].device)); -;} + (yyval.device) = new_chip(cur_parent, cur_bus, (yyvsp[(2) - (2)].string)); + cur_parent = (yyval.device); +} break; case 15: { - (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); -;} + cur_parent = (yyvsp[(3) - (5)].device)->parent; + fold_in((yyvsp[(3) - (5)].device)); + add_header((yyvsp[(3) - (5)].device)); +} break; 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 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 fc101c20ee..3b45778f64 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 f97850ff69..12573a7d2d 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 */ { $$ = new_chip(cur_parent, cur_bus, $2); @@ -72,5 +72,6 @@ subsystemid: SUBSYSTEMID NUMBER NUMBER subsystemid: SUBSYSTEMID NUMBER NUMBER INHERIT { add_pci_subsystem_ids(cur_parent, strtol($2, NULL, 16), strtol($3, NULL, 16), 1); }; - +ioapic_irq: IOAPIC_IRQ NUMBER PCIINT NUMBER + { add_ioapic_info(cur_parent, strtol($2, NULL, 16), $3, strtol($4, NULL, 16)); }; %%