1 /* SPDX-License-Identifier: GPL-2.0-only */
4 * ACPI - create the Fixed ACPI Description Tables (FADT)
8 #include <console/console.h>
10 #include <acpi/acpi_gnvs.h>
11 #include <acpi/acpigen.h>
12 #include <device/pci_ops.h>
13 #include <arch/ioapic.h>
14 #include <arch/smp/mpspec.h>
15 #include <cpu/x86/smm.h>
17 #include <device/device.h>
18 #include <device/pci.h>
19 #include <amdblocks/acpimmio.h>
20 #include <amdblocks/acpi.h>
22 #include <soc/pci_devs.h>
24 #include <soc/southbridge.h>
30 unsigned long acpi_fill_mcfg(unsigned long current
)
33 current
+= acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t
*)current
,
34 CONFIG_MMCONF_BASE_ADDRESS
,
37 CONFIG_MMCONF_BUS_NUMBER
- 1);
42 unsigned long acpi_fill_madt(unsigned long current
)
44 const struct soc_amd_picasso_config
*cfg
= config_of_soc();
49 /* create all subtables for processors */
50 current
= acpi_create_madt_lapics(current
);
52 current
+= acpi_create_madt_ioapic((acpi_madt_ioapic_t
*)current
,
53 CONFIG_PICASSO_FCH_IOAPIC_ID
, IO_APIC_ADDR
, 0);
55 current
+= acpi_create_madt_ioapic((acpi_madt_ioapic_t
*)current
,
56 CONFIG_PICASSO_GNB_IOAPIC_ID
, GNB_IO_APIC_ADDR
, IO_APIC_INTERRUPTS
);
58 /* 0: mean bus 0--->ISA */
61 /* 5 mean: 0101 --> Edge-triggered, Active high */
62 current
+= acpi_create_madt_irqoverride((acpi_madt_irqoverride_t
*)
64 current
+= acpi_create_madt_irqoverride(
65 (acpi_madt_irqoverride_t
*)current
, 0, 9, 9,
66 MP_IRQ_TRIGGER_LEVEL
| MP_IRQ_POLARITY_LOW
);
68 for (i
= 0; i
< ARRAY_SIZE(cfg
->irq_override
); ++i
) {
69 irq
= cfg
->irq_override
[i
].irq
;
70 flags
= cfg
->irq_override
[i
].flags
;
75 current
+= acpi_create_madt_irqoverride((acpi_madt_irqoverride_t
*)current
, 0,
79 /* create all subtables for processors */
80 current
+= acpi_create_madt_lapic_nmi((acpi_madt_lapic_nmi_t
*)current
,
82 /* 1: LINT1 connect to NMI */
88 * Reference section 5.2.9 Fixed ACPI Description Table (FADT)
89 * in the ACPI 3.0b specification.
91 void acpi_fill_fadt(acpi_fadt_t
*fadt
)
93 const struct soc_amd_picasso_config
*cfg
= config_of_soc();
95 printk(BIOS_DEBUG
, "pm_base: 0x%04x\n", PICASSO_ACPI_IO_BASE
);
97 fadt
->sci_int
= 9; /* IRQ 09 - ACPI SCI */
99 if (permanent_smi_handler()) {
100 fadt
->smi_cmd
= APM_CNT
;
101 fadt
->acpi_enable
= APM_CNT_ACPI_ENABLE
;
102 fadt
->acpi_disable
= APM_CNT_ACPI_DISABLE
;
105 fadt
->pm1a_evt_blk
= ACPI_PM_EVT_BLK
;
106 fadt
->pm1a_cnt_blk
= ACPI_PM1_CNT_BLK
;
107 fadt
->pm_tmr_blk
= ACPI_PM_TMR_BLK
;
108 fadt
->gpe0_blk
= ACPI_GPE0_BLK
;
110 fadt
->pm1_evt_len
= 4; /* 32 bits */
111 fadt
->pm1_cnt_len
= 2; /* 16 bits */
112 fadt
->pm_tmr_len
= 4; /* 32 bits */
113 fadt
->gpe0_blk_len
= 8; /* 64 bits */
115 fadt
->p_lvl2_lat
= ACPI_FADT_C2_NOT_SUPPORTED
;
116 fadt
->p_lvl3_lat
= ACPI_FADT_C3_NOT_SUPPORTED
;
117 fadt
->duty_offset
= 1; /* CLK_VAL bits 3:1 */
118 fadt
->duty_width
= 3; /* CLK_VAL bits 3:1 */
119 fadt
->day_alrm
= 0x0d;
121 fadt
->century
= 0x32;
122 fadt
->iapc_boot_arch
= cfg
->fadt_boot_arch
; /* legacy free default */
123 fadt
->res2
= 0; /* reserved, MUST be 0 ACPI 3.0 */
124 fadt
->flags
|= ACPI_FADT_WBINVD
| /* See table 5-34 ACPI 6.3 spec */
125 ACPI_FADT_C1_SUPPORTED
|
126 ACPI_FADT_S4_RTC_WAKE
|
127 ACPI_FADT_32BIT_TIMER
|
128 ACPI_FADT_PCI_EXPRESS_WAKE
|
129 ACPI_FADT_PLATFORM_CLOCK
|
130 ACPI_FADT_S4_RTC_VALID
|
131 ACPI_FADT_REMOTE_POWER_ON
;
132 fadt
->flags
|= cfg
->fadt_flags
; /* additional board-specific flags */
134 fadt
->ARM_boot_arch
= 0; /* MUST be 0 ACPI 3.0 */
135 fadt
->FADT_MinorVersion
= 0; /* MUST be 0 ACPI 3.0 */
137 fadt
->x_firmware_ctl_l
= 0; /* set to 0 if firmware_ctrl is used */
138 fadt
->x_firmware_ctl_h
= 0;
140 fadt
->x_pm1a_evt_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
141 fadt
->x_pm1a_evt_blk
.bit_width
= 32;
142 fadt
->x_pm1a_evt_blk
.bit_offset
= 0;
143 fadt
->x_pm1a_evt_blk
.access_size
= ACPI_ACCESS_SIZE_WORD_ACCESS
;
144 fadt
->x_pm1a_evt_blk
.addrl
= ACPI_PM_EVT_BLK
;
145 fadt
->x_pm1a_evt_blk
.addrh
= 0x0;
147 fadt
->x_pm1a_cnt_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
148 fadt
->x_pm1a_cnt_blk
.bit_width
= 16;
149 fadt
->x_pm1a_cnt_blk
.bit_offset
= 0;
150 fadt
->x_pm1a_cnt_blk
.access_size
= ACPI_ACCESS_SIZE_WORD_ACCESS
;
151 fadt
->x_pm1a_cnt_blk
.addrl
= ACPI_PM1_CNT_BLK
;
152 fadt
->x_pm1a_cnt_blk
.addrh
= 0x0;
155 fadt
->x_pm_tmr_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
156 fadt
->x_pm_tmr_blk
.bit_width
= 32;
157 fadt
->x_pm_tmr_blk
.bit_offset
= 0;
158 fadt
->x_pm_tmr_blk
.access_size
= ACPI_ACCESS_SIZE_DWORD_ACCESS
;
159 fadt
->x_pm_tmr_blk
.addrl
= ACPI_PM_TMR_BLK
;
160 fadt
->x_pm_tmr_blk
.addrh
= 0x0;
163 fadt
->x_gpe0_blk
.space_id
= ACPI_ADDRESS_SPACE_IO
;
164 fadt
->x_gpe0_blk
.bit_width
= 64; /* EventStatus + Event Enable */
165 fadt
->x_gpe0_blk
.bit_offset
= 0;
166 fadt
->x_gpe0_blk
.access_size
= ACPI_ACCESS_SIZE_BYTE_ACCESS
;
167 fadt
->x_gpe0_blk
.addrl
= ACPI_GPE0_BLK
;
168 fadt
->x_gpe0_blk
.addrh
= 0x0;
171 void generate_cpu_entries(const struct device
*device
)
175 cores
= get_cpu_count();
176 printk(BIOS_DEBUG
, "ACPI \\_SB report %d core(s)\n", cores
);
178 /* Generate BSP \_SB.P000 */
179 acpigen_write_processor(0, ACPI_GPE0_BLK
, 6);
182 /* Generate AP \_SB.Pxxx */
183 for (cpu
= 1; cpu
< cores
; cpu
++) {
184 acpigen_write_processor(cpu
, 0, 0);
189 unsigned long southbridge_write_acpi_tables(const struct device
*device
,
190 unsigned long current
,
191 struct acpi_rsdp
*rsdp
)
193 return acpi_write_hpet(device
, current
, rsdp
);
196 void acpi_create_gnvs(struct global_nvs
*gnvs
)
198 /* Clear out GNVS. */
199 memset(gnvs
, 0, sizeof(*gnvs
));
201 if (CONFIG(CONSOLE_CBMEM
))
202 gnvs
->cbmc
= (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE
);
204 if (CONFIG(CHROMEOS
)) {
205 /* Initialize Verified Boot data */
206 chromeos_init_chromeos_acpi(&gnvs
->chromeos
);
207 gnvs
->chromeos
.vbt2
= ACTIVE_ECFW_RO
;
210 /* Set unknown wake source */
215 gnvs
->pcnt
= dev_count_cpu();
218 void southbridge_inject_dsdt(const struct device
*device
)
220 struct global_nvs
*gnvs
;
222 gnvs
= cbmem_find(CBMEM_ID_ACPI_GNVS
);
225 acpi_create_gnvs(gnvs
);
228 acpigen_write_scope("\\");
229 acpigen_write_name_dword("NVSA", (uintptr_t)gnvs
);
234 static void acpigen_soc_get_gpio_in_local5(uintptr_t addr
)
237 * Store (\_SB.GPR2 (addr), Local5)
238 * \_SB.GPR2 is used to read control byte 2 from control register.
239 * / It is defined in gpio_lib.asl.
241 acpigen_write_store();
242 acpigen_emit_namestring("\\_SB.GPR2");
243 acpigen_write_integer(addr
);
244 acpigen_emit_byte(LOCAL5_OP
);
247 static int acpigen_soc_get_gpio_val(unsigned int gpio_num
, uint32_t mask
)
249 if (gpio_num
>= SOC_GPIO_TOTAL_PINS
) {
250 printk(BIOS_WARNING
, "Warning: Pin %d should be smaller than"
251 " %d\n", gpio_num
, SOC_GPIO_TOTAL_PINS
);
254 uintptr_t addr
= gpio_get_address(gpio_num
);
256 acpigen_soc_get_gpio_in_local5(addr
);
258 /* If (And (Local5, mask)) */
259 acpigen_write_if_and(LOCAL5_OP
, mask
);
261 /* Store (One, Local0) */
262 acpigen_write_store_ops(ONE_OP
, LOCAL0_OP
);
264 acpigen_pop_len(); /* If */
267 acpigen_write_else();
269 /* Store (Zero, Local0) */
270 acpigen_write_store_ops(ZERO_OP
, LOCAL0_OP
);
272 acpigen_pop_len(); /* Else */
277 static int acpigen_soc_set_gpio_val(unsigned int gpio_num
, uint32_t val
)
279 if (gpio_num
>= SOC_GPIO_TOTAL_PINS
) {
280 printk(BIOS_WARNING
, "Warning: Pin %d should be smaller than"
281 " %d\n", gpio_num
, SOC_GPIO_TOTAL_PINS
);
284 uintptr_t addr
= gpio_get_address(gpio_num
);
286 /* Store (0x40, Local0) */
287 acpigen_write_store();
288 acpigen_write_integer(GPIO_PIN_OUT
);
289 acpigen_emit_byte(LOCAL0_OP
);
291 acpigen_soc_get_gpio_in_local5(addr
);
294 /* Or (Local5, GPIO_PIN_OUT, Local5) */
295 acpigen_write_or(LOCAL5_OP
, LOCAL0_OP
, LOCAL5_OP
);
297 /* Not (GPIO_PIN_OUT, Local6) */
298 acpigen_write_not(LOCAL0_OP
, LOCAL6_OP
);
300 /* And (Local5, Local6, Local5) */
301 acpigen_write_and(LOCAL5_OP
, LOCAL6_OP
, LOCAL5_OP
);
305 * SB.GPW2 (addr, Local5)
306 * \_SB.GPW2 is used to write control byte in control register
307 * / byte 2. It is defined in gpio_lib.asl.
309 acpigen_emit_namestring("\\_SB.GPW2");
310 acpigen_write_integer(addr
);
311 acpigen_emit_byte(LOCAL5_OP
);
316 int acpigen_soc_read_rx_gpio(unsigned int gpio_num
)
318 return acpigen_soc_get_gpio_val(gpio_num
, GPIO_PIN_IN
);
321 int acpigen_soc_get_tx_gpio(unsigned int gpio_num
)
323 return acpigen_soc_get_gpio_val(gpio_num
, GPIO_PIN_OUT
);
326 int acpigen_soc_set_tx_gpio(unsigned int gpio_num
)
328 return acpigen_soc_set_gpio_val(gpio_num
, 1);
331 int acpigen_soc_clear_tx_gpio(unsigned int gpio_num
)
333 return acpigen_soc_set_gpio_val(gpio_num
, 0);