coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
ioapic.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <arch/ioapic.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ids.h>
7 #include <device/pci_ops.h>
8 #include <assert.h>
9 #include "82870.h"
10 
11 static int num_p64h2_ioapics = 0;
12 
13 static void p64h2_ioapic_enable(struct device *dev)
14 {
15  /* We have to enable MEM and Bus Master for IOAPIC */
17 
18  pci_write_config16(dev, PCI_COMMAND, command);
19 }
20 
21 /**
22  * Configure one of the IOAPICs in a P64H2.
23  *
24  * Note that a PCI bus scan will detect both IOAPICs, so this function
25  * will be called twice for each P64H2 in the system.
26  *
27  * @param dev PCI bus/device/function of P64H2 IOAPIC.
28  * NOTE: There are two IOAPICs per P64H2, at D28:F0 and D30:F0.
29  */
30 static void p64h2_ioapic_init(struct device *dev)
31 {
32  uint32_t memoryBase;
33  int apic_index, apic_id;
34 
35  apic_index = num_p64h2_ioapics;
37 
38  // A note on IOAPIC addresses:
39  // 0 and 1 are used for the local APICs of the dual virtual
40  // (hyper-threaded) CPUs of physical CPU 0 (devicetree.cb).
41  // 6 and 7 are used for the local APICs of the dual virtual
42  // (hyper-threaded) CPUs of physical CPU 1 (devicetree.cb).
43  // 2 is used for the IOAPIC in the 82801 southbridge (hard-coded in i82801xx_lpc.c)
44 
45  // Map APIC index into APIC ID
46  // IDs 3, 4, 5, and 8+ are available (see above note)
47 
48  if (apic_index < 3)
49  apic_id = apic_index + 3;
50  else
51  apic_id = apic_index + 5;
52 
53  ASSERT(apic_id < 16); // ID is only 4 bits
54 
55  // Read the MBAR address for setting up the IOAPIC in memory space
56  // NOTE: this address was assigned during enumeration of the bus
57 
58  memoryBase = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
59 
60  set_ioapic_id((void *)memoryBase, apic_id);
61 
62  // Use Processor System Bus to deliver interrupts
63  ioapic_set_boot_config((void *)memoryBase, true);
64 }
65 
66 static struct device_operations ioapic_ops = {
68  .set_resources = pci_dev_set_resources,
69  .enable_resources = pci_dev_enable_resources,
70  .init = p64h2_ioapic_init,
71  .enable = p64h2_ioapic_enable,
72 };
73 
74 static const struct pci_driver ioapic_driver __pci_driver = {
75  .ops = &ioapic_ops,
76  .vendor = PCI_VID_INTEL,
77  .device = PCI_DID_INTEL_82870_1E0,
78 
79 };
void ioapic_set_boot_config(void *ioapic_base, bool irq_on_fsb)
Definition: ioapic.c:143
void set_ioapic_id(void *ioapic_base, u8 ioapic_id)
Definition: ioapic.c:111
#define ASSERT(x)
Definition: assert.h:44
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
static __always_inline void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Definition: pci_ops.h:70
#define PCI_COMMAND_PARITY
Definition: pci_def.h:17
#define PCI_COMMAND_SERR
Definition: pci_def.h:19
#define PCI_COMMAND_MASTER
Definition: pci_def.h:13
#define PCI_COMMAND_MEMORY
Definition: pci_def.h:12
#define PCI_BASE_ADDRESS_0
Definition: pci_def.h:63
#define PCI_COMMAND
Definition: pci_def.h:10
void pci_dev_enable_resources(struct device *dev)
Definition: pci_device.c:721
void pci_dev_read_resources(struct device *dev)
Definition: pci_device.c:534
void pci_dev_set_resources(struct device *dev)
Definition: pci_device.c:691
#define PCI_DID_INTEL_82870_1E0
Definition: pci_ids.h:2679
#define PCI_VID_INTEL
Definition: pci_ids.h:2157
static struct device_operations ioapic_ops
Definition: ioapic.c:66
static void p64h2_ioapic_init(struct device *dev)
Configure one of the IOAPICs in a P64H2.
Definition: ioapic.c:30
static const struct pci_driver ioapic_driver __pci_driver
Definition: ioapic.c:74
static int num_p64h2_ioapics
Definition: ioapic.c:11
static void p64h2_ioapic_enable(struct device *dev)
Definition: ioapic.c:13
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
void(* read_resources)(struct device *dev)
Definition: device.h:39
Definition: device.h:107