blob: 8bfaec8b70b9b958e42ef37de27b4682b1e1b1dc [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>
7#if CONFIG_LOGICAL_CPUS==1
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +00008#include <cpu/amd/multicore.h>
Yinghai Luc34e3ab2006-10-12 00:58:20 +00009#endif
10
11#include <cpu/amd/amdk8_sysconf.h>
12#include "mb_sysconf.h"
13
Stefan Reinauere9de1e22010-04-07 15:30:11 +000014
Yinghai Luc34e3ab2006-10-12 00:58:20 +000015
Stefan Reinauer50776fa2010-03-17 04:40:15 +000016static void *smp_write_config_table(void *v)
Yinghai Luc34e3ab2006-10-12 00:58:20 +000017{
18 static const char sig[4] = "PCMP";
Stefan Reinauerd6532112010-04-16 00:31:44 +000019 static const char oem[8] = "COREBOOT";
Yinghai Luc34e3ab2006-10-12 00:58:20 +000020 static const char productid[12] = "DK8-HTX ";
21 struct mp_config_table *mc;
22
23 unsigned char bus_num;
24 int i, j;
25 struct mb_sysconf_t *m;
26
27 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
28 memset(mc, 0, sizeof(*mc));
29
30 memcpy(mc->mpc_signature, sig, sizeof(sig));
31 mc->mpc_length = sizeof(*mc); /* initially just the header */
32 mc->mpc_spec = 0x04;
33 mc->mpc_checksum = 0; /* not yet computed */
34 memcpy(mc->mpc_oem, oem, sizeof(oem));
35 memcpy(mc->mpc_productid, productid, sizeof(productid));
36 mc->mpc_oemptr = 0;
37 mc->mpc_oemsize = 0;
38 mc->mpc_entry_count = 0; /* No entries yet... */
39 mc->mpc_lapic = LAPIC_ADDR;
40 mc->mpe_length = 0;
41 mc->mpe_checksum = 0;
42 mc->reserved = 0;
43
44 smp_write_processors(mc);
45
46 get_bus_conf();
47
48 m = sysconf.mb;
49
50/*Bus: Bus ID Type*/
51 /* define bus and isa numbers */
52 for(bus_num = 0; bus_num < m->bus_isa; bus_num++) {
53 smp_write_bus(mc, bus_num, "PCI ");
54 }
55 smp_write_bus(mc, m->bus_isa, "ISA ");
56
57/*I/O APICs: APIC ID Version State Address*/
Uwe Hermann74d1a6e2010-10-12 17:34:08 +000058 smp_write_ioapic(mc, m->apicid_8111, 0x11, IO_APIC_ADDR); //8111
Yinghai Luc34e3ab2006-10-12 00:58:20 +000059 {
60 device_t dev;
61 struct resource *res;
62 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
63 if (dev) {
64 res = find_resource(dev, PCI_BASE_ADDRESS_0);
65 if (res) {
66 smp_write_ioapic(mc, m->apicid_8132_1, 0x11, res->base);
67 }
68 }
69 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
70 if (dev) {
71 res = find_resource(dev, PCI_BASE_ADDRESS_0);
72 if (res) {
73 smp_write_ioapic(mc, m->apicid_8132_2, 0x11, res->base);
74 }
75 }
76
77 j = 0;
78
79 for(i=1; i< sysconf.hc_possible_num; i++) {
80 if(!(sysconf.pci1234[i] & 0x1) ) continue;
81
82 switch(sysconf.hcid[i]) {
83 case 1: // 8132
84 case 3: // 8131
85 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
86 if (dev) {
87 res = find_resource(dev, PCI_BASE_ADDRESS_0);
88 if (res) {
89 smp_write_ioapic(mc, m->apicid_8132a[j][0], 0x11, res->base);
90 }
91 }
92 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
93 if (dev) {
94 res = find_resource(dev, PCI_BASE_ADDRESS_0);
95 if (res) {
96 smp_write_ioapic(mc, m->apicid_8132a[j][1], 0x11, res->base);
97 }
98 }
99 break;
100 }
101 j++;
102 }
103
104 }
Stefan Reinauer14e22772010-04-27 06:56:47 +0000105
Patrick Georgic5b87c82010-05-20 15:28:19 +0000106 mptable_add_isa_interrupts(mc, m->bus_isa, m->apicid_8111, 0);
107
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000108//??? What
109 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);
110
111// Onboard AMD USB
112 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);
113
114// Onboard VGA
115 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);
116
117//Slot 5 PCI 32
118 for(i=0;i<4;i++) {
119 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
120 }
121
122//Slot 6 PCI 32
123 for(i=0;i<4;i++) {
124 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
125 }
126//Slot 1: HTX
127
128//Slot 2 PCI-X 133/100/66
129 for(i=0;i<4;i++) {
130 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
131 }
132
133//Slot 3 PCI-X 133/100/66
134 for(i=0;i<4;i++) {
135 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
136 }
137
138//Slot 4 PCI-X 133/100/66
139 for(i=0;i<4;i++) {
Stefan Reinauer14e22772010-04-27 06:56:47 +0000140 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 +0000141 }
142
143//Onboard NICS
144 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
145 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
146
Stefan Reinauer14e22772010-04-27 06:56:47 +0000147//Onboard SATA
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000148 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
149
150 j = 0;
151
152 for(i=1; i< sysconf.hc_possible_num; i++) {
153 if(!(sysconf.pci1234[i] & 0x1) ) continue;
154 int ii;
155 device_t dev;
156 struct resource *res;
157 switch(sysconf.hcid[i]) {
158 case 1:
159 case 3:
160 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
161 if (dev) {
162 res = find_resource(dev, PCI_BASE_ADDRESS_0);
163 if (res) {
164 //Slot 1 PCI-X 133/100/66
165 for(ii=0;ii<4;ii++) {
166 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); //
167 }
168 }
169 }
170
171 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
172 if (dev) {
173 res = find_resource(dev, PCI_BASE_ADDRESS_0);
174 if (res) {
175 //Slot 2 PCI-X 133/100/66
176 for(ii=0;ii<4;ii++) {
177 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
178 }
179 }
180 }
181
182 break;
183 case 2:
184
185 // Slot AGP
186 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8151[j][1], 0x0, m->apicid_8111, 0x11);
187 break;
188 }
189
190 j++;
191 }
192
193
194
195/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
196 smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0);
197 smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x1);
198 /* There is no extension information... */
199
200 /* Compute the checksums */
201 mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
202 mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000203 printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
Yinghai Luc34e3ab2006-10-12 00:58:20 +0000204 mc, smp_next_mpe_entry(mc));
205 return smp_next_mpe_entry(mc);
206}
207
208unsigned long write_smp_table(unsigned long addr)
209{
210 void *v;
211 v = smp_write_floating_table(addr);
212 return (unsigned long)smp_write_config_table(v);
213}