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/smp/mpspec.h>
7 #include <cpu/cpu.h>
8 #include <cpu/x86/smm.h>
9 #include <string.h>
10 #include <device/pci.h>
11 #include <device/pci_ops.h>
12 #include <cbmem.h>
13 #include <console/console.h>
14 #include <intelblocks/acpi.h>
15 #include <soc/acpi.h>
16 #include <soc/cpu.h>
17 #include <soc/nvs.h>
18 #include <soc/soc_util.h>
19 #include <soc/pmc.h>
20 #include <soc/systemagent.h>
21 #include <soc/pci_devs.h>
22 
23 #define CSTATE_RES(address_space, width, offset, address) \
24  { \
25  .space_id = address_space, \
26  .bit_width = width, \
27  .bit_offset = offset, \
28  .addrl = address, \
29  }
30 
31 static const acpi_cstate_t cstate_map[] = {
32  {
33  /* C1 */
34  .ctype = 1, /* ACPI C1 */
35  .latency = 2,
36  .power = 1000,
37  .resource = MWAIT_RES(0, 0),
38  },
39  {
40  .ctype = 2, /* ACPI C2 */
41  .latency = 10,
42  .power = 10,
43  .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0,
44  ACPI_BASE_ADDRESS + 0x14),
45  },
46  {
47  .ctype = 3, /* ACPI C3 */
48  .latency = 50,
49  .power = 10,
50  .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0,
51  ACPI_BASE_ADDRESS + 0x15),
52  }
53 };
54 
56 {
57  /* Top of Low Memory (start of resource allocation) */
59 
60  /* MMIO Low/High & TSEG base and length */
62  gnvs->mmiol = (u32)(get_pciebase() - 1);
64  gnvs->mmiohl = (u64)(((u64)1 << cpu_phys_address_size()) - 1);
67 }
68 
70 {
71  struct device *dev = get_pmc_dev();
72 
73  if (!dev)
74  return 0;
75 
76  return pci_read_config32(dev, PMC_ACPI_CNT);
77 }
78 
79 const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
80 {
81  *entries = ARRAY_SIZE(cstate_map);
82  return cstate_map;
83 }
84 
86 {
87  u16 pmbase = get_pmbase();
88 
89  /* Power Control */
90  fadt->pm2_cnt_blk = pmbase + PM2_CNT;
91  fadt->pm_tmr_blk = pmbase + PM1_TMR;
92 
93  /* Control Registers - Length */
94  fadt->pm2_cnt_len = 1;
95  fadt->pm_tmr_len = 4;
96 
98 
99  /* PM2 Control Registers */
101  fadt->x_pm2_cnt_blk.bit_width = 8;
102  fadt->x_pm2_cnt_blk.bit_offset = 0;
104  fadt->x_pm2_cnt_blk.addrl = fadt->pm2_cnt_blk;
105  fadt->x_pm2_cnt_blk.addrh = 0x00;
106 
107  /* PM1 Timer Register */
109  fadt->x_pm_tmr_blk.bit_width = 32;
110  fadt->x_pm_tmr_blk.bit_offset = 0;
112  fadt->x_pm_tmr_blk.addrl = fadt->pm_tmr_blk;
113  fadt->x_pm_tmr_blk.addrh = 0x00;
114 }
115 
117  { 100, 1000, 0, 0x00, 0 },
118  { 88, 875, 0, 0x1e, 0 },
119  { 75, 750, 0, 0x1c, 0 },
120  { 63, 625, 0, 0x1a, 0 },
121  { 50, 500, 0, 0x18, 0 },
122  { 38, 375, 0, 0x16, 0 },
123  { 25, 250, 0, 0x14, 0 },
124  { 13, 125, 0, 0x12, 0 },
125 };
126 
128 {
129  *entries = ARRAY_SIZE(denverton_tss_table);
130  return denverton_tss_table;
131 }
132 
133 void soc_power_states_generation(int core_id, int cores_per_package)
134 {
135  generate_p_state_entries(core_id, cores_per_package);
136 
137  generate_t_state_entries(core_id, cores_per_package);
138 }
139 
141 {
142  if (sci >= 20)
143  return MP_IRQ_POLARITY_LOW;
144  else
145  return MP_IRQ_POLARITY_HIGH;
146 }
147 
148 unsigned long southcluster_write_acpi_tables(const struct device *device,
149  unsigned long current,
150  struct acpi_rsdp *rsdp)
151 {
152  acpi_header_t *ssdt2;
153 
154  current = acpi_write_hpet(device, current, rsdp);
155  current = (ALIGN(current, 16));
156 
157  ssdt2 = (acpi_header_t *)current;
158  memset(ssdt2, 0, sizeof(acpi_header_t));
160  if (ssdt2->length) {
161  current += ssdt2->length;
162  acpi_add_table(rsdp, ssdt2);
163  printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n", ssdt2,
164  ssdt2->length);
165  current = (ALIGN(current, 16));
166  } else {
167  ssdt2 = NULL;
168  printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n");
169  }
170 
171  printk(BIOS_DEBUG, "current = %lx\n", current);
172 
173  return current;
174 }
175 
177 
178 static unsigned long acpi_fill_dmar(unsigned long current)
179 {
180  uint64_t vtbar;
181  unsigned long tmp = current;
182 
183  vtbar = read64((void *)(DEFAULT_MCHBAR + MCH_VTBAR_OFFSET)) & MCH_VTBAR_MASK;
184  printk(BIOS_DEBUG, "DEFVTBAR:0x%llx\n", vtbar);
185  if (!vtbar)
186  return current;
187 
188  current += acpi_create_dmar_drhd(current,
189  DRHD_INCLUDE_PCI_ALL, 0, vtbar);
190 
191  current += acpi_create_dmar_ds_ioapic(current,
193  current += acpi_create_dmar_ds_msi_hpet(current,
195 
196  acpi_dmar_drhd_fixup(tmp, current);
197 
198  /* Create RMRR; see "VTD PLATFORM CONFIGURATION" in FSP log */
199  tmp = current;
200  current += acpi_create_dmar_rmrr(current, 0,
203  current += acpi_create_dmar_ds_pci(current,
204  0, XHCI_DEV, XHCI_FUNC);
205  acpi_dmar_rmrr_fixup(tmp, current);
206 
207  return current;
208 }
209 
210 unsigned long systemagent_write_acpi_tables(const struct device *dev,
211  unsigned long current,
212  struct acpi_rsdp *const rsdp)
213 {
214  /* Create DMAR table only if we have VT-d capability. */
215  const u32 capid0_a = pci_read_config32(dev, CAPID0_A);
216  if (capid0_a & VTD_DISABLE)
217  return current;
218 
219  acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
220  printk(BIOS_DEBUG, "ACPI: * DMAR\n");
222  current += dmar->header.length;
223  current = acpi_align_current(current);
224  acpi_add_table(rsdp, dmar);
225 
226  return current;
227 }
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
unsigned long acpi_write_hpet(const struct device *device, unsigned long current, acpi_rsdp_t *rsdp)
Definition: acpi.c:1141
__weak void soc_fill_fadt(acpi_fadt_t *fadt)
Definition: acpi.c:1483
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 PM1_TMR
Definition: pm.h:31
#define PM2_CNT
Definition: pm.h:77
uint64_t read64(const void *addr)
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
#define ARRAY_SIZE(a)
Definition: helpers.h:12
void * cbmem_top(void)
Definition: imd_cbmem.c:18
#define printk(level,...)
Definition: stdlib.h:16
#define MWAIT_RES(state, sub_state)
Definition: acpi.c:17
int cpu_phys_address_size(void)
Definition: cpu_common.c:46
#define MCH_VTBAR_MASK
Definition: systemagent.h:65
#define MCH_VTBAR_OFFSET
Definition: systemagent.h:63
#define CAPID0_A
Definition: host_bridge.h:65
#define VTD_DISABLE
Definition: host_bridge.h:67
#define ACPI_FADT_LEGACY_DEVICES
Definition: acpi.h:818
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
#define ACPI_ACCESS_SIZE_DWORD_ACCESS
Definition: acpi.h:129
#define ACPI_FADT_8042
Definition: acpi.h:819
#define ACPI_ACCESS_SIZE_BYTE_ACCESS
Definition: acpi.h:127
#define ACPI_ADDRESS_SPACE_IO
Definition: acpi.h:105
#define ALIGN
Definition: asm.h:22
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
#define ACPI_BASE_ADDRESS
Definition: iomap.h:99
#define DEFAULT_MCHBAR
Definition: iomap.h:11
#define RMRR_USB_LIMIT_ADDRESS
Definition: iomap.h:27
#define RMRR_USB_BASE_ADDRESS
Definition: iomap.h:26
#define PMC_ACPI_CNT
Definition: pmc.h:9
uint32_t get_pciebase(void)
Definition: soc_util.c:66
uint32_t get_top_of_low_memory(void)
Definition: soc_util.c:153
struct device * get_pmc_dev(void)
Definition: soc_util.c:48
uint64_t get_top_of_upper_memory(void)
Definition: soc_util.c:168
uint32_t get_tseg_memory(void)
Definition: soc_util.c:138
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define MP_IRQ_POLARITY_LOW
Definition: mpspec.h:125
#define MP_IRQ_POLARITY_HIGH
Definition: mpspec.h:124
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
struct global_nvs * gnvs
#define XHCI_DEV
Definition: pci_devs.h:151
#define XHCI_FUNC
Definition: pci_devs.h:152
const acpi_cstate_t * soc_get_cstate_map(size_t *entries)
Definition: acpi.c:113
int soc_madt_sci_irq_polarity(int sci)
Definition: acpi.c:282
void soc_power_states_generation(int core_id, int cores_per_package)
Definition: acpi.c:139
void soc_fill_gnvs(struct global_nvs *gnvs)
Definition: acpi.c:267
uint32_t soc_read_sci_irq_select(void)
Definition: acpi.c:167
__weak void acpi_create_serialio_ssdt(acpi_header_t *ssdt)
Definition: acpi.c:371
unsigned long southcluster_write_acpi_tables(const struct device *device, unsigned long current, struct acpi_rsdp *rsdp)
Definition: acpi.c:342
#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
acpi_tstate_t * soc_get_tss_table(int *entries)
Definition: acpi.c:343
void generate_t_state_entries(int core, int cores_per_package)
Definition: acpi.c:349
void generate_p_state_entries(int core, int cores_per_package)
Definition: acpi.c:259
static const acpi_cstate_t cstate_map[]
Definition: acpi.c:31
#define CSTATE_RES(address_space, width, offset, address)
Definition: acpi.c:23
unsigned long systemagent_write_acpi_tables(const struct device *dev, unsigned long current, struct acpi_rsdp *const rsdp)
Definition: acpi.c:210
static acpi_tstate_t denverton_tss_table[]
Definition: acpi.c:116
static unsigned long acpi_fill_dmar(unsigned long current)
Definition: acpi.c:178
uint16_t get_pmbase(void)
Definition: acpi.c:76
static u16 pmbase
Definition: smi.c:27
#define NULL
Definition: stddef.h:19
uint64_t u64
Definition: stdint.h:54
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint16_t u16
Definition: stdint.h:48
unsigned long long uint64_t
Definition: stdint.h:17
u8 ctype
Definition: acpi.h:984
acpi_header_t header
Definition: acpi.h:580
u32 pm_tmr_blk
Definition: acpi.h:724
acpi_addr_t x_pm2_cnt_blk
Definition: acpi.h:759
u8 pm_tmr_len
Definition: acpi.h:730
u8 pm2_cnt_len
Definition: acpi.h:729
u16 iapc_boot_arch
Definition: acpi.h:744
acpi_addr_t x_pm_tmr_blk
Definition: acpi.h:760
u32 pm2_cnt_blk
Definition: acpi.h:723
u8 bit_offset
Definition: acpi.h:98
u8 bit_width
Definition: acpi.h:97
u8 access_size
Definition: acpi.h:99
Definition: acpi.h:82
Definition: device.h:107
Definition: nvs.h:14
u32 tsegl
Definition: nvs.h:47
u64 mmiohb
Definition: nvs.h:44
u32 tolm
Definition: nvs.h:44
u32 tsegb
Definition: nvs.h:46
u32 mmiob
Definition: nvs.h:42
u32 mmiol
Definition: nvs.h:43
u64 mmiohl
Definition: nvs.h:45