blob: eecad5cac21bf8aa1f46b30bcb476151040a18fb [file] [log] [blame]
Yinghai Luc34e3ab2006-10-12 00:58:20 +00001#include <console/console.h>
2#include <arch/smp/mpspec.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +00003#include <arch/ioapic.h>
Yinghai Luc34e3ab2006-10-12 00:58:20 +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>
Yinghai Luc34e3ab2006-10-12 00:58:20 +00009#endif
Yinghai Luc34e3ab2006-10-12 00:58:20 +000010#include <cpu/amd/amdk8_sysconf.h>
11#include "mb_sysconf.h"
12
Stefan Reinauer50776fa2010-03-17 04:40:15 +000013static void *smp_write_config_table(void *v)
Yinghai Luc34e3ab2006-10-12 00:58:20 +000014{
Yinghai Luc34e3ab2006-10-12 00:58:20 +000015 struct mp_config_table *mc;
Patrick Georgi5244e1b2010-11-21 14:41:07 +000016 int i, j, bus_isa;
Yinghai Luc34e3ab2006-10-12 00:58:20 +000017 struct mb_sysconf_t *m;
18
19 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000020
Patrick Georgic8feedd2012-02-16 18:43:25 +010021 mptable_init(mc, LOCAL_APIC_ADDR);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000022
23 smp_write_processors(mc);
24
25 get_bus_conf();
26
27 m = sysconf.mb;
28
Patrick Georgi5244e1b2010-11-21 14:41:07 +000029 mptable_write_buses(mc, NULL, &bus_isa);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000030
31/*I/O APICs: APIC ID Version State Address*/
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080032 smp_write_ioapic(mc, m->apicid_8111, 0x11, VIO_APIC_VADDR); //8111
Yinghai Luc34e3ab2006-10-12 00:58:20 +000033 {
34 device_t dev;
35 struct resource *res;
36 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
37 if (dev) {
38 res = find_resource(dev, PCI_BASE_ADDRESS_0);
39 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080040 smp_write_ioapic(mc, m->apicid_8132_1, 0x11,
41 res2mmio(res, 0, 0));
Yinghai Luc34e3ab2006-10-12 00:58:20 +000042 }
43 }
44 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
45 if (dev) {
46 res = find_resource(dev, PCI_BASE_ADDRESS_0);
47 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080048 smp_write_ioapic(mc, m->apicid_8132_2, 0x11,
49 res2mmio(res, 0, 0));
Yinghai Luc34e3ab2006-10-12 00:58:20 +000050 }
51 }
52
53 j = 0;
54
55 for(i=1; i< sysconf.hc_possible_num; i++) {
56 if(!(sysconf.pci1234[i] & 0x1) ) continue;
57
58 switch(sysconf.hcid[i]) {
59 case 1: // 8132
60 case 3: // 8131
61 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
62 if (dev) {
63 res = find_resource(dev, PCI_BASE_ADDRESS_0);
64 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080065 smp_write_ioapic(mc, m->apicid_8132a[j][0], 0x11,
66 res2mmio(res, 0, 0));
Yinghai Luc34e3ab2006-10-12 00:58:20 +000067 }
68 }
69 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
70 if (dev) {
71 res = find_resource(dev, PCI_BASE_ADDRESS_0);
72 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080073 smp_write_ioapic(mc, m->apicid_8132a[j][1], 0x11,
74 res2mmio(res, 0, 0));
Yinghai Luc34e3ab2006-10-12 00:58:20 +000075 }
76 }
77 break;
78 }
79 j++;
80 }
81
82 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000083
Patrick Georgi5244e1b2010-11-21 14:41:07 +000084 mptable_add_isa_interrupts(mc, bus_isa, m->apicid_8111, 0);
Patrick Georgic5b87c82010-05-20 15:28:19 +000085
Yinghai Luc34e3ab2006-10-12 00:58:20 +000086//??? What
87 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_0, ((sysconf.sbdn+1)<<2)|3, m->apicid_8111, 0x13);
88
89// Onboard AMD USB
90 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (0<<2)|3, m->apicid_8111, 0x13);
91
92// Onboard VGA
93 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (6<<2)|0, m->apicid_8111, 0x12);
94
95//Slot 5 PCI 32
96 for(i=0;i<4;i++) {
97 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (5<<2)|i, m->apicid_8111, 0x10 + (1+i)%4); //16
98 }
99
100//Slot 6 PCI 32
101 for(i=0;i<4;i++) {
102 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (4<<2)|i, m->apicid_8111, 0x10 + (0+i)%4); //16
103 }
104//Slot 1: HTX
105
106//Slot 2 PCI-X 133/100/66
107 for(i=0;i<4;i++) {
108 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_2, (2<<2)|i, m->apicid_8132_2, (2+i)%4); //30
109 }
110
111//Slot 3 PCI-X 133/100/66
112 for(i=0;i<4;i++) {
113 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (1<<2)|i, m->apicid_8132_1, (1+i)%4); //25
114 }
115
116//Slot 4 PCI-X 133/100/66
117 for(i=0;i<4;i++) {
Stefan Reinauer14e22772010-04-27 06:56:47 +0000118 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (2<<2)|i, m->apicid_8132_1, (2+i)%4); //26
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000119 }
120
121//Onboard NICS
122 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (3<<2)|0, m->apicid_8132_1, 3); //27
123 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (4<<2)|0, m->apicid_8132_1, 0); //24
124
Stefan Reinauer14e22772010-04-27 06:56:47 +0000125//Onboard SATA
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000126 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (5<<2)|0, m->apicid_8132_1, 1); //25
127
128 j = 0;
129
130 for(i=1; i< sysconf.hc_possible_num; i++) {
131 if(!(sysconf.pci1234[i] & 0x1) ) continue;
132 int ii;
133 device_t dev;
134 struct resource *res;
135 switch(sysconf.hcid[i]) {
136 case 1:
137 case 3:
138 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
139 if (dev) {
140 res = find_resource(dev, PCI_BASE_ADDRESS_0);
141 if (res) {
142 //Slot 1 PCI-X 133/100/66
143 for(ii=0;ii<4;ii++) {
144 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][1], (0<<2)|ii, m->apicid_8132a[j][0], (0+ii)%4); //
145 }
146 }
147 }
148
149 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
150 if (dev) {
151 res = find_resource(dev, PCI_BASE_ADDRESS_0);
152 if (res) {
153 //Slot 2 PCI-X 133/100/66
154 for(ii=0;ii<4;ii++) {
155 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][2], (0<<2)|ii, m->apicid_8132a[j][1], (0+ii)%4); //25
156 }
157 }
158 }
159
160 break;
161 case 2:
162
163 // Slot AGP
164 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8151[j][1], 0x0, m->apicid_8111, 0x11);
165 break;
166 }
167
168 j++;
169 }
170
171
172
173/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +0200174 mptable_lintsrc(mc, bus_isa);
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000175 /* There is no extension information... */
176
177 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +0200178 return mptable_finalize(mc);
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000179}
180
181unsigned long write_smp_table(unsigned long addr)
182{
183 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +0200184 v = smp_write_floating_table(addr, 0);
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000185 return (unsigned long)smp_write_config_table(v);
186}