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-or-later */
2 
3 #include <acpi/acpi.h>
4 #include <acpi/acpi_gnvs.h>
5 #include <acpi/acpigen.h>
6 #include <console/console.h>
7 #include <device/device.h>
8 #include <device/mmio.h>
9 #include <arch/smp/mpspec.h>
10 #include <assert.h>
11 #include <device/pci_ops.h>
12 #include <gpio.h>
13 #include <intelblocks/acpi.h>
14 #include <intelblocks/pmclib.h>
15 #include <intelblocks/p2sb.h>
16 #include <soc/iomap.h>
17 #include <soc/pm.h>
18 #include <soc/nvs.h>
19 #include <soc/pci_devs.h>
20 #include <soc/systemagent.h>
21 
22 #include "chip.h"
23 
24 #define CSTATE_RES(address_space, width, offset, address) \
25  { \
26  .space_id = address_space, \
27  .bit_width = width, \
28  .bit_offset = offset, \
29  .addrl = address, \
30  }
31 
32 static const acpi_cstate_t cstate_map[] = {
33  {
34  /* C1 */
35  .ctype = 1, /* ACPI C1 */
36  .latency = 1,
37  .power = 1000,
38  .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_FIXED, 0, 0, 0),
39  },
40  {
41  .ctype = 2, /* ACPI C2 */
42  .latency = 50,
43  .power = 10,
44  .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x415),
45  },
46  {
47  .ctype = 3, /* ACPI C3 */
48  .latency = 150,
49  .power = 10,
50  .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x419),
51  }
52 };
53 
55 {
56  return read32p(soc_read_pmc_base() + IRQ_REG);
57 }
58 
60 {
62 }
63 
64 const acpi_cstate_t *soc_get_cstate_map(size_t *entries)
65 {
66  *entries = ARRAY_SIZE(cstate_map);
67  return cstate_map;
68 }
69 
71 {
72  struct soc_intel_apollolake_config *cfg;
73  cfg = config_of_soc();
74 
75  /* Enable DPTF based on mainboard configuration */
76  gnvs->dpte = cfg->dptf_enable;
77 
78  /* Assign address of PERST_0 if GPIO is defined in devicetree */
79  if (cfg->prt0_gpio != GPIO_PRT0_UDEF)
81 
82  /* Get sdcard cd GPIO portid if GPIO is defined in devicetree.
83  * Get offset of sdcard cd pin.
84  */
85  if (cfg->sdcard_cd_gpio) {
88  }
89 
90  /* Fill in Above 4GB MMIO resource */
92 }
93 
95 {
96  return MP_IRQ_POLARITY_LOW;
97 }
98 
100 {
101  const struct soc_intel_apollolake_config *cfg;
102  cfg = config_of_soc();
103 
105 
106  fadt->pm_tmr_len = 4;
107 
109 
111  fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8;
114 
115  if (cfg->lpss_s0ix_enable)
117 }
118 
119 static unsigned long soc_fill_dmar(unsigned long current)
120 {
121  uint64_t gfxvtbar = MCHBAR64(GFXVTBAR) & VTBAR_MASK;
122  uint64_t defvtbar = MCHBAR64(DEFVTBAR) & VTBAR_MASK;
123  bool gfxvten = MCHBAR32(GFXVTBAR) & VTBAR_ENABLED;
124  bool defvten = MCHBAR32(DEFVTBAR) & VTBAR_ENABLED;
125  unsigned long tmp;
126 
127  /* IGD has to be enabled, GFXVTBAR set and enabled. */
128  const bool emit_igd = is_devfn_enabled(SA_DEVFN_IGD) && gfxvtbar && gfxvten;
129 
130  /* First, add DRHD entries */
131  if (emit_igd) {
132  tmp = current;
133 
134  current += acpi_create_dmar_drhd(current, 0, 0, gfxvtbar);
135  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
136  acpi_dmar_drhd_fixup(tmp, current);
137  }
138 
139  /* DEFVTBAR has to be set and enabled. */
140  if (defvtbar && defvten) {
141  tmp = current;
142  union p2sb_bdf ibdf = p2sb_get_ioapic_bdf();
143  union p2sb_bdf hbdf = p2sb_get_hpet_bdf();
144  p2sb_hide();
145 
146  current += acpi_create_dmar_drhd(current,
147  DRHD_INCLUDE_PCI_ALL, 0, defvtbar);
148  current += acpi_create_dmar_ds_ioapic(current,
149  2, ibdf.bus, ibdf.dev, ibdf.fn);
150  current += acpi_create_dmar_ds_msi_hpet(current,
151  0, hbdf.bus, hbdf.dev, hbdf.fn);
152  acpi_dmar_drhd_fixup(tmp, current);
153  }
154 
155  /* Then, add RMRR entries after all DRHD entries */
156  if (emit_igd) {
157  tmp = current;
158  current += acpi_create_dmar_rmrr(current, 0,
160  current += acpi_create_dmar_ds_pci(current, 0, 2, 0);
161  acpi_dmar_rmrr_fixup(tmp, current);
162  }
163 
164  return current;
165 }
166 
167 unsigned long sa_write_acpi_tables(const struct device *const dev,
168  unsigned long current,
169  struct acpi_rsdp *const rsdp)
170 {
171  acpi_dmar_t *const dmar = (acpi_dmar_t *)current;
172 
173  /* Create DMAR table only if virtualization is enabled. Due to some
174  * constraints on Apollo Lake SoC (some stepping affected), VTD could
175  * not be enabled together with IPU. Doing so will override and disable
176  * VTD while leaving CAPID0_A still reporting that VTD is available.
177  * As in this case FSP will lock VTD to disabled state, we need to make
178  * sure that DMAR table generation only happens when at least DEFVTBAR
179  * is enabled. Otherwise the DMAR header will be generated while the
180  * content of the table will be missing.
181  */
182 
185  return current;
186 
187  printk(BIOS_DEBUG, "ACPI: * DMAR\n");
189  current += dmar->header.length;
190  current = acpi_align_current(current);
191  acpi_add_table(rsdp, dmar);
192  current = acpi_align_current(current);
193 
194  return current;
195 }
196 
197 void soc_power_states_generation(int core_id, int cores_per_package)
198 {
199  /* Generate P-state tables */
200  generate_p_state_entries(core_id, cores_per_package);
201 
202  /* Generate T-state tables */
203  generate_t_state_entries(core_id, cores_per_package);
204 }
205 
207 {
208  /*
209  * Store (\_SB.GPC0 (addr), Local5)
210  * \_SB.GPC0 is used to read cfg0 value from dw0. It is defined in
211  * gpiolib.asl.
212  */
214  acpigen_emit_namestring("\\_SB.GPC0");
217 }
218 
219 static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask)
220 {
221  assert(gpio_num < TOTAL_PADS);
223 
225 
226  /* If (And (Local5, mask)) */
228 
229  /* Store (One, Local0) */
231 
232  /* Else */
234 
235  /* Store (Zero, Local0) */
237 
238  acpigen_pop_len(); /* Else */
239 
240  return 0;
241 }
242 
243 static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val)
244 {
245  assert(gpio_num < TOTAL_PADS);
247 
249 
250  if (val) {
251  /* Or (Local5, PAD_CFG0_TX_STATE, Local5) */
253  } else {
254  /* Not (PAD_CFG0_TX_STATE, Local6) */
256 
257  /* And (Local5, Local6, Local5) */
259  }
260 
261  /*
262  * \_SB.SPC0 (addr, Local5)
263  * \_SB.SPC0 is used to write cfg0 value in dw0. It is defined in
264  * gpiolib.asl.
265  */
266  acpigen_emit_namestring("\\_SB.SPC0");
269 
270  return 0;
271 }
272 
273 int acpigen_soc_read_rx_gpio(unsigned int gpio_num)
274 {
276 }
277 
278 int acpigen_soc_get_tx_gpio(unsigned int gpio_num)
279 {
281 }
282 
283 int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
284 {
285  return acpigen_soc_set_gpio_val(gpio_num, 1);
286 }
287 
288 int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
289 {
290  return acpigen_soc_set_gpio_val(gpio_num, 0);
291 }
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
void acpigen_write_or(uint8_t arg1, uint8_t arg2, uint8_t res)
Definition: acpigen.c:1371
void acpigen_write_and(uint8_t arg1, uint8_t arg2, uint8_t res)
Definition: acpigen.c:1389
void acpigen_emit_namestring(const char *namepath)
Definition: acpigen.c:275
void acpigen_write_store(void)
Definition: acpigen.c:1333
void acpigen_write_integer(uint64_t data)
Definition: acpigen.c:136
void acpigen_pop_len(void)
Definition: acpigen.c:37
void acpigen_write_not(uint8_t arg, uint8_t res)
Definition: acpigen.c:1398
void acpigen_write_if_and(uint8_t arg1, uint8_t arg2)
Definition: acpigen.c:1444
void acpigen_write_store_ops(uint8_t src, uint8_t dst)
Definition: acpigen.c:1339
void acpigen_emit_byte(unsigned char b)
Definition: acpigen.c:61
void acpigen_write_else(void)
Definition: acpigen.c:1510
#define TOTAL_PADS
#define PM1_TMR
Definition: pm.h:31
#define VTBAR_ENABLED
Definition: systemagent.h:38
#define VTBAR_MASK
Definition: systemagent.h:39
#define DEFVTBAR
Definition: systemagent.h:18
#define assert(statement)
Definition: assert.h:74
#define ARRAY_SIZE(a)
Definition: helpers.h:12
static u32 addr
Definition: cirrus.c:14
union p2sb_bdf p2sb_get_ioapic_bdf(void)
Definition: p2sb.c:59
void p2sb_hide(void)
Definition: p2sb.c:83
union p2sb_bdf p2sb_get_hpet_bdf(void)
Definition: p2sb.c: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
bool is_devfn_enabled(unsigned int devfn)
Definition: device_const.c:382
#define GPIO_PRT0_UDEF
Definition: gpio_apl.h:318
#define CAPID0_A
Definition: host_bridge.h:65
#define VTD_DISABLE
Definition: host_bridge.h:67
#define GFXVTBAR
Definition: mchbar.h:18
#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_FADT_LOW_PWR_IDLE_S0
Definition: acpi.h:814
#define ACPI_ADDRESS_SPACE_IO
Definition: acpi.h:105
#define ACPI_ADDRESS_SPACE_FIXED
Definition: acpi.h:115
@ LOCAL0_OP
Definition: acpigen.h:81
@ ZERO_OP
Definition: acpigen.h:30
@ LOCAL5_OP
Definition: acpigen.h:86
@ LOCAL6_OP
Definition: acpigen.h:87
@ ONE_OP
Definition: acpigen.h:31
#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 void write32p(const uintptr_t addr, const uint32_t value)
Definition: mmio.h:240
static __always_inline u32 pci_read_config32(const struct device *dev, u16 reg)
Definition: pci_ops.h:58
uint16_t gpio_acpi_pin(gpio_t gpio)
Definition: gpio.c:178
#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
#define MP_IRQ_POLARITY_LOW
Definition: mpspec.h:125
struct global_nvs * gnvs
const acpi_cstate_t * soc_get_cstate_map(size_t *entries)
Definition: acpi.c:113
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 SA_DEVFN_IGD
Definition: pci_devs.h:32
uintptr_t soc_read_pmc_base(void)
Definition: pmutil.c:147
static unsigned long soc_fill_dmar(unsigned long current)
Definition: acpi.c:119
static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val)
Definition: acpi.c:243
int acpigen_soc_get_tx_gpio(unsigned int gpio_num)
Definition: acpi.c:278
int acpigen_soc_clear_tx_gpio(unsigned int gpio_num)
Definition: acpi.c:288
static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask)
Definition: acpi.c:219
static const acpi_cstate_t cstate_map[]
Definition: acpi.c:32
#define CSTATE_RES(address_space, width, offset, address)
Definition: acpi.c:24
int acpigen_soc_read_rx_gpio(unsigned int gpio_num)
Definition: acpi.c:273
static void acpigen_soc_get_dw0_in_local5(uintptr_t addr)
Definition: acpi.c:206
int acpigen_soc_set_tx_gpio(unsigned int gpio_num)
Definition: acpi.c:283
void soc_write_sci_irq_select(uint32_t scis)
Definition: acpi.c:59
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
uint8_t gpio_get_pad_portid(const gpio_t pad)
Definition: gpio.c:411
void * gpio_dwx_address(const gpio_t pad)
Definition: gpio.c:398
static const int mask[4]
Definition: gpio.c:308
#define PAD_CFG0_RX_STATE
Definition: gpio_defs.h:11
#define PAD_CFG0_TX_STATE
Definition: gpio_defs.h:9
unsigned int uint32_t
Definition: stdint.h:14
unsigned long uintptr_t
Definition: stdint.h:21
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
u8 pm_tmr_len
Definition: acpi.h:730
u32 flags
Definition: acpi.h:746
u16 iapc_boot_arch
Definition: acpi.h:744
acpi_addr_t x_pm_tmr_blk
Definition: acpi.h:760
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
uint32_t prt0
Definition: nvs.h:26
uint8_t dpte
Definition: nvs.h:20
uint8_t scdp
Definition: nvs.h:27
uint8_t scdo
Definition: nvs.h:28
unsigned int sdcard_cd_gpio
Definition: chip.h:144
u8 val
Definition: sys.c:300
Definition: p2sb.h:40
uint16_t dev
Definition: p2sb.h:43
uint16_t fn
Definition: p2sb.h:42
uint16_t bus
Definition: p2sb.h:44