Revision: linuxbios@linuxbios.org--devel/freebios--devel--2.0--patch-51
[coreboot.git] / src / mainboard / tyan / s2885 / mptable.c
1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <device/pci.h>
4 #include <string.h>
5 #include <stdint.h>
6 #if CONFIG_LOGICAL_CPUS==1
7 #include <cpu/amd/dualcore.h>
8 #endif
9
10 void *smp_write_config_table(void *v)
11 {
12         static const char sig[4] = "PCMP";
13         static const char oem[8] = "TYAN    ";
14         static const char productid[12] = "S2885       ";
15         struct mp_config_table *mc;
16
17         unsigned char bus_num;
18         unsigned char bus_isa;
19         unsigned char bus_8131_0;
20         unsigned char bus_8131_1;
21         unsigned char bus_8131_2;
22         unsigned char bus_8111_0;
23         unsigned char bus_8111_1;
24         unsigned char bus_8151_0;
25         unsigned char bus_8151_1;
26         unsigned apicid_base;
27         unsigned apicid_8111;
28         unsigned apicid_8131_1;
29         unsigned apicid_8131_2;
30
31
32         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
33         memset(mc, 0, sizeof(*mc));
34
35         memcpy(mc->mpc_signature, sig, sizeof(sig));
36         mc->mpc_length = sizeof(*mc); /* initially just the header */
37         mc->mpc_spec = 0x04;
38         mc->mpc_checksum = 0; /* not yet computed */
39         memcpy(mc->mpc_oem, oem, sizeof(oem));
40         memcpy(mc->mpc_productid, productid, sizeof(productid));
41         mc->mpc_oemptr = 0;
42         mc->mpc_oemsize = 0;
43         mc->mpc_entry_count = 0; /* No entries yet... */
44         mc->mpc_lapic = LAPIC_ADDR;
45         mc->mpe_length = 0;
46         mc->mpe_checksum = 0;
47         mc->reserved = 0;
48
49         smp_write_processors(mc);
50
51        {
52                 device_t dev;
53
54                 /* 8151 */
55                 bus_8151_0 = 1;
56                 dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
57                 if (dev) {
58                         bus_8151_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
59 //                        printk_debug("bus_8151_1=%d\n",bus_8151_1);
60                         bus_8111_0 = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
61                         bus_8111_0++;
62                         bus_8131_0 = bus_8111_0;
63 //                      printk_debug("bus_8111_0=%d\n",bus_8111_0);
64                 }
65                 else {
66                         printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
67                         bus_8151_1 = 2;
68                         bus_8111_0 = bus_8131_0 = 3;
69                 }
70
71                 /* 8111 */
72                 dev = dev_find_slot(bus_8111_0, PCI_DEVFN(0x03,0));
73                 if (dev) {
74                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
75                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
76                         bus_isa++;
77 //                      printk_debug("bus_isa=%d\n",bus_isa);
78                 }
79                 else {
80                         printk_debug("ERROR - could not find PCI %02x:03.0, using defaults\n", bus_8111_0);
81
82                         bus_8111_1 = 6;
83                         bus_isa = 7;
84                 }
85                 /* 8131-1 */
86                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x01,0));
87                 if (dev) {
88                         bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
89
90                 }
91                 else {
92                         printk_debug("ERROR - could not find PCI %02x:01.0, using defaults\n", bus_8131_0);
93
94                         bus_8131_1 = 4;
95                 }
96                 /* 8131-2 */
97                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x02,0));
98                 if (dev) {
99                         bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
100
101                 }
102                 else {
103                         printk_debug("ERROR - could not find PCI %02x:02.0, using defaults\n", bus_8131_0);
104
105                         bus_8131_2 = 5;
106                 }
107    
108         }
109
110
111
112 /*Bus:          Bus ID  Type*/
113        /* define bus and isa numbers */
114         for(bus_num = 0; bus_num < bus_isa; bus_num++) {
115                 smp_write_bus(mc, bus_num, "PCI   ");
116         }
117         smp_write_bus(mc, bus_isa, "ISA   ");
118
119 /*I/O APICs:    APIC ID Version State           Address*/
120 #if CONFIG_LOGICAL_CPUS==1
121         apicid_base = get_apicid_base(3);
122 #else 
123         apicid_base = CONFIG_MAX_PHYSICAL_CPUS; 
124 #endif
125         apicid_8111 = apicid_base+0;
126         apicid_8131_1 = apicid_base+1;
127         apicid_8131_2 = apicid_base+2;
128         smp_write_ioapic(mc, apicid_8111, 0x11, 0xfec00000); //8111
129         {
130                 device_t dev;
131                 struct resource *res;
132                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x1,1));
133                 if (dev) {
134                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
135                         if (res) {
136                                 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
137                         }
138                 }
139                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(0x2,1));
140                 if (dev) {
141                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
142                         if (res) {
143                                 smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
144                         }
145                 }
146         }
147   
148 /*I/O Ints:     Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN#
149 */      smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, apicid_8111, 0x0);
150         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x1, apicid_8111, 0x1);
151         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x0, apicid_8111, 0x2);
152         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x3, apicid_8111, 0x3);
153         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x4, apicid_8111, 0x4);
154         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x5, apicid_8111, 0x5);
155         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x6, apicid_8111, 0x6);
156         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x7, apicid_8111, 0x7);
157         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0x8, apicid_8111, 0x8);
158         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xc, apicid_8111, 0xc);
159         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xd, apicid_8111, 0xd);
160         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xe, apicid_8111, 0xe);
161         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,  bus_isa, 0xf, apicid_8111, 0xf);
162 //??? What
163         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<2)|3, apicid_8111, 0x13);
164 //Onboard AMD AC97 Audio 
165         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_0, (4<<2)|1, apicid_8111, 0x11);
166 // Onboard AMD USB
167         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0<<2)|3, apicid_8111, 0x13);
168
169 //  AGP Display Adapter
170         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8151_1, 0x0, apicid_8111, 0x10);
171
172 //Onboard Serial ATA        
173         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0b<<2)|0, apicid_8111, 0x11);
174 //Onboard Firewire
175         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0c<<2)|0, apicid_8111, 0x13);
176 //Onboard Broadcom NIC
177         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (9<<2)|0, apicid_8131_1, 0x0);
178
179 //Slot 5 PCI 32
180         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|0, apicid_8111, 0x10);
181         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|1, apicid_8111, 0x11);
182         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|2, apicid_8111, 0x12); //
183         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8111_1, (0x0a<<2)|3, apicid_8111, 0x13); //
184
185 //Slot 3 PCIX 100/66
186         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|0, apicid_8131_1, 0x3);
187         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|1, apicid_8131_1, 0x0);
188         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|2, apicid_8131_1, 0x1);//
189         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (8<<2)|3, apicid_8131_1, 0x2);//
190
191 //Slot 4 PCIX 100/66        
192         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|0, apicid_8131_1, 0x2);
193         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|1, apicid_8131_1, 0x3);//
194         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|2, apicid_8131_1, 0x0);//
195         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (7<<2)|3, apicid_8131_1, 0x1);//
196
197 //Slot 1 PCI-X 133/100/66
198         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|0, apicid_8131_2, 0x0);
199         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|1, apicid_8131_2, 0x1);
200         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|2, apicid_8131_2, 0x2); //
201         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (3<<2)|3, apicid_8131_2, 0x3); //
202
203 //Slot 2 PCI-X 133/100/66
204         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|0, apicid_8131_2, 0x1);
205         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|1, apicid_8131_2, 0x2);
206         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|2, apicid_8131_2, 0x3);//
207         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|3, apicid_8131_2, 0x0);//
208
209 /*Local Ints:   Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN#*/
210         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
211         smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
212         /* There is no extension information... */
213
214         /* Compute the checksums */
215         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
216         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
217         printk_debug("Wrote the mp table end at: %p - %p\n",
218                 mc, smp_next_mpe_entry(mc));
219         return smp_next_mpe_entry(mc);
220 }
221
222 unsigned long write_smp_table(unsigned long addr)
223 {
224         void *v;
225         v = smp_write_floating_table(addr);
226         return (unsigned long)smp_write_config_table(v);
227 }