eric patch
[coreboot.git] / src / mainboard / arima / hdama / 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
7 static unsigned node_link_to_bus(unsigned node, unsigned link)
8 {
9         device_t dev;
10         unsigned reg;
11
12         dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
13         if (!dev) {
14                 return 0;
15         }
16         for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
17                 uint32_t config_map;
18                 unsigned dst_node;
19                 unsigned dst_link;
20                 unsigned bus_base;
21                 config_map = pci_read_config32(dev, reg);
22                 if ((config_map & 3) != 3) {
23                         continue;
24                 }
25                 dst_node = (config_map >> 4) & 7;
26                 dst_link = (config_map >> 8) & 3;
27                 bus_base = (config_map >> 16) & 0xff;
28 #if 0                           
29                 printk_debug("node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
30                         dst_node, dst_link, bus_base,
31                         reg, config_map);
32 #endif
33                 if ((dst_node == node) && (dst_link == link)) 
34                 {
35                         return bus_base;
36                 }
37         }
38         return 0;
39 }
40
41 void *smp_write_config_table(void *v)
42 {
43         static const char sig[4] = "PCMP";
44         static const char oem[8] = "LNXI    ";
45         static const char productid[12] = "HDAMA       ";
46         struct mp_config_table *mc;
47         unsigned char bus_num;
48         unsigned char bus_isa;
49         unsigned char bus_chain_0;
50         unsigned char bus_8131_1;
51         unsigned char bus_8131_2;
52         unsigned char bus_8111_1;
53
54         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
55         memset(mc, 0, sizeof(*mc));
56
57         memcpy(mc->mpc_signature, sig, sizeof(sig));
58         mc->mpc_length = sizeof(*mc); /* initially just the header */
59         mc->mpc_spec = 0x04;
60         mc->mpc_checksum = 0; /* not yet computed */
61         memcpy(mc->mpc_oem, oem, sizeof(oem));
62         memcpy(mc->mpc_productid, productid, sizeof(productid));
63         mc->mpc_oemptr = 0;
64         mc->mpc_oemsize = 0;
65         mc->mpc_entry_count = 0; /* No entries yet... */
66         mc->mpc_lapic = LAPIC_ADDR;
67         mc->mpe_length = 0;
68         mc->mpe_checksum = 0;
69         mc->reserved = 0;
70
71         smp_write_processors(mc);
72
73         {
74                 device_t dev;
75
76                 /* HT chain 0 */
77                 bus_chain_0 = node_link_to_bus(0, 0);
78                 if (bus_chain_0 == 0) {
79                         printk_debug("ERROR - cound not find bus for node 0 chain 0, using defaults\n");
80                         bus_chain_0 = 1;
81                 }
82
83                 /* 8111 */
84                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
85                 if (dev) {
86                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
87                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
88                         bus_isa++;
89                 }
90                 else {
91                         printk_debug("ERROR - could not find PCI 1:03.0, using defaults\n");
92
93                         bus_8111_1 = 4;
94                         bus_isa = 5;
95                 }
96                 /* 8131-1 */
97                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
98                 if (dev) {
99                         bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
100
101                 }
102                 else {
103                         printk_debug("ERROR - could not find PCI 1:01.0, using defaults\n");
104
105                         bus_8131_1 = 2;
106                 }
107                 /* 8131-2 */
108                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
109                 if (dev) {
110                         bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
111
112                 }
113                 else {
114                         printk_debug("ERROR - could not find PCI 1:02.0, using defaults\n");
115
116                         bus_8131_2 = 3;
117                 }
118         }
119
120         /* define bus and isa numbers */
121         for(bus_num = 0; bus_num < bus_isa; bus_num++) {
122                 smp_write_bus(mc, bus_num, "PCI   ");
123         }
124         smp_write_bus(mc, bus_isa, "ISA   ");
125
126         /* IOAPIC handling */
127         smp_write_ioapic(mc, 2, 0x11, 0xfec00000);
128         {
129                 device_t dev;
130                 struct resource *res;
131                 /* 8131 apic 3 */
132                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,1));
133                 if (dev) {
134                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
135                         if (res) {
136                                 smp_write_ioapic(mc, 0x03, 0x11, res->base);
137                         }
138                 }
139                 /* 8131 apic 4 */
140                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,1));
141                 if (dev) {
142                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
143                         if (res) {
144                                 smp_write_ioapic(mc, 0x04, 0x11, res->base);
145                         }
146                 }
147         }
148
149         /* ISA backward compatibility interrupts  */
150         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
151                 bus_isa, 0x00, 0x02, 0x00);
152         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
153                 bus_isa, 0x01, 0x02, 0x01);
154         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
155                 bus_isa, 0x00, 0x02, 0x02);
156         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
157                 bus_isa, 0x03, 0x02, 0x03);
158         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
159                 bus_isa, 0x04, 0x02, 0x04);
160         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
161                 bus_isa, 0x05, 0x02, 0x05);
162         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
163                 bus_isa, 0x06, 0x02, 0x06);
164         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
165                 bus_isa, 0x07, 0x02, 0x07);
166         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
167                 bus_isa, 0x08, 0x02, 0x08);
168         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
169                 bus_isa, 0x09, 0x02, 0x09);
170         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
171                 bus_isa, 0x0a, 0x02, 0x0a);
172         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
173                 bus_isa, 0x0b, 0x02, 0x0b);
174         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
175                 bus_isa, 0x0c, 0x02, 0x0c);
176         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
177                 bus_isa, 0x0d, 0x02, 0x0d);
178         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
179                 bus_isa, 0x0e, 0x02, 0x0e);
180         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
181                 bus_isa, 0x0f, 0x02, 0x0f);
182
183         /* Standard local interrupt assignments */
184         smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
185                 bus_isa, 0x00, MP_APIC_ALL, 0x00);
186         smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
187                 bus_isa, 0x00, MP_APIC_ALL, 0x01);
188
189         /* PCI Ints:         Type    Trigger                Polarity                 Bus ID      PCIDEVNUM|IRQ  APIC ID PIN# */
190         /* On board nics */
191         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x03<<2)|0, 0x02, 0x13);
192         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x04<<2)|0, 0x02, 0x13);
193
194         /* PCI Slot 1 */
195         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|0, 0x02, 0x11);
196         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|1, 0x02, 0x12);
197         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|2, 0x02, 0x13);
198         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|3, 0x02, 0x10);
199
200         /* PCI Slot 2 */
201         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|0, 0x02, 0x12);
202         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|1, 0x02, 0x13);
203         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|2, 0x02, 0x10);
204         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|3, 0x02, 0x11);
205
206         /* PCI Slot 3 */
207         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|0, 0x02, 0x11);
208         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|1, 0x02, 0x12);
209         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|2, 0x02, 0x13);
210         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|3, 0x02, 0x10);
211
212         /* PCI Slot 4 */
213         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|0, 0x02, 0x12);
214         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|1, 0x02, 0x13);
215         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|2, 0x02, 0x10);
216         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|3, 0x02, 0x11);
217
218         /* PCI Slot 5 */
219 #warning "FIXME get the irqs right, it's just hacked to work for now"
220         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|0, 0x02, 0x11);
221         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|1, 0x02, 0x12);
222         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|2, 0x02, 0x13);
223         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|3, 0x02, 0x10);
224
225         /* PCI Slot 6 */
226 #warning "FIXME get the irqs right, it's just hacked to work for now"
227         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|0, 0x02, 0x10);
228         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|1, 0x02, 0x11);
229         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|2, 0x02, 0x12);
230         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|3, 0x02, 0x13);
231
232         /* There is no extension information... */
233
234         /* Compute the checksums */
235         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
236         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
237         printk_debug("Wrote the mp table end at: %p - %p\n",
238                 mc, smp_next_mpe_entry(mc));
239         return smp_next_mpe_entry(mc);
240 }
241
242 unsigned long write_smp_table(unsigned long addr)
243 {
244         void *v;
245         v = smp_write_floating_table(addr);
246         return (unsigned long)smp_write_config_table(v);
247 }
248