Since some people disapprove of white space cleanups mixed in regular commits
[coreboot.git] / src / mainboard / intel / xe7501devkit / 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 #include <assert.h>
7 #include "bus.h"
8 #include "ioapic.h"
9
10 // Generate MP-table IRQ numbers for PCI devices.
11 #define INT_A   0
12 #define INT_B   1
13 #define INT_C   2
14 #define INT_D   3
15 #define PCI_IRQ(dev, intLine)   (((dev)<<2) | intLine)
16
17
18 static void xe7501devkit_register_buses(struct mp_config_table *mc)
19 {
20         // Bus ID, Bus Type
21         smp_write_bus(mc, PCI_BUS_CHIPSET,      BUSTYPE_PCI);
22         smp_write_bus(mc, PCI_BUS_E7501_HI_B,   BUSTYPE_PCI);
23         smp_write_bus(mc, PCI_BUS_P64H2_2_B,    BUSTYPE_PCI);
24         smp_write_bus(mc, PCI_BUS_P64H2_2_A,    BUSTYPE_PCI);
25         smp_write_bus(mc, PCI_BUS_E7501_HI_D,   BUSTYPE_PCI);
26         smp_write_bus(mc, PCI_BUS_P64H2_1_B,    BUSTYPE_PCI);
27         smp_write_bus(mc, PCI_BUS_P64H2_1_A,    BUSTYPE_PCI);
28         smp_write_bus(mc, PCI_BUS_ICH3,         BUSTYPE_PCI);
29         smp_write_bus(mc, SUPERIO_BUS,          BUSTYPE_ISA);
30 }
31
32 static void xe7501devkit_register_ioapics(struct mp_config_table *mc)
33 {
34         device_t dev;
35         struct resource *res;
36
37         // TODO: Gack. This is REALLY ugly.
38
39         // Southbridge IOAPIC
40         smp_write_ioapic(mc, IOAPIC_ICH3, 0x20, 0xfec00000);    // APIC ID, Version, Address
41
42         // P64H2#2 Bus A IOAPIC
43         dev = dev_find_slot(PCI_BUS_E7501_HI_B, PCI_DEVFN(30, 0));
44         if (!dev)
45                 BUG();          // Config.lb error?
46         res = find_resource(dev, PCI_BASE_ADDRESS_0);
47         smp_write_ioapic(mc, IOAPIC_P64H2_2_BUS_A, P64H2_IOAPIC_VERSION, res->base);
48
49         // P64H2#2 Bus B IOAPIC
50         dev = dev_find_slot(PCI_BUS_E7501_HI_B, PCI_DEVFN(28, 0));
51         if (!dev)
52                 BUG();          // Config.lb error?
53         res = find_resource(dev, PCI_BASE_ADDRESS_0);
54         smp_write_ioapic(mc, IOAPIC_P64H2_2_BUS_B, P64H2_IOAPIC_VERSION, res->base);
55
56
57         // P64H2#1 Bus A IOAPIC
58         dev = dev_find_slot(PCI_BUS_E7501_HI_D, PCI_DEVFN(30, 0));
59         if (!dev)
60                 BUG();          // Config.lb error?
61         res = find_resource(dev, PCI_BASE_ADDRESS_0);
62         smp_write_ioapic(mc, IOAPIC_P64H2_1_BUS_A, P64H2_IOAPIC_VERSION, res->base);
63
64         // P64H2#1 Bus B IOAPIC
65         dev = dev_find_slot(PCI_BUS_E7501_HI_D, PCI_DEVFN(28, 0));
66         if (!dev)
67                 BUG();          // Config.lb error?
68         res = find_resource(dev, PCI_BASE_ADDRESS_0);
69         smp_write_ioapic(mc, IOAPIC_P64H2_1_BUS_B, P64H2_IOAPIC_VERSION, res->base);
70 }
71
72 static void xe7501devkit_register_interrupts(struct mp_config_table *mc)
73 {
74         // Chipset PCI bus
75         //                                       Type           Trigger | Polarity                                                      Bus ID                          IRQ                                     APIC ID                                 PIN#
76         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      PCI_BUS_CHIPSET,        0,                                      MP_APIC_ALL,                     0);
77         smp_write_intsrc(mc, mp_NMI,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      PCI_BUS_CHIPSET,        0,                                      MP_APIC_ALL,                     1);
78         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_CHIPSET,        PCI_IRQ(29, INT_A), IOAPIC_ICH3,                        16);    // USB 1.1 Controller #1
79         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_CHIPSET,        PCI_IRQ(31, INT_B),     IOAPIC_ICH3,                    17);    // SMBus
80         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_CHIPSET,        PCI_IRQ(29, INT_C), IOAPIC_ICH3,                        18);    // USB 1.1 Controller #3
81         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_CHIPSET,        PCI_IRQ(31, INT_C), IOAPIC_ICH3,                        18);    // IDE
82         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_CHIPSET,        PCI_IRQ(29, INT_D), IOAPIC_ICH3,                        19);    // USB 1.1 Controller #2
83
84         // P64H2#2 Bus B
85         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(1, INT_A),      IOAPIC_P64H2_2_BUS_B,    0);    // Slot 2A (J23)
86         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(1, INT_B),      IOAPIC_P64H2_2_BUS_B,    1);    // Slot 2A (J23)
87         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(1, INT_C),      IOAPIC_P64H2_2_BUS_B,    2);    // Slot 2A (J23)
88         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(1, INT_D),      IOAPIC_P64H2_2_BUS_B,    3);    // Slot 2A (J23)
89         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(2, INT_A),      IOAPIC_P64H2_2_BUS_B,    4);    // Slot 2B (J24)
90         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(2, INT_B),      IOAPIC_P64H2_2_BUS_B,    5);    // Slot 2B (J24)
91         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(2, INT_C),      IOAPIC_P64H2_2_BUS_B,    6);    // Slot 2B (J24)
92         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(2, INT_D),      IOAPIC_P64H2_2_BUS_B,    7);    // Slot 2B (J24)
93         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(3, INT_A),      IOAPIC_P64H2_2_BUS_B,    8);    // Slot 2C (J25)
94         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(3, INT_B),      IOAPIC_P64H2_2_BUS_B,    9);    // Slot 2C (J25)
95         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(3, INT_C),      IOAPIC_P64H2_2_BUS_B,   10);    // Slot 2C (J25)
96         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(3, INT_D),      IOAPIC_P64H2_2_BUS_B,   11);    // Slot 2C (J25)
97         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(4, INT_A),      IOAPIC_P64H2_2_BUS_B,   12);    // Slot 2D (J12)
98         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(4, INT_B),      IOAPIC_P64H2_2_BUS_B,   13);    // Slot 2D (J12)
99         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(4, INT_C),      IOAPIC_P64H2_2_BUS_B,   14);    // Slot 2D (J12)
100         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_B,      PCI_IRQ(4, INT_D),      IOAPIC_P64H2_2_BUS_B,   15);    // Slot 2D (J12)
101
102         // P64H2#2 Bus A
103         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_A,      PCI_IRQ(1, INT_A),      IOAPIC_P64H2_2_BUS_A,    0);    // SCSI
104         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_2_A,      PCI_IRQ(1, INT_B),      IOAPIC_P64H2_2_BUS_A,    1);    // SCSI
105
106         // P64H2#1 Bus B
107         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_B,      PCI_IRQ(1, INT_A),      IOAPIC_P64H2_1_BUS_B,    0);    // GB Ethernet
108         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_B,      PCI_IRQ(2, INT_A),      IOAPIC_P64H2_1_BUS_B,    4);    // Slot 1B (J21)
109         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_B,      PCI_IRQ(2, INT_B),      IOAPIC_P64H2_1_BUS_B,    5);    // Slot 1B (J21)
110         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_B,      PCI_IRQ(2, INT_C),      IOAPIC_P64H2_1_BUS_B,    6);    // Slot 1B (J21)
111         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_B,      PCI_IRQ(2, INT_D),      IOAPIC_P64H2_1_BUS_B,    7);    // Slot 1B (J21)
112
113         // P64H2#1 Bus A
114         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_A,      PCI_IRQ(1, INT_A),      IOAPIC_P64H2_1_BUS_A,    0);    // Slot 1A (J20)
115         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_A,      PCI_IRQ(1, INT_B),      IOAPIC_P64H2_1_BUS_A,    1);    // Slot 1A (J20)
116         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_A,      PCI_IRQ(1, INT_C),      IOAPIC_P64H2_1_BUS_A,    2);    // Slot 1A (J20)
117         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_P64H2_1_A,      PCI_IRQ(1, INT_D),      IOAPIC_P64H2_1_BUS_A,    3);    // Slot 1A (J20)
118
119         // ICH-3
120
121         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_ICH3,           PCI_IRQ(0, INT_A),      IOAPIC_ICH3,                    16);    // Video
122         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_ICH3,           PCI_IRQ(2, INT_A),      IOAPIC_ICH3,                    18);    // Debug slot (J11)
123         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_ICH3,           PCI_IRQ(2, INT_B),      IOAPIC_ICH3,                    19);    // Debug slot (J11)
124         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_ICH3,           PCI_IRQ(2, INT_C),      IOAPIC_ICH3,                    16);    // Debug slot (J11)
125         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,       PCI_BUS_ICH3,           PCI_IRQ(2, INT_D),      IOAPIC_ICH3,                    17);    // Debug slot (J11)
126
127         // TODO: Not sure how to handle BT_INTR# signals from the P64H2s. Do we even need to, in APIC mode?
128
129         // Super I/O (ISA interrupts)
130         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             0,                                     IOAPIC_ICH3,                     0);
131         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             1,                                     IOAPIC_ICH3,                     1);
132         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             0,                                     IOAPIC_ICH3,                     2);
133
134         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             3,                                     IOAPIC_ICH3,                     3);
135         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             4,                                     IOAPIC_ICH3,                     4);
136         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             6,                                     IOAPIC_ICH3,                     6);
137         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             8,                                     IOAPIC_ICH3,                     8);
138         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,             9,                                     IOAPIC_ICH3,                     9);
139         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,            12,                                     IOAPIC_ICH3,                    12);
140         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,            13,                                     IOAPIC_ICH3,                    13);
141         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,            14,                                     IOAPIC_ICH3,                    14);
142         smp_write_intsrc(mc, mp_INT,    MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,      SUPERIO_BUS,            15,                                     IOAPIC_ICH3,                    15);
143 }
144
145 static void *smp_write_config_table(void* v)
146 {
147         static const char sig[4] = MPC_SIGNATURE;
148         static const char oem[8] = "COREBOOT";
149         static const char productid[12] = "XE7501DEVKIT";
150         struct mp_config_table *mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
151         memset(mc, 0, sizeof(*mc));
152
153         memcpy(mc->mpc_signature, sig, sizeof(sig));
154         memcpy(mc->mpc_oem, oem, sizeof(oem));
155         memcpy(mc->mpc_productid, productid, sizeof(productid));
156
157         mc->mpc_length = sizeof(*mc);   // initially just the header
158         mc->mpc_spec = 0x04;            // Multiprocessing Spec V1.4
159         mc->mpc_lapic = LAPIC_ADDR;
160
161         smp_write_processors(mc);
162
163         xe7501devkit_register_buses(mc);
164         xe7501devkit_register_ioapics(mc);
165         xe7501devkit_register_interrupts(mc);
166
167         /* Compute the checksums */
168         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
169         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
170         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
171
172         return smp_next_mpe_entry(mc);
173 }
174
175 unsigned long write_smp_table(unsigned long addr)
176 {
177         void *v;
178         v = smp_write_floating_table(addr);
179         return (unsigned long)smp_write_config_table(v);
180 }