summaryrefslogtreecommitdiff
path: root/util/sconfig/main.c
diff options
context:
space:
mode:
authorSven Schnelle <svens@stackframe.org>2012-06-21 22:19:48 +0200
committerPatrick Georgi <patrick@georgi-clan.de>2012-07-13 08:38:13 +0200
commit0fa50a1990fcdfca6a9f75a68f8e4ed22ddd6949 (patch)
treeff1ee24731267f351b79d321eb54fd773b51e299 /util/sconfig/main.c
parent6591470ae0c9639b1ef591ede96eee4a930f35e2 (diff)
downloadcoreboot-0fa50a1990fcdfca6a9f75a68f8e4ed22ddd6949.tar.xz
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@stackframe.org> Reviewed-on: http://review.coreboot.org/1138 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'util/sconfig/main.c')
-rw-r--r--util/sconfig/main.c72
1 files changed, 60 insertions, 12 deletions
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);