9279b8485d5f553cc0081a8b0255140c8e3e1500
[coreboot.git] / src / mainboard / intel / xe7501devkit / 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 <assert.h>
8 #include "bus.h"
9 #include "ioapic.h"
10
11 // Generate MP-table IRQ numbers for PCI devices.
12 #define INT_A   0
13 #define INT_B   1
14 #define INT_C   2
15 #define INT_D   3
16 #define PCI_IRQ(dev, intLine)   (((dev)<<2) | intLine)
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, IO_APIC_ADDR);  // 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_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE |MP_IRQ_POLARITY_HIGH,     PCI_BUS_CHIPSET,        0,                                      MP_APIC_ALL,                     0);
77         smp_write_lintsrc(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         mptable_add_isa_interrupts(mc, SUPERIO_BUS, IOAPIC_ICH3, 0);
130 }
131
132 static void *smp_write_config_table(void* v)
133 {
134         struct mp_config_table *mc;
135
136         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
137
138         mptable_init(mc, "XE7501DEVKIT", LAPIC_ADDR);
139
140         smp_write_processors(mc);
141
142         xe7501devkit_register_buses(mc);
143         xe7501devkit_register_ioapics(mc);
144         xe7501devkit_register_interrupts(mc);
145
146         /* Compute the checksums */
147         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
148         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
149         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n", mc, smp_next_mpe_entry(mc));
150
151         return smp_next_mpe_entry(mc);
152 }
153
154 unsigned long write_smp_table(unsigned long addr)
155 {
156         void *v;
157         v = smp_write_floating_table(addr);
158         return (unsigned long)smp_write_config_table(v);
159 }