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 <device/device.h>
7 #include <device/mmio.h>
8 #include <arch/smp/mpspec.h>
9 #include <console/console.h>
10 #include <device/pci_ops.h>
11 #include <intelblocks/cpulib.h>
12 #include <intelblocks/pmclib.h>
13 #include <intelblocks/acpi.h>
14 #include <soc/cpu.h>
15 #include <soc/iomap.h>
16 #include <soc/nvs.h>
17 #include <soc/pci_devs.h>
18 #include <soc/pm.h>
19 #include <soc/soc_chip.h>
20 #include <soc/systemagent.h>
21 
22 /*
23  * List of supported C-states in this processor.
24  */
25 enum {
26  C_STATE_C0, /* 0 */
27  C_STATE_C1, /* 1 */
28  C_STATE_C1E, /* 2 */
35  C_STATE_C8, /* 9 */
36  C_STATE_C9, /* 10 */
37  C_STATE_C10, /* 11 */
39 };
40 
42  [C_STATE_C0] = {},
43  [C_STATE_C1] = {
45  .power = C1_POWER,
46  .resource = MWAIT_RES(0, 0),
47  },
48  [C_STATE_C1E] = {
49  .latency = C1_LATENCY,
50  .power = C1_POWER,
51  .resource = MWAIT_RES(0, 1),
52  },
54  .latency = C6_LATENCY,
55  .power = C6_POWER,
56  .resource = MWAIT_RES(2, 0),
57  },
59  .latency = C6_LATENCY,
60  .power = C6_POWER,
61  .resource = MWAIT_RES(2, 1),
62  },
64  .latency = C7_LATENCY,
65  .power = C7_POWER,
66  .resource = MWAIT_RES(3, 0),
67  },
69  .latency = C7_LATENCY,
70  .power = C7_POWER,
71  .resource = MWAIT_RES(3, 1),
72  },
74  .latency = C7_LATENCY,
75  .power = C7_POWER,
76  .resource = MWAIT_RES(3, 2),
77  },
79  .latency = C7_LATENCY,
80  .power = C7_POWER,
81  .resource = MWAIT_RES(3, 3),
82  },
83  [C_STATE_C8] = {
84  .latency = C8_LATENCY,
85  .power = C8_POWER,
86  .resource = MWAIT_RES(4, 0),
87  },
88  [C_STATE_C9] = {
89  .latency = C9_LATENCY,
90  .power = C9_POWER,
91  .resource = MWAIT_RES(5, 0),
92  },
93  [C_STATE_C10] = {
94  .latency = C10_LATENCY,
95  .power = C10_POWER,
96  .resource = MWAIT_RES(6, 0),
97  },
98 };
99 
100 static int cstate_set_non_s0ix[] = {
101  C_STATE_C1,
104 };
105 
106 static int cstate_set_s0ix[] = {
107  C_STATE_C1,
110 };
111 
112 const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
113 {
116  int *set;
117  int i;
118 
120 
121  int is_s0ix_enable = config->s0ix_enable;
122 
123  if (is_s0ix_enable) {
124  *entries = ARRAY_SIZE(cstate_set_s0ix);
125  set = cstate_set_s0ix;
126  } else {
127  *entries = ARRAY_SIZE(cstate_set_non_s0ix);
128  set = cstate_set_non_s0ix;
129  }
130 
131  for (i = 0; i < *entries; i++) {
132  map[i] = cstate_map[set[i]];
133  map[i].ctype = i + 1;
134  }
135  return map;
136 }
137 
138 void soc_power_states_generation(int core_id, int cores_per_package)
139 {
141 
142  if (config->eist_enable)
143  /* Generate P-state tables */
144  generate_p_state_entries(core_id, cores_per_package);
145 }
146 
148 {
150 
152 
153  fadt->pm_tmr_blk = pmbase + PM1_TMR;
154  fadt->pm_tmr_len = 4;
156  fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
157  fadt->x_pm_tmr_blk.bit_offset = 0;
159  fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR;
160  fadt->x_pm_tmr_blk.addrh = 0x0;
161 
162  if (config->s0ix_enable)
164 }
165 
167 {
168  return read32p(soc_read_pmc_base() + IRQ_REG);
169 }
170 
171 static unsigned long soc_fill_dmar(unsigned long current)
172 {
173  uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
174  bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
175 
176  if (is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten) {
177  unsigned long tmp = current;
178 
179  current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
180  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
181 
182  acpi_dmar_drhd_fixup(tmp, current);
183  }
184 
185  uint64_t ipuvtbar = MCHBAR64(IPUVTBAR) & VTBAR_MASK;
186  bool ipuvten = MCHBAR32(IPUVTBAR) & VTBAR_ENABLED;
187 
188  if (is_devfn_enabled(SA_DEVFN_IPU) && ipuvtbar && ipuvten) {
189  unsigned long tmp = current;
190 
191  current += acpi_create_dmar_drhd(current, 0, 0, ipuvtbar);
192  current += acpi_create_dmar_ds_pci(current, 0, 5, 0);
193 
194  acpi_dmar_drhd_fixup(tmp, current);
195  }
196 
197  uint64_t vtvc0bar = MCHBAR64(VTVC0BAR) & VTBAR_MASK;
198  bool vtvc0en = MCHBAR32(VTVC0BAR) & VTBAR_ENABLED;
199 
200  if (vtvc0bar && vtvc0en) {
201  const unsigned long tmp = current;
202 
203  current += acpi_create_dmar_drhd(current,
204  DRHD_INCLUDE_PCI_ALL, 0, vtvc0bar);
205  current += acpi_create_dmar_ds_ioapic(current,
208  current += acpi_create_dmar_ds_msi_hpet(current,
211 
212  acpi_dmar_drhd_fixup(tmp, current);
213  }
214 
215  /* Add RMRR entry */
216  const unsigned long tmp = current;
217  current += acpi_create_dmar_rmrr(current, 0,
219  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
220  acpi_dmar_rmrr_fixup(tmp, current);
221 
222  return current;
223 }
224 
225 unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current,
226  struct acpi_rsdp *rsdp)
227 {
228  acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
229 
230  /*
231  * Create DMAR table only if we have VT-d capability and FSP does not override its
232  * feature.
233  */
234  if ((pci_read_config32(dev, CAPID0_A) & VTD_DISABLE) ||
236  return current;
237 
238  printk(BIOS_DEBUG, "ACPI: * DMAR\n");
240  current += dmar->header.length;
241  current = acpi_align_current(current);
242  acpi_add_table(rsdp, dmar);
243 
244  return current;
245 }
246 
248 {
250 
251  /* Enable DPTF based on mainboard configuration */
252  gnvs->dpte = config->dptf_enable;
253 
254  /* Set USB2/USB3 wake enable bitmaps. */
255  gnvs->u2we = config->usb2_wake_enable_bitmap;
256  gnvs->u3we = config->usb3_wake_enable_bitmap;
257 
258  /* Fill in Above 4GB MMIO resource */
260 }
261 
263 {
264  return MP_IRQ_POLARITY_HIGH;
265 }
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
__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 VTBAR_ENABLED
Definition: systemagent.h:38
#define V_P2SB_CFG_IBDF_BUS
Definition: systemagent.h:51
#define V_P2SB_CFG_IBDF_FUNC
Definition: systemagent.h:53
#define V_P2SB_CFG_HBDF_FUNC
Definition: systemagent.h:56
#define VTBAR_MASK
Definition: systemagent.h:39
#define IPUVTBAR
Definition: systemagent.h:33
#define V_P2SB_CFG_IBDF_DEV
Definition: systemagent.h:52
#define V_P2SB_CFG_HBDF_DEV
Definition: systemagent.h:55
#define V_P2SB_CFG_HBDF_BUS
Definition: systemagent.h:54
#define ARRAY_SIZE(a)
Definition: helpers.h:12
#define MAX(a, b)
Definition: helpers.h:40
#define MCHBAR32(x)
Definition: systemagent.h:23
void sa_fill_gnvs(struct global_nvs *gnvs)
Definition: systemagent.c:140
#define MCHBAR64(x)
Definition: systemagent.h:24
uintptr_t sa_get_tolud_base(void)
uintptr_t sa_get_gsm_base(void)
#define printk(level,...)
Definition: stdlib.h:16
#define MWAIT_RES(state, sub_state)
Definition: acpi.c:17
bool is_devfn_enabled(unsigned int devfn)
Definition: device_const.c:382
#define CAPID0_A
Definition: host_bridge.h:65
#define VTD_DISABLE
Definition: host_bridge.h:67
#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
#define ACPI_ACCESS_SIZE_UNDEFINED
Definition: acpi.h:126
@ DMA_CTRL_PLATFORM_OPT_IN_FLAG
Definition: acpi.h:525
@ DMAR_INTR_REMAP
Definition: acpi.h:523
#define ACPI_FADT_LOW_PWR_IDLE_S0
Definition: acpi.h:814
#define ACPI_ADDRESS_SPACE_IO
Definition: acpi.h:105
#define config_of_soc()
Definition: device.h:394
static __always_inline uint32_t read32p(const uintptr_t addr)
Definition: mmio.h:220
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 IRQ_REG
Definition: pmc.h:142
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
enum board_config config
Definition: memory.c:448
#define MP_IRQ_POLARITY_HIGH
Definition: mpspec.h:124
struct global_nvs * gnvs
const acpi_cstate_t * soc_get_cstate_map(size_t *entries)
Definition: acpi.c:113
@ C_STATE_C0
Definition: acpi.c:27
@ C_STATE_C7S_LONG_LAT
Definition: acpi.c:35
@ C_STATE_C1E
Definition: acpi.c:29
@ C_STATE_C7S_SHORT_LAT
Definition: acpi.c:34
@ C_STATE_C7_LONG_LAT
Definition: acpi.c:33
@ C_STATE_C6_LONG_LAT
Definition: acpi.c:31
@ C_STATE_C9
Definition: acpi.c:37
@ C_STATE_C10
Definition: acpi.c:38
@ C_STATE_C7_SHORT_LAT
Definition: acpi.c:32
@ C_STATE_C1
Definition: acpi.c:28
@ C_STATE_C8
Definition: acpi.c:36
@ NUM_C_STATES
Definition: acpi.c:39
@ C_STATE_C6_SHORT_LAT
Definition: acpi.c:30
unsigned long sa_write_acpi_tables(const struct device *dev, unsigned long current, struct acpi_rsdp *rsdp)
Definition: acpi.c:245
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
#define C7_POWER
Definition: cpu.h:17
#define C7_LATENCY
Definition: cpu.h:9
#define C1_POWER
Definition: cpu.h:15
#define C9_LATENCY
Definition: cpu.h:11
#define C6_POWER
Definition: cpu.h:16
#define C9_POWER
Definition: cpu.h:19
#define C8_LATENCY
Definition: cpu.h:10
#define C10_LATENCY
Definition: cpu.h:12
#define C10_POWER
Definition: cpu.h:20
#define C6_LATENCY
Definition: cpu.h:8
#define C8_POWER
Definition: cpu.h:18
#define C1_LATENCY
Definition: cpu.h:7
#define SA_DEVFN_IPU
Definition: pci_devs.h:40
#define SA_DEVFN_IGD
Definition: pci_devs.h:32
uintptr_t soc_read_pmc_base(void)
Definition: pmutil.c:147
void generate_p_state_entries(int core, int cores_per_package)
Definition: acpi.c:259
static unsigned long soc_fill_dmar(unsigned long current)
Definition: acpi.c:171
static int cstate_set_non_s0ix[]
Definition: acpi.c:100
static int cstate_set_s0ix[]
Definition: acpi.c:106
static const acpi_cstate_t cstate_map[NUM_C_STATES]
Definition: acpi.c:41
static u16 pmbase
Definition: smi.c:27
unsigned short uint16_t
Definition: stdint.h:11
unsigned int uint32_t
Definition: stdint.h:14
unsigned long long uint64_t
Definition: stdint.h:17
u8 ctype
Definition: acpi.h:984
u16 latency
Definition: acpi.h:985
acpi_header_t header
Definition: acpi.h:580
u32 pm_tmr_blk
Definition: acpi.h:724
u8 pm_tmr_len
Definition: acpi.h:730
u32 flags
Definition: acpi.h:746
acpi_addr_t x_pm_tmr_blk
Definition: acpi.h:760
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
u16 u2we
Definition: nvs.h:24
u16 u3we
Definition: nvs.h:25
uint8_t dpte
Definition: nvs.h:20