blob: b1fcdd1577fbfb379ac85fd1d8f6703eaf90f95b [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{
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060015 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
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060019 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
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060023 smp_write_processors(mc);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000024
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
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060033 {
34 device_t dev;
Yinghai Luc34e3ab2006-10-12 00:58:20 +000035 struct resource *res;
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060036 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
37 if (dev) {
Yinghai Luc34e3ab2006-10-12 00:58:20 +000038 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 }
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060043 }
44 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
45 if (dev) {
Yinghai Luc34e3ab2006-10-12 00:58:20 +000046 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 }
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060051 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +000052
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060053 j = 0;
Yinghai Luc34e3ab2006-10-12 00:58:20 +000054
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060055 for(i = 1; i< sysconf.hc_possible_num; i++) {
56 if(!(sysconf.pci1234[i] & 0x1) ) continue;
Yinghai Luc34e3ab2006-10-12 00:58:20 +000057
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060058 switch(sysconf.hcid[i]) {
59 case 1: // 8132
Yinghai Luc34e3ab2006-10-12 00:58:20 +000060 case 3: // 8131
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060061 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) {
65 smp_write_ioapic(mc, m->apicid_8132a[j][0], 0x11,
66 res2mmio(res, 0, 0));
67 }
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) {
73 smp_write_ioapic(mc, m->apicid_8132a[j][1], 0x11,
74 res2mmio(res, 0, 0));
75 }
76 }
77 break;
78 }
79 j++;
80 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +000081
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
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060087 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);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000088
89// Onboard AMD USB
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060090 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);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000091
92// Onboard VGA
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060093 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);
Yinghai Luc34e3ab2006-10-12 00:58:20 +000094
95//Slot 5 PCI 32
Elyes HAOUAS531b87a2016-09-19 09:46:33 -060096 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +000099
100//Slot 6 PCI 32
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600101 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000104//Slot 1: HTX
105
106//Slot 2 PCI-X 133/100/66
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600107 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000110
111//Slot 3 PCI-X 133/100/66
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600112 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000115
116//Slot 4 PCI-X 133/100/66
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600117 for(i = 0; i < 4; i++) {
118 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
119 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000120
121//Onboard NICS
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600122 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
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000124
Stefan Reinauer14e22772010-04-27 06:56:47 +0000125//Onboard SATA
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600126 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
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000127
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600128 j = 0;
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000129
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600130 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:
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000137 case 3:
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600138 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000148
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600149 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000159
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600160 break;
161 case 2:
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000162
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600163 // 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 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000167
Elyes HAOUAS531b87a2016-09-19 09:46:33 -0600168 j++;
169 }
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000170
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}