7a2a5943ff7a63602b159395b24411eaa0f05e55
[coreboot.git] / src / mainboard / intel / jarrell / mptable.c
1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <arch/ioapic.h>
4 #include <device/pci.h>
5 #include <string.h>
6 #include <stdint.h>
7
8 static void *smp_write_config_table(void *v)
9 {
10         static const char sig[4] = "PCMP";
11         static const char oem[8] = "COREBOOT";
12         static const char productid[12] = "SE7520JR20  ";
13         struct mp_config_table *mc;
14         unsigned char bus_num;
15         unsigned char bus_isa;
16         unsigned char bus_pxhd_1;
17         unsigned char bus_pxhd_2;
18         unsigned char bus_pxhd_3 = 0;
19         unsigned char bus_pxhd_4 = 0;
20         unsigned char bus_pxhd_x = 0;
21         unsigned char bus_ich5r_1;
22         unsigned int bus_pxhd_id;
23
24         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
25         memset(mc, 0, sizeof(*mc));
26
27         memcpy(mc->mpc_signature, sig, sizeof(sig));
28         mc->mpc_length = sizeof(*mc); /* initially just the header */
29         mc->mpc_spec = 0x04;
30         mc->mpc_checksum = 0; /* not yet computed */
31         memcpy(mc->mpc_oem, oem, sizeof(oem));
32         memcpy(mc->mpc_productid, productid, sizeof(productid));
33         mc->mpc_oemptr = 0;
34         mc->mpc_oemsize = 0;
35         mc->mpc_entry_count = 0; /* No entries yet... */
36         mc->mpc_lapic = LAPIC_ADDR;
37         mc->mpe_length = 0;
38         mc->mpe_checksum = 0;
39         mc->reserved = 0;
40
41         smp_write_processors(mc);
42
43         {
44                 device_t dev;
45
46                 /* ich5r */
47                 dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
48                 if (dev) {
49                         bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
50                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
51                         bus_isa++;
52                 }
53                 else {
54                         printk(BIOS_DEBUG, "ERROR - could not find PCI 0:1f.0, using defaults\n");
55
56                         bus_ich5r_1 = 4;
57                         bus_isa = 5;
58                 }
59                 /* pxhd-1 */
60                 dev = dev_find_slot(1, PCI_DEVFN(0x0,0));
61                 if (dev) {
62                         bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
63
64                 }
65                 else {
66                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:00.1, using defaults\n");
67
68                         bus_pxhd_1 = 2;
69                 }
70                 /* pxhd-2 */
71                 dev = dev_find_slot(1, PCI_DEVFN(0x00,2));
72                 if (dev) {
73                         bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
74
75                 }
76                 else {
77                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n");
78
79                         bus_pxhd_2 = 3;
80                 }
81                 /* test for active riser with 2nd pxh device */
82                 dev = dev_find_slot(0, PCI_DEVFN(0x06,0));
83                 if (dev) {
84                         bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
85                         if(bus_pxhd_id == 0x35998086) {
86                                 bus_pxhd_x = pci_read_config8(dev, PCI_SECONDARY_BUS);
87                                 /* pxhd-3 */
88                                 dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x0,0));
89                                 if (dev) {
90                                         bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
91                                         if(bus_pxhd_id == 0x03298086) {
92                                             bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
93                                         }
94                                 }
95                                 /* pxhd-4 */
96                                 dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,2));
97                                 if (dev) {
98                                         bus_pxhd_id = pci_read_config32(dev, PCI_VENDOR_ID);
99                                         if(bus_pxhd_id == 0x032a8086) {
100                                             bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
101                                         }
102                                 }
103                         }
104                 }
105         }
106
107         /* define bus and isa numbers */
108         for(bus_num = 0; bus_num < bus_isa; bus_num++) {
109                 smp_write_bus(mc, bus_num, "PCI   ");
110         }
111         smp_write_bus(mc, bus_isa, "ISA   ");
112
113         /* IOAPIC handling */
114
115         smp_write_ioapic(mc, 8, 0x20, IO_APIC_ADDR);
116         {
117                 struct resource *res;
118                 device_t dev;
119                 /* pxhd apic 3 */
120                 dev = dev_find_slot(1, PCI_DEVFN(0x00,1));
121                 if (dev) {
122                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
123                         if (res) {
124                                 smp_write_ioapic(mc, 0x09, 0x20, res->base);
125                         }
126                 }
127                 else {
128                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 1:00.1\n");
129                 }
130                 /* pxhd apic 4 */
131                 dev = dev_find_slot(1, PCI_DEVFN(0x00,3));
132                 if (dev) {
133                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
134                         if (res) {
135                                 smp_write_ioapic(mc, 0x0a, 0x20, res->base);
136                         }
137                 }
138                 else {
139                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 1:00.3\n");
140                 }
141
142                 /* pxhd apic 5 */
143                 if(bus_pxhd_3) { /* Active riser pxhd */
144                         dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,1));
145                         if (dev) {
146                                 res = find_resource(dev, PCI_BASE_ADDRESS_0);
147                                 if (res) {
148                                         smp_write_ioapic(mc, 0x0b, 0x20, res->base);
149                                 }
150                         }
151                         else {
152                                 printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI %d:00.1\n",bus_pxhd_x);
153                         }
154                 }
155                 /* pxhd apic 6 */
156                 if(bus_pxhd_4) { /* active riser pxhd */
157                         dev = dev_find_slot(bus_pxhd_x, PCI_DEVFN(0x00,3));
158                         if (dev) {
159                                 res = find_resource(dev, PCI_BASE_ADDRESS_0);
160                                 if (res) {
161                                         smp_write_ioapic(mc, 0x0c, 0x20, res->base);
162                                 }
163                         }
164                         else {
165                                 printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI %d:00.3\n",bus_pxhd_x);
166                         }
167                 }
168         }
169
170         mptable_add_isa_interrupts(mc, bus_isa, 0x8, 0);
171
172         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
173                 bus_isa, 0x0a, 0x08, 0x10);
174         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
175                 bus_isa, 0x0b, 0x08, 0x11);
176         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
177                 bus_isa, 0x0a, 0x08, 0x10);
178         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
179                 bus_isa, 0x07, 0x08, 0x13);
180         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
181                 bus_isa, 0x0b, 0x08, 0x12);
182         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
183                 bus_isa, 0x05, 0x08, 0x17);
184         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
185                 bus_isa, 0x0b, 0x08, 0x12);
186         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
187                 bus_isa, 0x07, 0x08, 0x13);
188         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
189                 bus_isa, 0x0b, 0x08, 0x11);
190         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
191                 bus_isa, 0x0a, 0x08, 0x10);
192
193         /* Standard local interrupt assignments */
194         smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
195                 bus_isa, 0x00, MP_APIC_ALL, 0x00);
196         smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
197                 bus_isa, 0x00, MP_APIC_ALL, 0x01);
198
199         /* FIXME verify I have the irqs handled for all of the risers */
200
201         /* 2:3.0 PCI Slot 1 */
202         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
203                 bus_pxhd_1, (3<<2)|0, 0x9, 0x0);
204         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
205                 bus_pxhd_1, (3<<2)|1, 0x9, 0x3);
206         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
207                 bus_pxhd_1, (3<<2)|2, 0x9, 0x5);
208         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
209                 bus_pxhd_1, (3<<2)|3, 0x9, 0x4);
210
211
212         /* 3:7.0 PCI Slot 2 */
213         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
214                 bus_pxhd_2, (7<<2)|0, 0xa, 0x4);
215         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
216                 bus_pxhd_2, (7<<2)|1, 0xa, 0x3);
217         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
218                 bus_pxhd_2, (7<<2)|2, 0xa, 0x2);
219         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
220                 bus_pxhd_2, (7<<2)|3, 0xa, 0x1);
221
222         /* PCI Slot 3 (if active riser) */
223         if(bus_pxhd_3) {
224                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
225                         bus_pxhd_3, (1<<2)|0, 0xb, 0x0);
226         }
227
228         /* PCI Slot 4 (if active riser) */
229         if(bus_pxhd_4) {
230                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
231                         bus_pxhd_4, (1<<2)|0, 0xc, 0x0);
232         }
233
234         /* Onboard SCSI 0 */
235         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
236                 bus_pxhd_1, (5<<2)|0, 0x9, 0x2);
237
238         /* Onboard SCSI 1 */
239         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
240                 bus_pxhd_1, (5<<2)|1, 0x9, 0x1);
241
242         /* Onboard NIC 0 */
243         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
244                 bus_pxhd_2, (4<<2)|0, 0xa, 0x6);
245
246         /* Onboard NIC 1 */
247         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
248                 bus_pxhd_2, (4<<2)|1, 0xa, 0x7);
249
250         /* Onboard VGA */
251         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
252                  bus_ich5r_1, (12<<2)|0, 0x8, 0x11);
253
254         /* There is no extension information... */
255
256         /* Compute the checksums */
257         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
258
259         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
260         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
261                 mc, smp_next_mpe_entry(mc));
262         return smp_next_mpe_entry(mc);
263 }
264
265 unsigned long write_smp_table(unsigned long addr)
266 {
267         void *v;
268         v = smp_write_floating_table(addr);
269         return (unsigned long)smp_write_config_table(v);
270 }
271