diff options
Diffstat (limited to 'src/mainboard/tyan/s2881/mptable.c')
-rw-r--r-- | src/mainboard/tyan/s2881/mptable.c | 55 |
1 files changed, 49 insertions, 6 deletions
diff --git a/src/mainboard/tyan/s2881/mptable.c b/src/mainboard/tyan/s2881/mptable.c index 06f1301ee5..ee92919db8 100644 --- a/src/mainboard/tyan/s2881/mptable.c +++ b/src/mainboard/tyan/s2881/mptable.c @@ -7,6 +7,41 @@ #include <cpu/amd/dualcore.h> #endif + +static unsigned node_link_to_bus(unsigned node, unsigned link) +{ + device_t dev; + unsigned reg; + + dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); + if (!dev) { + return 0; + } + for(reg = 0xE0; reg < 0xF0; reg += 0x04) { + uint32_t config_map; + unsigned dst_node; + unsigned dst_link; + unsigned bus_base; + config_map = pci_read_config32(dev, reg); + if ((config_map & 3) != 3) { + continue; + } + dst_node = (config_map >> 4) & 7; + dst_link = (config_map >> 8) & 3; + bus_base = (config_map >> 16) & 0xff; +#if 0 + printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n", + dst_node, dst_link, bus_base, + reg, config_map); +#endif + if ((dst_node == node) && (dst_link == link)) + { + return bus_base; + } + } + return 0; +} + void *smp_write_config_table(void *v) { static const char sig[4] = "PCMP"; @@ -16,6 +51,7 @@ void *smp_write_config_table(void *v) unsigned char bus_num; unsigned char bus_isa; + unsigned char bus_chain_0; unsigned char bus_8131_1; unsigned char bus_8131_2; unsigned char bus_8111_1; @@ -46,9 +82,16 @@ void *smp_write_config_table(void *v) { device_t dev; + + /* HT chain 0 */ + bus_chain_0 = node_link_to_bus(0, 2); + if (bus_chain_0 == 0) { + printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n"); + bus_chain_0 = 1; + } /* 8111 */ - dev = dev_find_slot(1, PCI_DEVFN(0x03,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0)); if (dev) { bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS); @@ -61,7 +104,7 @@ void *smp_write_config_table(void *v) bus_isa = 5; } /* 8131-1 */ - dev = dev_find_slot(1, PCI_DEVFN(0x01,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0)); if (dev) { bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -72,7 +115,7 @@ void *smp_write_config_table(void *v) bus_8131_1 = 2; } /* 8131-2 */ - dev = dev_find_slot(1, PCI_DEVFN(0x02,0)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0)); if (dev) { bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS); @@ -106,14 +149,14 @@ void *smp_write_config_table(void *v) { device_t dev; struct resource *res; - dev = dev_find_slot(1, PCI_DEVFN(0x1,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base); } } - dev = dev_find_slot(1, PCI_DEVFN(0x2,1)); + dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1)); if (dev) { res = find_resource(dev, PCI_BASE_ADDRESS_0); if (res) { @@ -138,7 +181,7 @@ void *smp_write_config_table(void *v) smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_8111, 0xf); //8111 LPC ???? - smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 1, (4<<2)|0, apicid_8111, 0x13); + smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13); //On Board AMD USB ??? smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13); |