1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <device/pci.h>
7 void *smp_write_config_table(void *v)
9 static const char sig[4] = "PCMP";
10 static const char oem[8] = "TYAN ";
11 static const char productid[12] = "S2891 ";
12 struct mp_config_table *mc;
14 unsigned char bus_num;
15 unsigned char bus_isa;
16 unsigned char bus_ck804_0; //1
17 unsigned char bus_ck804_1; //2
18 unsigned char bus_ck804_2; //3
19 unsigned char bus_ck804_3; //4
20 unsigned char bus_ck804_4; //5
21 unsigned char bus_ck804_5; //6
22 unsigned char bus_8131_0; //7
23 unsigned char bus_8131_1; //8
24 unsigned char bus_8131_2; //9
26 unsigned apicid_ck804;
27 unsigned apicid_8131_1;
28 unsigned apicid_8131_2;
30 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
31 memset(mc, 0, sizeof(*mc));
33 memcpy(mc->mpc_signature, sig, sizeof(sig));
34 mc->mpc_length = sizeof(*mc); /* initially just the header */
36 mc->mpc_checksum = 0; /* not yet computed */
37 memcpy(mc->mpc_oem, oem, sizeof(oem));
38 memcpy(mc->mpc_productid, productid, sizeof(productid));
41 mc->mpc_entry_count = 0; /* No entries yet... */
42 mc->mpc_lapic = LAPIC_ADDR;
47 smp_write_processors(mc);
55 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x09,0));
57 bus_ck804_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
58 bus_ck804_4 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
62 printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n", CK804_DEVN_BASE + 0x09);
68 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0d,0));
70 bus_ck804_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
71 bus_ck804_5 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
75 printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0d);
77 bus_ck804_5 = bus_ck804_4+1;
80 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE + 0x0e,0));
82 bus_ck804_5 = pci_read_config8(dev, PCI_SECONDARY_BUS);
83 bus_8131_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
87 printk_debug("ERROR - could not find PCI 1:%02x.0, using defaults\n",CK804_DEVN_BASE + 0x0e);
89 bus_8131_0 = bus_ck804_5+1;
93 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x01,0));
95 bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
96 bus_8131_2 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
100 printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_8131_0);
102 bus_8131_1 = bus_8131_0+1;
103 bus_8131_2 = bus_8131_0+2;
106 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x02,0));
108 bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
109 bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
113 printk_debug("ERROR - could not find PCI %02x:02.0, using defaults\n", bus_8131_0);
115 bus_8131_2 = bus_8131_1+1;
116 bus_isa = bus_8131_1+2;
124 /* define bus and isa numbers */
125 for(bus_num = 0; bus_num < bus_isa; bus_num++) {
126 smp_write_bus(mc, bus_num, "PCI ");
128 smp_write_bus(mc, bus_isa, "ISA ");
130 /*I/O APICs: APIC ID Version State Address*/
131 apicid_base = CONFIG_MAX_CPUS;
132 apicid_ck804 = apicid_base;
133 apicid_8131_1 = apicid_base+1;
134 apicid_8131_2 = apicid_base+2;
135 // smp_write_ioapic(mc, 2, 0x11, 0xfec00000);
138 struct resource *res;
141 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(CK804_DEVN_BASE+ 0x1,0));
143 res = find_resource(dev, PCI_BASE_ADDRESS_1);
145 smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
150 pci_write_config32(dev, 0x7c, dword);
155 pci_write_config32(dev, 0x80, dword);
159 pci_write_config32(dev, 0x84, dword);
163 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x1,1));
165 res = find_resource(dev, PCI_BASE_ADDRESS_0);
167 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
170 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x2,1));
172 res = find_resource(dev, PCI_BASE_ADDRESS_0);
174 smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
180 /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
181 */ smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x0);
182 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x1, apicid_ck804, 0x1);
183 smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_ck804, 0x2);
184 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x3, apicid_ck804, 0x3);
185 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x4, apicid_ck804, 0x4);
186 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x6, apicid_ck804, 0x6);
187 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x7, apicid_ck804, 0x7);
188 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x8, apicid_ck804, 0x8);
189 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xc, apicid_ck804, 0xc);
190 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xd, apicid_ck804, 0xd);
191 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xe, apicid_ck804, 0xe);
192 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0xf, apicid_ck804, 0xf);
194 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+1)<<2)|1, apicid_ck804, 0xa);
196 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|0, apicid_ck804, 0x16);
198 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE+2)<<2)|1, apicid_ck804, 0x17);
200 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +7)<<2)|0, apicid_ck804, 0x14);
202 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((CK804_DEVN_BASE +8)<<2)|0, apicid_ck804, 0x15);
205 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|0, apicid_ck804, 0x12); //
206 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|1, apicid_ck804, 0x13); //
207 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|2, apicid_ck804, 0x10); //
208 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|3, apicid_ck804, 0x11); //
212 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|0, apicid_ck804, 0x11); //
213 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|1, apicid_ck804, 0x12); //
214 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|2, apicid_ck804, 0x13); //
215 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_4, (0x00<<2)|3, apicid_ck804, 0x10); //
218 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (7<<2)|0, apicid_ck804, 0x13); //
220 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|0, apicid_8131_2, 0x0); //
221 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|1, apicid_8131_2, 0x1);
223 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x0); //
224 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x1);//
225 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x2);//
226 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x3);//
228 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|0, apicid_8131_1, 0x2); //
229 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|1, apicid_8131_1, 0x3);//
230 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|2, apicid_8131_1, 0x0);//
231 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (0xa<<2)|3, apicid_8131_1, 0x1);//
234 /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
235 smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
236 smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
237 /* There is no extension information... */
239 /* Compute the checksums */
240 mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
241 mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
242 printk_debug("Wrote the mp table end at: %p - %p\n",
243 mc, smp_next_mpe_entry(mc));
244 return smp_next_mpe_entry(mc);
247 unsigned long write_smp_table(unsigned long addr)
250 v = smp_write_floating_table(addr);
251 return (unsigned long)smp_write_config_table(v);