coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
mptable.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/device.h>
4 #include <console/console.h>
5 #include <arch/smp/mpspec.h>
6 #include <arch/ioapic.h>
7 
8 static void *smp_write_config_table(void *v)
9 {
10  struct mp_config_table *mc;
11  struct device *riser = NULL, *firewire = NULL;
12  int firewire_bus = 0, riser_bus = 0, isa_bus;
13 
14  mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
15 
16  mptable_init(mc);
17 
19 
20  firewire = dev_find_device(0x104c, 0x8023, 0);
21  if (firewire) {
22  firewire_bus = firewire->bus->secondary;
23  printk(BIOS_SPEW, "Firewire device is on bus %x\n",
24  firewire_bus);
25  }
26 
27  // If a riser card is used, this riser is detected on bus 4, so its secondary bus is the
28  // highest bus number on the pci bus.
29  riser = dev_find_device(0x3388, 0x0021, 0);
30  if (!riser)
31  riser = dev_find_device(0x3388, 0x0022, 0);
32  if (riser) {
33  riser_bus = riser->link_list->secondary;
34  printk(BIOS_SPEW, "Riser bus is %x\n", riser_bus);
35  }
36 
37  mptable_write_buses(mc, NULL, &isa_bus);
38 
39  /* I/O APICs: APIC ID Version State Address */
41 
42  /* Legacy Interrupts */
43 
44  /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
45  smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x0, ioapic_id, 0x0);
46  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x1, ioapic_id, 0x1);
47  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x0, ioapic_id, 0x2);
48  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x3, ioapic_id, 0x3);
49  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x4, ioapic_id, 0x4);
50  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE | MP_IRQ_POLARITY_HIGH, isa_bus, 0x8, ioapic_id, 0x8);
51  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0x9, ioapic_id, 0x9);
52  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xa, ioapic_id, 0xa);
53  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xb, ioapic_id, 0xb);
54  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xc, ioapic_id, 0xc);
55  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xd, ioapic_id, 0xd);
56  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xe, ioapic_id, 0xe);
57  smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT | MP_IRQ_POLARITY_DEFAULT, isa_bus, 0xf, ioapic_id, 0xf);
58 
59  /* Builtin devices on Bus 0 */
60  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x01, 0, ioapic_id, 0x10);
61  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x02, 0, ioapic_id, 0x10);
62  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1f, 1, ioapic_id, 0x13);
63  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1d, 0, ioapic_id, 0x17);
64  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1d, 1, ioapic_id, 0x13);
65  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1d, 2, ioapic_id, 0x12);
66  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1d, 3, ioapic_id, 0x10);
67  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1b, 0, ioapic_id, 0x10);
68  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1c, 0, ioapic_id, 0x10);
69  smp_write_pci_intsrc(mc, mp_INT, 0x0, 0x1c, 1, ioapic_id, 0x11);
70 
71  /* Internal PCI bus (Firewire, PCI slot) */
72  if (firewire) {
73  smp_write_pci_intsrc(mc, mp_INT, firewire_bus, 0x00, 0, ioapic_id, 0x10);
74  smp_write_pci_intsrc(mc, mp_INT, firewire_bus, 0x01, 0, ioapic_id, 0x14);
75  }
76 
77  if (riser) {
78  /* Old riser card */
79  // riser slot top 5:8.0
80  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x08, 0, ioapic_id, 0x14);
81  // riser slot middle 5:9.0
82  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x09, 0, ioapic_id, 0x15);
83  // riser slot bottom 5:a.0
84  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x0a, 0, ioapic_id, 0x16);
85 
86  /* New Riser Card */
87  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x0c, 0, ioapic_id, 0x14);
88  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x0d, 0, ioapic_id, 0x15);
89  smp_write_pci_intsrc(mc, mp_INT, riser_bus, 0x0e, 0, ioapic_id, 0x16);
90  }
91 
92  /* PCIe slot */
93  smp_write_pci_intsrc(mc, mp_INT, 0x1, 0x00, 0, ioapic_id, 0x10);
94  smp_write_pci_intsrc(mc, mp_INT, 0x1, 0x00, 1, ioapic_id, 0x11);
95 
96  /* Onboard Ethernet */
97  smp_write_pci_intsrc(mc, mp_INT, 0x2, 0x00, 0, ioapic_id, 0x10);
98 
99  /* Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
100  mptable_lintsrc(mc, isa_bus);
101 
102  /* Compute the checksums */
103  return mptable_finalize(mc);
104 }
105 
106 unsigned long write_smp_table(unsigned long addr)
107 {
108  void *v;
110  return (unsigned long)smp_write_config_table(v);
111 }
unsigned long write_smp_table(unsigned long addr)
Definition: mptable.c:48
#define VIO_APIC_VADDR
Definition: ioapic.h:7
static u32 addr
Definition: cirrus.c:14
#define printk(level,...)
Definition: stdlib.h:16
struct device * dev_find_device(u16 vendor, u16 device, struct device *from)
Find a device of a given vendor and type.
Definition: device_util.c:42
static void * smp_write_config_table(void *v)
Definition: mptable.c:8
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
#define MP_IRQ_TRIGGER_DEFAULT
Definition: mpspec.h:127
void * smp_write_floating_table(unsigned long addr, unsigned int virtualwire)
Definition: mpspec.c:84
@ mp_INT
Definition: mpspec.h:117
@ mp_ExtINT
Definition: mpspec.h:120
void smp_write_intsrc(struct mp_config_table *mc, u8 irqtype, u16 irqflag, u8 srcbus, u8 srcbusirq, u8 dstapic, u8 dstirq)
Definition: mpspec.c:237
#define MP_IRQ_POLARITY_HIGH
Definition: mpspec.h:124
void * mptable_finalize(struct mp_config_table *mc)
Definition: mpspec.c:504
void mptable_lintsrc(struct mp_config_table *mc, unsigned long bus_isa)
Definition: mpspec.c:418
void mptable_init(struct mp_config_table *mc)
Definition: mpspec.c:14
#define SMP_FLOATING_TABLE_LEN
Definition: mpspec.h:26
void smp_write_processors(struct mp_config_table *mc)
Definition: mpspec.c:146
#define MP_IRQ_POLARITY_DEFAULT
Definition: mpspec.h:123
u8 smp_write_ioapic_from_hw(struct mp_config_table *mc, void *apicaddr)
Definition: mpspec.c:224
#define MP_IRQ_TRIGGER_EDGE
Definition: mpspec.h:128
void mptable_write_buses(struct mp_config_table *mc, int *max_pci_bus, int *isa_bus)
Definition: mpspec.c:465
void smp_write_pci_intsrc(struct mp_config_table *mc, u8 irqtype, u8 srcbus, u8 dev, u8 pirq, u8 dstapic, u8 dstirq)
Definition: mpspec.c:264
#define NULL
Definition: stddef.h:19
uint8_t u8
Definition: stdint.h:45
uint16_t secondary
Definition: device.h:84
Definition: device.h:107
DEVTREE_CONST struct bus * link_list
Definition: device.h:139