Factor out common mptable code to mptable_init().
[coreboot.git] / src / mainboard / supermicro / x6dhr_ig / 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         struct mp_config_table *mc;
11         unsigned char bus_num;
12         unsigned char bus_isa;
13         unsigned char bus_pxhd_1;
14         unsigned char bus_pxhd_2;
15         unsigned char bus_pxhd_3;
16         unsigned char bus_pxhd_4;
17         unsigned char bus_ich5r_1;
18
19         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
20
21         mptable_init(mc, "X6DHR-iG    ", LAPIC_ADDR);
22
23         smp_write_processors(mc);
24
25         {
26                 device_t dev;
27
28                 /* ich5r */
29                 dev = dev_find_slot(0, PCI_DEVFN(0x1e,0));
30                 if (dev) {
31                         bus_ich5r_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
32                         bus_isa    = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
33                         bus_isa++;
34                 }
35                 else {
36                         printk(BIOS_DEBUG, "ERROR - could not find PCI 0:1f.0, using defaults\n");
37
38                         bus_ich5r_1 = 9;
39                         bus_isa = 10;
40                 }
41                 /* pxhd-1 */
42                 dev = dev_find_slot(2, PCI_DEVFN(0x0,0));
43                 if (dev) {
44                         bus_pxhd_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
45
46                 }
47                 else {
48                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:00.1, using defaults\n");
49
50                         bus_pxhd_1 = 3;
51                 }
52                 /* pxhd-2 */
53                 dev = dev_find_slot(2, PCI_DEVFN(0x00,2));
54                 if (dev) {
55                         bus_pxhd_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
56
57                 }
58                 else {
59                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n");
60
61                         bus_pxhd_2 = 4;
62                 }
63
64                 /* pxhd-3 */
65                 dev = dev_find_slot(5, PCI_DEVFN(0x0,0));
66                 if (dev) {
67                         bus_pxhd_3 = pci_read_config8(dev, PCI_SECONDARY_BUS);
68
69                 }
70                 else {
71                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:00.1, using defaults\n");
72
73                         bus_pxhd_3 = 6;
74                 }
75                 /* pxhd-4 */
76                 dev = dev_find_slot(5, PCI_DEVFN(0x00,2));
77                 if (dev) {
78                         bus_pxhd_4 = pci_read_config8(dev, PCI_SECONDARY_BUS);
79
80                 }
81                 else {
82                         printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n");
83
84                         bus_pxhd_4 = 7;
85                 }
86
87         }
88
89         /* define bus and isa numbers */
90         for(bus_num = 0; bus_num < bus_isa; bus_num++) {
91                 smp_write_bus(mc, bus_num, "PCI   ");
92         }
93         smp_write_bus(mc, bus_isa, "ISA   ");
94
95         /* IOAPIC handling */
96
97         smp_write_ioapic(mc, 2, 0x20, IO_APIC_ADDR);
98         {
99                 struct resource *res;
100                 device_t dev;
101                 /* pxhd apic 3 */
102                 dev = dev_find_slot(2, PCI_DEVFN(0x00,1));
103                 if (dev) {
104                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
105                         if (res) {
106                                 smp_write_ioapic(mc, 0x03, 0x20, res->base);
107                         }
108                 }
109                 else {
110                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 2:00.1\n");
111                 }
112                 /* pxhd apic 4 */
113                 dev = dev_find_slot(2, PCI_DEVFN(0x00,3));
114                 if (dev) {
115                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
116                         if (res) {
117                                 smp_write_ioapic(mc, 0x04, 0x20, res->base);
118                         }
119                 }
120                 else {
121                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 2:00.3\n");
122                 }
123                 /* pxhd apic 5 */
124                 dev = dev_find_slot(5, PCI_DEVFN(0x00,1));
125                 if (dev) {
126                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
127                         if (res) {
128                                 smp_write_ioapic(mc, 0x05, 0x20, res->base);
129                         }
130                 }
131                 else {
132                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 5:00.1\n");
133                 }
134                 /* pxhd apic 8 */
135                 dev = dev_find_slot(5, PCI_DEVFN(0x00,3));
136                 if (dev) {
137                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
138                         if (res) {
139                                 smp_write_ioapic(mc, 0x08, 0x20, res->base);
140                         }
141                 }
142                 else {
143                         printk(BIOS_DEBUG, "ERROR - could not find IOAPIC PCI 5:00.3\n");
144                 }
145         }
146
147         mptable_add_isa_interrupts(mc, bus_isa, 0x2, 0);
148
149         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
150                 0x00, 0x74, 0x02, 0x10);
151         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
152                 0x00, 0x76, 0x02, 0x12);
153         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
154                 0x00, 0x77, 0x02, 0x17);
155         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
156                 0x00, 0x75, 0x02, 0x13);
157         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
158                 0x00, 0x74, 0x02, 0x10);
159         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
160                 0x00, 0x7c, 0x02, 0x12);
161         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
162                 0x00, 0x7d, 0x02, 0x11);
163         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
164                 bus_pxhd_2, 0x08, 0x04, 0x06);
165         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
166                 bus_pxhd_2, 0x09, 0x04, 0x07);
167         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
168                 bus_pxhd_3, 0x08, 0x05, 0x00);
169         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
170                 bus_pxhd_4, 0x08, 0x08, 0x00);
171         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
172                 (bus_isa - 1), 0x04, 0x02, 0x10);
173
174         /* Standard local interrupt assignments */
175         smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
176                 bus_isa, 0x00, MP_APIC_ALL, 0x00);
177         smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH,
178                 bus_isa, 0x00, MP_APIC_ALL, 0x01);
179
180         /* There is no extension information... */
181
182         /* Compute the checksums */
183         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
184
185         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
186         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
187                 mc, smp_next_mpe_entry(mc));
188         return smp_next_mpe_entry(mc);
189 }
190
191 unsigned long write_smp_table(unsigned long addr)
192 {
193         void *v;
194         v = smp_write_floating_table(addr);
195         return (unsigned long)smp_write_config_table(v);
196 }
197