coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
acpi.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_gnvs.h>
5 #include <acpi/acpigen.h>
6 #include <arch/ioapic.h>
7 #include <arch/smp/mpspec.h>
9 #include <device/pci_ops.h>
10 #include <console/console.h>
11 #include <device/device.h>
12 #include <types.h>
13 #include <cpu/x86/msr.h>
14 #include <cpu/intel/turbo.h>
15 #include <soc/acpi.h>
16 #include <soc/device_nvs.h>
17 #include <soc/iomap.h>
18 #include <soc/lpc.h>
19 #include <soc/pci_devs.h>
20 #include <soc/pm.h>
21 #include <soc/systemagent.h>
23 
24 static unsigned long acpi_fill_dmar(unsigned long current)
25 {
26  struct device *const igfx_dev = pcidev_path_on_root(SA_DEVFN_IGD);
27  const u32 gfxvtbar = mchbar_read32(GFXVTBAR) & ~0xfff;
28  const u32 vtvc0bar = mchbar_read32(VTVC0BAR) & ~0xfff;
29  const bool gfxvten = mchbar_read32(GFXVTBAR) & 0x1;
30  const bool vtvc0en = mchbar_read32(VTVC0BAR) & 0x1;
31 
32  /* iGFX has to be enabled; GFXVTBAR set, enabled, in 32-bit space */
33  const bool emit_igd =
34  igfx_dev && igfx_dev->enabled &&
35  gfxvtbar && gfxvten &&
36  !mchbar_read32(GFXVTBAR + 4);
37 
38  /* First, add DRHD entries */
39  if (emit_igd) {
40  const unsigned long tmp = current;
41 
42  current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
43  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
44 
45  acpi_dmar_drhd_fixup(tmp, current);
46  }
47 
48  /* VTVC0BAR has to be set, enabled, and in 32-bit space */
49  if (vtvc0bar && vtvc0en && !mchbar_read32(VTVC0BAR + 4)) {
50  const unsigned long tmp = current;
51  current += acpi_create_dmar_drhd(current,
52  DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
53  current += acpi_create_dmar_ds_ioapic(current,
55  size_t i;
56  for (i = 0; i < 8; ++i)
57  current += acpi_create_dmar_ds_msi_hpet(current,
60  acpi_dmar_drhd_fixup(tmp, current);
61  }
62 
63  /* Then, add RMRR entries after all DRHD entries */
64  if (emit_igd) {
65  const unsigned long tmp = current;
66 
67  const struct device *sa_dev = pcidev_on_root(0, 0);
68 
69  /* Bit 0 is lock bit, not part of address */
70  const u32 tolud = pci_read_config32(sa_dev, TOLUD) & ~1;
71  const u32 bgsm = pci_read_config32(sa_dev, BGSM) & ~1;
72 
73  current += acpi_create_dmar_rmrr(current, 0, bgsm, tolud - 1);
74  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
75  acpi_dmar_rmrr_fixup(tmp, current);
76  }
77 
78  return current;
79 }
80 
81 unsigned long northbridge_write_acpi_tables(const struct device *const dev,
82  unsigned long current,
83  struct acpi_rsdp *const rsdp)
84 {
85  /* Create DMAR table only if we have VT-d capability. */
86  const u32 capid0_a = pci_read_config32(dev, CAPID0_A);
87  if (capid0_a & VTD_DISABLE)
88  return current;
89 
90  acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
91  printk(BIOS_DEBUG, "ACPI: * DMAR\n");
93  current += dmar->header.length;
94  current = acpi_align_current(current);
95  acpi_add_table(rsdp, dmar);
96 
97  return current;
98 }
99 
100 size_t size_of_dnvs(void)
101 {
102  return sizeof(struct device_nvs);
103 }
unsigned long acpi_create_dmar_ds_ioapic(unsigned long current, u8 enumeration_id, u8 bus, u8 dev, u8 fn)
Definition: acpi.c:775
unsigned long acpi_create_dmar_rmrr(unsigned long current, u16 segment, u64 bar, u64 limit)
Definition: acpi.c:652
void acpi_dmar_drhd_fixup(unsigned long base, unsigned long current)
Definition: acpi.c:719
void acpi_add_table(acpi_rsdp_t *rsdp, void *table)
Add an ACPI table to the RSDT (and XSDT) structure, recalculate length and checksum.
Definition: acpi.c:49
unsigned long acpi_create_dmar_ds_msi_hpet(unsigned long current, u8 enumeration_id, u8 bus, u8 dev, u8 fn)
Definition: acpi.c:782
unsigned long acpi_create_dmar_ds_pci(unsigned long current, u8 bus, u8 dev, u8 fn)
Definition: acpi.c:768
void acpi_create_dmar(acpi_dmar_t *dmar, enum dmar_flags flags, unsigned long(*acpi_fill_dmar)(unsigned long))
Definition: acpi.c:607
void acpi_dmar_rmrr_fixup(unsigned long base, unsigned long current)
Definition: acpi.c:725
unsigned long acpi_create_dmar_drhd(unsigned long current, u8 flags, u16 segment, u64 bar)
Definition: acpi.c:638
#define printk(level,...)
Definition: stdlib.h:16
DEVTREE_CONST struct device * pcidev_path_on_root(pci_devfn_t devfn)
Definition: device_const.c:255
DEVTREE_CONST struct device * pcidev_on_root(uint8_t dev, uint8_t fn)
Definition: device_const.c:260
static __always_inline uint32_t mchbar_read32(const uintptr_t offset)
Definition: fixed_bars.h:21
#define CAPID0_A
Definition: host_bridge.h:65
#define TOLUD
Definition: host_bridge.h:61
#define VTD_DISABLE
Definition: host_bridge.h:67
#define BGSM
Definition: host_bridge.h:59
#define VTVC0BAR
Definition: mchbar.h:20
#define GFXVTBAR
Definition: mchbar.h:18
static uintptr_t acpi_align_current(uintptr_t current)
Definition: acpi.h:1435
@ DRHD_INCLUDE_PCI_ALL
Definition: acpi.h:515
@ DMAR_INTR_REMAP
Definition: acpi.h:523
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
unsigned long northbridge_write_acpi_tables(const struct device *device, unsigned long start, struct acpi_rsdp *rsdp)
Definition: acpi.c:56
#define SA_DEVFN_IGD
Definition: pci_devs.h:32
size_t size_of_dnvs(void)
Definition: acpi.c:66
static unsigned long acpi_fill_dmar(unsigned long current)
Definition: acpi.c:24
#define PCH_IOAPIC_PCI_SLOT
Definition: pci_devs.h:81
#define PCH_HPET_PCI_SLOT
Definition: pci_devs.h:83
#define PCH_IOAPIC_PCI_BUS
Definition: pci_devs.h:80
#define PCH_HPET_PCI_BUS
Definition: pci_devs.h:82
uint32_t u32
Definition: stdint.h:51
acpi_header_t header
Definition: acpi.h:580
Definition: acpi.h:82
Definition: device.h:107
unsigned int enabled
Definition: device.h:122