blob: b315c40678e06f7169814d96ffae8ca077d74b8f [file] [log] [blame]
arch import user (historical)7dec0f92005-07-06 18:17:06 +00001#include <console/console.h>
2#include <arch/smp/mpspec.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +00003#include <arch/ioapic.h>
arch import user (historical)7dec0f92005-07-06 18:17:06 +00004#include <device/pci.h>
5#include <string.h>
6#include <stdint.h>
Patrick Georgie1667822012-05-05 15:29:32 +02007#if CONFIG_LOGICAL_CPUS
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +00008#include <cpu/amd/multicore.h>
arch import user (historical)7dec0f92005-07-06 18:17:06 +00009#endif
10
11static unsigned node_link_to_bus(unsigned node, unsigned link)
12{
13 device_t dev;
14 unsigned reg;
15
16 dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
17 if (!dev) {
18 return 0;
19 }
20 for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
21 uint32_t config_map;
22 unsigned dst_node;
23 unsigned dst_link;
24 unsigned bus_base;
25 config_map = pci_read_config32(dev, reg);
26 if ((config_map & 3) != 3) {
27 continue;
28 }
29 dst_node = (config_map >> 4) & 7;
30 dst_link = (config_map >> 8) & 3;
31 bus_base = (config_map >> 16) & 0xff;
Stefan Reinauer14e22772010-04-27 06:56:47 +000032#if 0
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000033 printk(BIOS_DEBUG, "node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
arch import user (historical)7dec0f92005-07-06 18:17:06 +000034 dst_node, dst_link, bus_base,
35 reg, config_map);
36#endif
37 if ((dst_node == node) && (dst_link == link))
38 {
39 return bus_base;
40 }
41 }
42 return 0;
43}
44
Myles Watson08e0fb82010-03-22 16:33:25 +000045static void *smp_write_config_table(void *v)
arch import user (historical)7dec0f92005-07-06 18:17:06 +000046{
arch import user (historical)7dec0f92005-07-06 18:17:06 +000047 struct mp_config_table *mc;
Patrick Georgi20979582010-09-24 18:42:56 +000048 int bus_isa;
arch import user (historical)7dec0f92005-07-06 18:17:06 +000049 unsigned char bus_chain_0;
50 unsigned char bus_8131_1;
51 unsigned char bus_8131_2;
52 unsigned char bus_8111_1;
53 unsigned apicid_base;
54 unsigned apicid_8111;
55 unsigned apicid_8131_1;
56 unsigned apicid_8131_2;
Stefan Reinauer14e22772010-04-27 06:56:47 +000057
arch import user (historical)7dec0f92005-07-06 18:17:06 +000058 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
arch import user (historical)7dec0f92005-07-06 18:17:06 +000059
Patrick Georgic8feedd2012-02-16 18:43:25 +010060 mptable_init(mc, LOCAL_APIC_ADDR);
arch import user (historical)7dec0f92005-07-06 18:17:06 +000061
62 smp_write_processors(mc);
63
arch import user (historical)7dec0f92005-07-06 18:17:06 +000064 {
65 device_t dev;
66
67 /* HT chain 0 */
68 bus_chain_0 = node_link_to_bus(0, 2);
69 if (bus_chain_0 == 0) {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000070 printk(BIOS_DEBUG, "ERROR - cound not find bus for node 0 chain 0, using defaults\n");
arch import user (historical)7dec0f92005-07-06 18:17:06 +000071 bus_chain_0 = 1;
72 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000073
arch import user (historical)7dec0f92005-07-06 18:17:06 +000074 /* 8111 */
75 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
76 if (dev) {
77 bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
Stefan Reinauer14e22772010-04-27 06:56:47 +000078 }
arch import user (historical)7dec0f92005-07-06 18:17:06 +000079 else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000080 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:03.0, using defaults\n");
arch import user (historical)7dec0f92005-07-06 18:17:06 +000081
82 bus_8111_1 = 4;
arch import user (historical)7dec0f92005-07-06 18:17:06 +000083 }
84 /* 8131-1 */
85 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
86 if (dev) {
87 bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
88
89 }
90 else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000091 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:01.0, using defaults\n");
arch import user (historical)7dec0f92005-07-06 18:17:06 +000092
93 bus_8131_1 = 2;
94 }
95 /* 8131-2 */
96 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
97 if (dev) {
98 bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
99
100 }
101 else {
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000102 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n");
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000103
104 bus_8131_2 = 3;
105 }
106 }
107
108/*Bus: Bus ID Type*/
Patrick Georgi20979582010-09-24 18:42:56 +0000109 mptable_write_buses(mc, NULL, &bus_isa);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000110
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000111/*I/O APICs: APIC ID Version State Address*/
Patrick Georgie1667822012-05-05 15:29:32 +0200112#if CONFIG_LOGICAL_CPUS
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000113 apicid_base = get_apicid_base(3);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000114#else
115 apicid_base = CONFIG_MAX_PHYSICAL_CPUS;
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000116#endif
Stefan Reinauer14e22772010-04-27 06:56:47 +0000117 apicid_8111 = apicid_base+0;
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000118 apicid_8131_1 = apicid_base+1;
119 apicid_8131_2 = apicid_base+2;
120
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800121 smp_write_ioapic(mc, apicid_8111, 0x11, VIO_APIC_VADDR);
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000122 {
123 device_t dev;
124 struct resource *res;
125 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x1,1));
126 if (dev) {
127 res = find_resource(dev, PCI_BASE_ADDRESS_0);
128 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800129 smp_write_ioapic(mc, apicid_8131_1, 0x11,
130 res2mmio(res, 0, 0));
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000131 }
132 }
133 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x2,1));
134 if (dev) {
135 res = find_resource(dev, PCI_BASE_ADDRESS_0);
136 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -0800137 smp_write_ioapic(mc, apicid_8131_2, 0x11,
138 res2mmio(res, 0, 0));
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000139 }
140 }
141
142 }
Stefan Reinauer14e22772010-04-27 06:56:47 +0000143
Patrick Georgic5b87c82010-05-20 15:28:19 +0000144 mptable_add_isa_interrupts(mc, bus_isa, apicid_8111, 0);
Stefan Reinauer14e22772010-04-27 06:56:47 +0000145
Patrick Georgic5b87c82010-05-20 15:28:19 +0000146/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000147 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_chain_0, (4<<2)|0, apicid_8111, 0x13);
148
149
150//On Board AMD USB
151 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13);
152
153//On Board Via USB 1.1 and 2
154 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|0, apicid_8111, 0x11); //1.1
155 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|1, apicid_8111, 0x10); //1.1
156 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (3<<2)|2, apicid_8111, 0x12); //2
157
158//Slot 5 PCI 32
159 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|0, apicid_8111, 0x10);
160 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|1, apicid_8111, 0x11);
161 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|2, apicid_8111, 0x12); //
162 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (4<<2)|3, apicid_8111, 0x13); //
163
164
165//On Board SI Serial ATA
166 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (5<<2)|0, apicid_8111, 0x13);
167//On Board ATI Display Adapter
168 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (6<<2)|0, apicid_8111, 0x12);
169
170
171//Slot 4 PCIX 100/66
172 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|0, apicid_8131_1, 0x3);
173 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|1, apicid_8131_1, 0x0);
174 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|2, apicid_8131_1, 0x1);//
175 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (3<<2)|3, apicid_8131_1, 0x2);//
176
Stefan Reinauer14e22772010-04-27 06:56:47 +0000177//Slot 3 PCIX 100/66
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000178 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|0, apicid_8131_1, 0x2);
179 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|1, apicid_8131_1, 0x3);//
180 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|2, apicid_8131_1, 0x0);//
181 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (2<<2)|3, apicid_8131_1, 0x1);//
182
183//On Board LSI scsi and NIC
184 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|0, apicid_8131_1, 0x0);
185 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|1, apicid_8131_1, 0x1);
186 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0);
187 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|1, apicid_8131_1, 0x1);
188
189//Slot 2 PCI-X 133/100/66
190 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0);
191 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, apicid_8131_2, 0x1);
192 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x2); //
193 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); //
194
195//Slot 1 PCI-X 133/100/66
196 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|0, apicid_8131_2, 0x1);
197 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|1, apicid_8131_2, 0x2);
198 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|2, apicid_8131_2, 0x3);//
199 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (1<<2)|3, apicid_8131_2, 0x0);//
200
201/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +0200202 mptable_lintsrc(mc, bus_isa);
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000203 /* There is no extension information... */
204
205 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +0200206 return mptable_finalize(mc);
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000207}
208
209unsigned long write_smp_table(unsigned long addr)
210{
211 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +0200212 v = smp_write_floating_table(addr, 0);
arch import user (historical)7dec0f92005-07-06 18:17:06 +0000213 return (unsigned long)smp_write_config_table(v);
214}