blob: 54faae5c3fdacf4b61e7f7393db5fff2eedb5959 [file] [log] [blame]
Angel Ponsa21dff62020-04-03 01:22:24 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauer36a22682008-10-29 04:52:57 +00002
Stefan Reinauer36a22682008-10-29 04:52:57 +00003#include <device/device.h>
Stefan Reinauer36a22682008-10-29 04:52:57 +00004#include <arch/smp/mpspec.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +00005#include <arch/ioapic.h>
Stefan Reinauer36a22682008-10-29 04:52:57 +00006
Stefan Reinauerde3206a2010-02-22 06:09:43 +00007static void *smp_write_config_table(void *v)
Stefan Reinauer36a22682008-10-29 04:52:57 +00008{
Elyes HAOUAS8da96e52016-09-22 21:20:54 +02009 struct mp_config_table *mc;
Stefan Reinauer762a2302010-01-19 21:15:37 +000010 struct device *riser = NULL, *firewire = NULL;
Patrick Georgiab272662010-06-25 13:43:22 +000011 int firewire_bus = 0, riser_bus = 0, isa_bus;
Stefan Reinauerde3206a2010-02-22 06:09:43 +000012 int ioapic_id;
Stefan Reinauer36a22682008-10-29 04:52:57 +000013
Elyes HAOUAS8da96e52016-09-22 21:20:54 +020014 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Stefan Reinauer36a22682008-10-29 04:52:57 +000015
Kyösti Mälkkidea42e02021-05-31 20:26:16 +030016 mptable_init(mc);
Stefan Reinauer36a22682008-10-29 04:52:57 +000017
Elyes HAOUAS8da96e52016-09-22 21:20:54 +020018 smp_write_processors(mc);
Stefan Reinauer36a22682008-10-29 04:52:57 +000019
Stefan Reinauer762a2302010-01-19 21:15:37 +000020 firewire = dev_find_device(0x104c, 0x8023, 0);
21 if (firewire) {
22 firewire_bus = firewire->bus->secondary;
Stefan Reinauer762a2302010-01-19 21:15:37 +000023 }
24
Elyes HAOUASf10b5ff2016-10-06 19:49:55 +020025 /* If a riser card is used, this riser is detected on bus 4, so its secondary bus is the */
26 /* highest bus number on the pci bus. */
Stefan Reinauer762a2302010-01-19 21:15:37 +000027 riser = dev_find_device(0x3388, 0x0021, 0);
28 if (!riser)
29 riser = dev_find_device(0x3388, 0x0022, 0);
30 if (riser) {
Myles Watson894a3472010-06-09 22:41:35 +000031 riser_bus = riser->link_list->secondary;
Stefan Reinauer762a2302010-01-19 21:15:37 +000032 }
Stefan Reinauer36a22682008-10-29 04:52:57 +000033
Patrick Georgiab272662010-06-25 13:43:22 +000034 mptable_write_buses(mc, NULL, &isa_bus);
Stefan Reinauer36a22682008-10-29 04:52:57 +000035
36 /* I/O APICs: APIC ID Version State Address */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000037 ioapic_id = 2;
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080038 smp_write_ioapic(mc, ioapic_id, 0x20, VIO_APIC_VADDR);
Stefan Reinauer36a22682008-10-29 04:52:57 +000039
40 /* Legacy Interrupts */
Patrick Georgic5b87c82010-05-20 15:28:19 +000041 mptable_add_isa_interrupts(mc, isa_bus, ioapic_id, 0);
Stefan Reinauer36a22682008-10-29 04:52:57 +000042
43 /* Builtin devices on Bus 0 */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000044 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x4, ioapic_id, 0x10);
45 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x8, ioapic_id, 0x10);
46 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x7d, ioapic_id, 0x13);
47 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x74, ioapic_id, 0x17);
48 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x75, ioapic_id, 0x13);
49 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x76, ioapic_id, 0x12);
50 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x77, ioapic_id, 0x10);
51 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x6c, ioapic_id, 0x10);
52 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x70, ioapic_id, 0x10);
53 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x71, ioapic_id, 0x11);
Stefan Reinauer36a22682008-10-29 04:52:57 +000054
Stefan Reinauerde3206a2010-02-22 06:09:43 +000055 /* Internal PCI bus (Firewire, PCI slot) */
Stefan Reinauer762a2302010-01-19 21:15:37 +000056 if (firewire) {
Stefan Reinauerde3206a2010-02-22 06:09:43 +000057 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, firewire_bus, 0x0, ioapic_id, 0x10);
58 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, firewire_bus, 0x4, ioapic_id, 0x14);
Stefan Reinauer762a2302010-01-19 21:15:37 +000059 }
Stefan Reinauer36a22682008-10-29 04:52:57 +000060
Stefan Reinauer762a2302010-01-19 21:15:37 +000061 if (riser) {
62 /* Old riser card */
Elyes HAOUASf10b5ff2016-10-06 19:49:55 +020063 /* riser slot top 5:8.0 */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000064 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x20, ioapic_id, 0x14);
Elyes HAOUASf10b5ff2016-10-06 19:49:55 +020065 /* riser slot middle 5:9.0 */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000066 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x24, ioapic_id, 0x15);
Elyes HAOUASf10b5ff2016-10-06 19:49:55 +020067 /* riser slot bottom 5:a.0 */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000068 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x28, ioapic_id, 0x16);
Stefan Reinauer36a22682008-10-29 04:52:57 +000069
Stefan Reinauer762a2302010-01-19 21:15:37 +000070 /* New Riser Card */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000071 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x30, ioapic_id, 0x14);
72 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x34, ioapic_id, 0x15);
73 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, riser_bus, 0x38, ioapic_id, 0x16);
Stefan Reinauer762a2302010-01-19 21:15:37 +000074 }
Stefan Reinauere1025d02009-03-11 15:20:36 +000075
Stefan Reinauerde3206a2010-02-22 06:09:43 +000076 /* PCIe slot */
77 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, 0x0, ioapic_id, 0x10);
78 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x1, 0x1, ioapic_id, 0x11);
79
Stefan Reinauer36a22682008-10-29 04:52:57 +000080 /* Onboard Ethernet */
Stefan Reinauerde3206a2010-02-22 06:09:43 +000081 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x2, 0x0, ioapic_id, 0x10);
Stefan Reinauer36a22682008-10-29 04:52:57 +000082
83 /* Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
Patrick Georgi6eb7a532011-10-07 21:42:52 +020084 mptable_lintsrc(mc, isa_bus);
Stefan Reinauer36a22682008-10-29 04:52:57 +000085
86 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +020087 return mptable_finalize(mc);
Stefan Reinauer36a22682008-10-29 04:52:57 +000088}
89
90unsigned long write_smp_table(unsigned long addr)
91{
92 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +020093 v = smp_write_floating_table(addr, 1);
Stefan Reinauer36a22682008-10-29 04:52:57 +000094 return (unsigned long)smp_write_config_table(v);
95}