Unify Local APIC address definitions
[coreboot.git] / src / mainboard / arima / hdama / 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 #include <cpu/x86/lapic.h>
8 #include <arch/cpu.h>
9 #include <arch/io.h>
10
11 #define HT_INIT_CONTROL 0x6c
12 #define HTIC_BIOSR_Detect  (1<<5)
13
14 static unsigned node_link_to_bus(unsigned node, unsigned link)
15 {
16         device_t dev;
17         unsigned reg;
18
19         dev = dev_find_slot(0, PCI_DEVFN(0x18, 1));
20         if (!dev) {
21                 return 0xff;
22         }
23         for(reg = 0xE0; reg < 0xF0; reg += 0x04) {
24                 uint32_t config_map;
25                 unsigned dst_node;
26                 unsigned dst_link;
27                 unsigned bus_base;
28                 config_map = pci_read_config32(dev, reg);
29                 if ((config_map & 3) != 3) {
30                         continue;
31                 }
32                 dst_node = (config_map >> 4) & 7;
33                 dst_link = (config_map >> 8) & 3;
34                 bus_base = (config_map >> 16) & 0xff;
35 #if 0
36                 printk(BIOS_DEBUG, "node.link=bus: %d.%d=%d 0x%2x->0x%08x\n",
37                         dst_node, dst_link, bus_base,
38                         reg, config_map);
39 #endif
40                 if ((dst_node == node) && (dst_link == link))
41                 {
42                         return bus_base;
43                 }
44         }
45         return 0xff;
46 }
47
48 static unsigned max_apicid(void)
49 {
50         unsigned max;
51         device_t dev;
52         max = 0;
53         for(dev = all_devices; dev; dev = dev->next) {
54                 if (dev->path.type != DEVICE_PATH_APIC)
55                         continue;
56                 if (dev->path.apic.apic_id > max) {
57                         max = dev->path.apic.apic_id;
58                 }
59         }
60         return max;
61 }
62
63 static void *smp_write_config_table(void *v)
64 {
65         struct mp_config_table *mc;
66         int bus_isa;
67         unsigned char bus_chain_0;
68         unsigned char bus_8131_1;
69         unsigned char bus_8131_2;
70         unsigned char bus_8111_1;
71         unsigned apicid_base;
72         unsigned apicid_8111;
73         unsigned apicid_8131_1;
74         unsigned apicid_8131_2;
75
76         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
77
78         mptable_init(mc, LOCAL_APIC_ADDR);
79
80         smp_write_processors(mc);
81
82         apicid_base = max_apicid() + 1;
83         apicid_8111 = apicid_base;
84         apicid_8131_1 = apicid_base + 1;
85         apicid_8131_2 = apicid_base + 2;
86         {
87                 device_t dev;
88
89                 /* HT chain 0 */
90                 bus_chain_0 = node_link_to_bus(0, 0);
91                 if (bus_chain_0 == 0xff) {
92                         printk(BIOS_DEBUG, "ERROR - cound not find bus for node 0 chain 0, using defaults\n");
93                         bus_chain_0 = 0;
94                 }
95
96                 /* 8111 */
97                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x03,0));
98                 if (dev) {
99                         bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
100                 }
101                 else {
102                         printk(BIOS_DEBUG, "ERROR - could not find PCI %02x:03.0, using defaults\n", bus_chain_0);
103                         bus_8111_1 = 4;
104                 }
105                 /* 8131-1 */
106                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
107                 if (dev) {
108                         bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
109                 }
110                 else {
111                         printk(BIOS_DEBUG, "ERROR - could not find PCI %02x:01.0, using defaults\n", bus_chain_0);
112                         bus_8131_1 = 2;
113                 }
114                 /* 8131-2 */
115                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
116                 if (dev) {
117                         bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
118                 }
119                 else {
120                         printk(BIOS_DEBUG, "ERROR - could not find PCI %02x:02.0, using defaults\n", bus_chain_0);
121                         bus_8131_2 = 3;
122                 }
123         }
124
125         mptable_write_buses(mc, NULL, &bus_isa);
126
127         /* IOAPIC handling */
128         smp_write_ioapic(mc, apicid_8111, 0x11, IO_APIC_ADDR);
129         {
130                 device_t dev;
131                 struct resource *res;
132                 /* 8131 apic 3 */
133                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,1));
134                 if (dev) {
135                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
136                         if (res) {
137                                 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
138                         }
139                 }
140                 /* 8131 apic 4 */
141                 dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,1));
142                 if (dev) {
143                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
144                         if (res) {
145                                 smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
146                         }
147                 }
148         }
149
150         mptable_add_isa_interrupts(mc, bus_isa, apicid_8111, 0);
151
152         /* Standard local interrupt assignments */
153         mptable_lintsrc(mc, bus_isa);
154
155         /* PCI Ints:         Type    Trigger                Polarity                 Bus ID      PCIDEVNUM|IRQ  APIC ID PIN# */
156         /* On board nics */
157         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x03<<2)|0, apicid_8111, 0x13);
158         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x04<<2)|0, apicid_8111, 0x13);
159         /* On board SATA */
160         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x05<<2)|0, apicid_8111, 0x11);
161
162         /* PCI Slot 1 */
163         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|0, apicid_8111, 0x11);
164         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|1, apicid_8111, 0x12);
165         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|2, apicid_8111, 0x13);
166         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x01<<2)|3, apicid_8111, 0x10);
167
168         /* PCI Slot 2 */
169         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|0, apicid_8111, 0x12);
170         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|1, apicid_8111, 0x13);
171         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|2, apicid_8111, 0x10);
172         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_2, (0x02<<2)|3, apicid_8111, 0x11);
173
174         /* PCI Slot 3 */
175         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|0, apicid_8111, 0x11);
176         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|1, apicid_8111, 0x12);
177         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|2, apicid_8111, 0x13);
178         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x01<<2)|3, apicid_8111, 0x10);
179
180         /* PCI Slot 4 */
181         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|0, apicid_8111, 0x12);
182         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|1, apicid_8111, 0x13);
183         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|2, apicid_8111, 0x10);
184         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8131_1, (0x02<<2)|3, apicid_8111, 0x11);
185
186         /* PCI Slot 5 */
187         // FIXME get the irqs right, it's just hacked to work for now
188         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|0, apicid_8111, 0x11);
189         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|1, apicid_8111, 0x12);
190         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|2, apicid_8111, 0x13);
191         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x05<<2)|3, apicid_8111, 0x10);
192
193         /* PCI Slot 6 */
194         // FIXME get the irqs right, it's just hacked to work for now
195         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|0, apicid_8111, 0x10);
196         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|1, apicid_8111, 0x11);
197         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|2, apicid_8111, 0x12);
198         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, bus_8111_1, (0x04<<2)|3, apicid_8111, 0x13);
199
200         /* There is no extension information... */
201
202         /* Compute the checksums */
203         return mptable_finalize(mc);
204 }
205
206 static void reboot_if_hotswap(void)
207 {
208         /* Hack patch work around for hot swap enable 33mhz problem */
209         device_t dev;
210         uint32_t data;
211         unsigned long htic;
212         int reset;
213
214         unsigned bus_chain_0 = node_link_to_bus(0, 0);
215
216         reset = 0;
217         printk(BIOS_DEBUG, "Looking for bad PCIX MHz input\n");
218         dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x02,0));
219         if (!dev)
220                 printk(BIOS_DEBUG, "Couldn't find %02x:02.0 \n", bus_chain_0);
221         else {
222                 data = pci_read_config32(dev, 0xa0);
223                 if(!(((data>>16)&0x03)==0x03)) {
224                         reset=1;
225                         printk(BIOS_DEBUG, "Bad PCIX MHz - Reset\n");
226                 }
227         }
228         printk(BIOS_DEBUG, "Looking for bad Hot Swap Enable\n");
229         dev = dev_find_slot(bus_chain_0, PCI_DEVFN(0x01,0));
230         if (!dev)
231                 printk(BIOS_DEBUG, "Couldn't find %02x:01.0 \n", bus_chain_0);
232         else {
233                 data = pci_read_config32(dev, 0x48);
234                 if(data & 0x0c) {
235                         reset=1;
236                         printk(BIOS_DEBUG, "Bad Hot Swap start - Reset\n");
237                 }
238         }
239         if(reset) {
240                 /* enable cf9 */
241                 dev = dev_find_slot(node_link_to_bus(0, 0), PCI_DEVFN(0x04,3));
242                 pci_write_config8(dev, 0x41, 0xf1);
243                 /* reset */
244                 dev = dev_find_slot(0, PCI_DEVFN(0x18,0));
245                 htic = pci_read_config32(dev, HT_INIT_CONTROL);
246                 htic &= ~HTIC_BIOSR_Detect;
247                 pci_write_config32(dev, HT_INIT_CONTROL, htic);
248                 outb(0x0e, 0x0cf9);
249         }
250         else {
251                 printk(BIOS_DEBUG, "OK 133MHz & Hot Swap is off\n");
252         }
253 }
254
255 unsigned long write_smp_table(unsigned long addr)
256 {
257         void *v;
258         reboot_if_hotswap();
259
260         v = smp_write_floating_table(addr, 0);
261         return (unsigned long)smp_write_config_table(v);
262 }
263