1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <arch/ioapic.h>
4 #include <device/pci.h>
8 static void *smp_write_config_table(void *v)
10 struct mp_config_table *mc;
11 unsigned char bus_num;
12 unsigned char bus_isa;
13 unsigned char bus_8131_1;
14 unsigned char bus_8131_2;
15 unsigned char bus_8111_1;
17 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
19 mptable_init(mc, "DK8S2 ", LAPIC_ADDR);
21 smp_write_processors(mc);
27 dev = dev_find_slot(1, PCI_DEVFN(0x03,0));
29 bus_8111_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
30 bus_isa = pci_read_config8(dev, PCI_SUBORDINATE_BUS);
34 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:03.0, using defaults\n");
40 dev = dev_find_slot(1, PCI_DEVFN(0x01,0));
42 bus_8131_1 = pci_read_config8(dev, PCI_SECONDARY_BUS);
46 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:01.0, using defaults\n");
51 dev = dev_find_slot(1, PCI_DEVFN(0x02,0));
53 bus_8131_2 = pci_read_config8(dev, PCI_SECONDARY_BUS);
57 printk(BIOS_DEBUG, "ERROR - could not find PCI 1:02.0, using defaults\n");
63 /* define bus and isa numbers */
64 for(bus_num = 0; bus_num < bus_isa; bus_num++) {
65 smp_write_bus(mc, bus_num, "PCI ");
67 smp_write_bus(mc, bus_isa, "ISA ");
70 smp_write_ioapic(mc, 2, 0x11, IO_APIC_ADDR);
75 dev = dev_find_slot(1, PCI_DEVFN(0x01,1));
77 res = find_resource(dev, PCI_BASE_ADDRESS_0);
79 smp_write_ioapic(mc, 0x03, 0x11, res->base);
83 dev = dev_find_slot(1, PCI_DEVFN(0x02,1));
85 res = find_resource(dev, PCI_BASE_ADDRESS_0);
87 smp_write_ioapic(mc, 0x04, 0x11, res->base);
92 mptable_add_isa_interrupts(mc, bus_isa, 0x2, 0);
94 /* Standard local interrupt assignments */
95 smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
96 bus_isa, 0x00, MP_APIC_ALL, 0x00);
97 smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
98 bus_isa, 0x00, MP_APIC_ALL, 0x01);
102 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
103 bus_8131_2, (1<<2)|0, 0x02, 0x11);
104 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
105 bus_8131_2, (1<<2)|1, 0x02, 0x12);
106 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
107 bus_8131_2, (1<<2)|2, 0x02, 0x13);
108 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
109 bus_8131_2, (1<<2)|3, 0x02, 0x10);
112 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
113 bus_8131_2, (2<<2)|0, 0x02, 0x12);
114 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
115 bus_8131_2, (2<<2)|1, 0x02, 0x13);
116 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
117 bus_8131_2, (2<<2)|2, 0x02, 0x10);
118 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
119 bus_8131_2, (2<<2)|3, 0x02, 0x11);
122 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
123 bus_8131_1, (1<<2)|0, 0x02, 0x11);
124 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
125 bus_8131_1, (1<<2)|1, 0x02, 0x12);
126 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
127 bus_8131_1, (1<<2)|2, 0x02, 0x13);
128 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
129 bus_8131_1, (1<<2)|3, 0x02, 0x10);
132 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
133 bus_8131_1, (2<<2)|0, 0x02, 0x12);
134 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
135 bus_8131_1, (2<<2)|1, 0x02, 0x13);
136 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
137 bus_8131_1, (2<<2)|2, 0x02, 0x10);
138 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
139 bus_8131_1, (2<<2)|3, 0x02, 0x11);
142 // FIXME get the irqs right, it's just hacked to work for now
143 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
144 bus_8111_1, (5<<2)|0, 0x02, 0x11);
145 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
146 bus_8111_1, (5<<2)|1, 0x02, 0x12);
147 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
148 bus_8111_1, (5<<2)|2, 0x02, 0x13);
149 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
150 bus_8111_1, (5<<2)|3, 0x02, 0x10);
153 // FIXME get the irqs right, it's just hacked to work for now
154 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
155 bus_8111_1, (4<<2)|0, 0x02, 0x10);
156 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
157 bus_8111_1, (4<<2)|1, 0x02, 0x11);
158 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
159 bus_8111_1, (4<<2)|2, 0x02, 0x12);
160 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
161 bus_8111_1, (4<<2)|3, 0x02, 0x13);
164 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
165 bus_8131_1, (3<<2)|0, 0x02, 0x13);
166 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
167 bus_8131_1, (4<<2)|0, 0x02, 0x13);
169 /* There is no extension information... */
171 /* Compute the checksums */
172 mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
173 mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
174 printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
175 mc, smp_next_mpe_entry(mc));
176 return smp_next_mpe_entry(mc);
179 unsigned long write_smp_table(unsigned long addr)
182 v = smp_write_floating_table(addr);
183 return (unsigned long)smp_write_config_table(v);