1 /* SPDX-License-Identifier: GPL-2.0-only */
5 #include <device/pci_ops.h>
6 #include <console/console.h>
7 #include <cpu/x86/cache.h>
8 #include <device/pci_def.h>
9 #include <cpu/x86/smm.h>
10 #include <cpu/intel/em64t101_save_state.h>
14 #include <southbridge/intel/common/finalize.h>
15 #include <northbridge/intel/haswell/haswell.h>
16 #include <cpu/intel/haswell/haswell.h>
23 * @brief Set the EOS bit
25 void southbridge_smi_set_eos(void)
30 static void busmaster_disable_on_bus(int bus
)
36 for (slot
= 0; slot
< 0x20; slot
++) {
37 for (func
= 0; func
< 8; func
++) {
38 pci_devfn_t dev
= PCI_DEV(bus
, slot
, func
);
40 val
= pci_read_config32(dev
, PCI_VENDOR_ID
);
42 if (val
== 0xffffffff || val
== 0x00000000 ||
43 val
== 0x0000ffff || val
== 0xffff0000)
46 /* Disable Bus Mastering for this one device */
47 pci_and_config16(dev
, PCI_COMMAND
, ~PCI_COMMAND_MASTER
);
49 /* If this is a bridge, then follow it. */
50 hdr
= pci_read_config8(dev
, PCI_HEADER_TYPE
);
52 if (hdr
== PCI_HEADER_TYPE_BRIDGE
||
53 hdr
== PCI_HEADER_TYPE_CARDBUS
) {
55 buses
= pci_read_config32(dev
, PCI_PRIMARY_BUS
);
56 busmaster_disable_on_bus((buses
>> 8) & 0xff);
62 static int power_on_after_fail(void)
64 /* save and recover RTC port values */
68 const unsigned int s5pwr
= get_uint_option("power_on_after_fail",
69 CONFIG_MAINBOARD_POWER_FAILURE_STATE
);
73 /* For "KEEP", switch to "OFF" - KEEP is software emulated. */
74 return (s5pwr
== MAINBOARD_POWER_ON
);
77 static void southbridge_smi_sleep(void)
81 u16 pmbase
= get_pmbase();
83 /* First, disable further SMIs */
84 disable_smi(SLP_SMI_EN
);
86 /* Figure out SLP_TYP */
87 reg32
= inl(pmbase
+ PM1_CNT
);
88 printk(BIOS_SPEW
, "SMI#: SLP = 0x%08x\n", reg32
);
89 slp_typ
= acpi_sleep_from_pm1(reg32
);
91 /* Do any mainboard sleep handling */
92 mainboard_smi_sleep(slp_typ
);
94 /* USB sleep preparations */
95 #if !CONFIG(FINALIZE_USB_ROUTE_XHCI)
96 usb_ehci_sleep_prepare(PCH_EHCI1_DEV
, slp_typ
);
97 usb_ehci_sleep_prepare(PCH_EHCI2_DEV
, slp_typ
);
99 usb_xhci_sleep_prepare(PCH_XHCI_DEV
, slp_typ
);
101 /* Log S3, S4, and S5 entry */
102 if (slp_typ
>= ACPI_S3
)
103 elog_gsmi_add_event_byte(ELOG_TYPE_ACPI_ENTER
, slp_typ
);
105 /* Next, do the deed.
110 printk(BIOS_DEBUG
, "SMI#: Entering S0 (On)\n");
113 printk(BIOS_DEBUG
, "SMI#: Entering S1 (Assert STPCLK#)\n");
116 printk(BIOS_DEBUG
, "SMI#: Entering S3 (Suspend-To-RAM)\n");
118 /* Invalidate the cache before going to S3 */
122 printk(BIOS_DEBUG
, "SMI#: Entering S4 (Suspend-To-Disk)\n");
125 printk(BIOS_DEBUG
, "SMI#: Entering S5 (Soft Power off)\n");
127 /* Disable all GPE */
130 /* Always set the flag in case CMOS was changed on runtime. */
131 if (power_on_after_fail())
132 pci_and_config8(PCH_LPC_DEV
, GEN_PMCON_3
, ~1);
134 pci_or_config8(PCH_LPC_DEV
, GEN_PMCON_3
, 1);
136 /* also iterates over all bridges on bus 0 */
137 busmaster_disable_on_bus(0);
140 printk(BIOS_DEBUG
, "SMI#: ERROR: SLP_TYP reserved\n");
145 * Write back to the SLP register to cause the originally intended
146 * event again. We need to set BIT13 (SLP_EN) though to make the
149 enable_pm1_control(SLP_EN
);
151 /* Make sure to stop executing code here for S3/S4/S5 */
152 if (slp_typ
>= ACPI_S3
)
156 * In most sleep states, the code flow of this function ends at
157 * the line above. However, if we entered sleep state S1 and wake
158 * up again, we will continue to execute code in this function.
160 reg32
= inl(pmbase
+ PM1_CNT
);
161 if (reg32
& SCI_EN
) {
162 /* The OS is not an ACPI OS, so we set the state to S0 */
163 disable_pm1_control(SLP_EN
| SLP_TYP
);
168 * Look for Synchronous IO SMI and use save state from that
169 * core in case we are not running on the same core that
170 * initiated the IO transaction.
172 static em64t101_smm_state_save_area_t
*smi_apmc_find_state_save(u8 cmd
)
174 em64t101_smm_state_save_area_t
*state
;
177 /* Check all nodes looking for the one that issued the IO */
178 for (node
= 0; node
< CONFIG_MAX_CPUS
; node
++) {
179 state
= smm_get_save_state(node
);
181 /* Check for Synchronous IO (bit0 == 1) */
182 if (!(state
->io_misc_info
& (1 << 0)))
185 /* Make sure it was a write (bit4 == 0) */
186 if (state
->io_misc_info
& (1 << 4))
189 /* Check for APMC IO port */
190 if (((state
->io_misc_info
>> 16) & 0xff) != APM_CNT
)
193 /* Check AX against the requested command */
194 if ((state
->rax
& 0xff) != cmd
)
203 static void southbridge_smi_gsmi(void)
207 em64t101_smm_state_save_area_t
*io_smi
=
208 smi_apmc_find_state_save(APM_CNT_ELOG_GSMI
);
213 /* Command and return value in EAX */
214 ret
= (u32
*)&io_smi
->rax
;
215 sub_command
= (u8
)(*ret
>> 8);
217 /* Parameter buffer in EBX */
218 param
= (u32
*)&io_smi
->rbx
;
220 /* drivers/elog/gsmi.c */
221 *ret
= gsmi_exec(sub_command
, param
);
224 static void southbridge_smi_store(void)
227 em64t101_smm_state_save_area_t
*io_smi
=
228 smi_apmc_find_state_save(APM_CNT_SMMSTORE
);
233 /* Command and return value in EAX */
234 sub_command
= (io_smi
->rax
>> 8) & 0xff;
236 /* Parameter buffer in EBX */
237 reg_ebx
= io_smi
->rbx
;
239 /* drivers/smmstore/smi.c */
240 ret
= smmstore_exec(sub_command
, (void *)reg_ebx
);
244 static void southbridge_smi_apmc(void)
247 static int chipset_finalized
= 0;
249 reg8
= apm_get_apmc();
251 case APM_CNT_FINALIZE
:
252 if (chipset_finalized
) {
253 printk(BIOS_DEBUG
, "SMI#: Already finalized\n");
257 intel_pch_finalize_smm();
258 intel_cpu_haswell_finalize_smm();
260 chipset_finalized
= 1;
262 case APM_CNT_ACPI_DISABLE
:
263 disable_pm1_control(SCI_EN
);
265 case APM_CNT_ACPI_ENABLE
:
266 enable_pm1_control(SCI_EN
);
268 case APM_CNT_ROUTE_ALL_XHCI
:
269 usb_xhci_route_all();
271 case APM_CNT_ELOG_GSMI
:
272 if (CONFIG(ELOG_GSMI
))
273 southbridge_smi_gsmi();
275 case APM_CNT_SMMSTORE
:
276 if (CONFIG(SMMSTORE
))
277 southbridge_smi_store();
281 mainboard_smi_apmc(reg8
);
284 static void southbridge_smi_pm1(void)
286 u16 pm1_sts
= clear_pm1_status();
288 /* While OSPM is not active, poweroff immediately
289 * on a power button event.
291 if (pm1_sts
& PWRBTN_STS
) {
292 /* power button pressed */
293 elog_gsmi_add_event(ELOG_TYPE_POWER_BUTTON
);
294 disable_pm1_control(-1);
295 enable_pm1_control(SLP_EN
| (SLP_TYP_S5
<< 10));
299 static void southbridge_smi_gpe0(void)
304 static void southbridge_smi_gpi(void)
306 mainboard_smi_gpi(clear_alt_smi_status());
308 /* Clear again after mainboard handler */
309 clear_alt_smi_status();
312 static void southbridge_smi_mc(void)
314 u32 reg32
= inl(get_pmbase() + SMI_EN
);
316 /* Are microcontroller SMIs enabled? */
317 if ((reg32
& MCSMI_EN
) == 0)
320 printk(BIOS_DEBUG
, "Microcontroller SMI.\n");
323 static void southbridge_smi_tco(void)
325 u32 tco_sts
= clear_tco_status();
332 if (tco_sts
& (1 << 8)) {
333 u8 bios_cntl
= pci_read_config8(PCH_LPC_DEV
, BIOS_CNTL
);
337 * BWE is RW, so the SMI was caused by a
338 * write to BWE, not by a write to the BIOS
340 * This is the place where we notice someone
341 * is trying to tinker with the BIOS. We are
342 * trying to be nice and just ignore it. A more
343 * resolute answer would be to power down the
346 printk(BIOS_DEBUG
, "Switching back to RO\n");
347 pci_write_config8(PCH_LPC_DEV
, BIOS_CNTL
, (bios_cntl
& ~1));
348 } /* No else for now? */
349 } else if (tco_sts
& (1 << 3)) { /* TIMEOUT */
350 /* Handle TCO timeout */
351 printk(BIOS_DEBUG
, "TCO Timeout.\n");
355 static void southbridge_smi_periodic(void)
357 u32 reg32
= inl(get_pmbase() + SMI_EN
);
359 /* Are periodic SMIs enabled? */
360 if ((reg32
& PERIODIC_EN
) == 0)
363 printk(BIOS_DEBUG
, "Periodic SMI.\n");
366 static void southbridge_smi_monitor(void)
368 #define IOTRAP(x) (trap_sts & (1 << x))
369 u32 trap_sts
, trap_cycle
;
373 trap_sts
= RCBA32(0x1e00); // TRSR - Trap Status Register
374 RCBA32(0x1e00) = trap_sts
; // Clear trap(s) in TRSR
376 trap_cycle
= RCBA32(0x1e10);
377 for (i
= 16; i
< 20; i
++) {
378 if (trap_cycle
& (1 << i
))
379 mask
|= (0xff << ((i
- 16) << 3));
382 /* IOTRAP(3) SMI function call */
384 if (gnvs
&& gnvs
->smif
)
385 io_trap_handler(gnvs
->smif
); // call function smif
389 /* IOTRAP(2) currently unused
390 * IOTRAP(1) currently unused */
395 if (!(trap_cycle
& (1 << 24))) {
396 printk(BIOS_DEBUG
, "SMI1 command\n");
397 (void)RCBA32(0x1e18);
398 // data = RCBA32(0x1e18);
401 // southbridge_smi_command(data);
404 // Fall through to debug
407 printk(BIOS_DEBUG
, " trapped io address = 0x%x\n",
408 trap_cycle
& 0xfffc);
409 for (i
= 0; i
< 4; i
++)
411 printk(BIOS_DEBUG
, " TRAP = %d\n", i
);
412 printk(BIOS_DEBUG
, " AHBE = %x\n", (trap_cycle
>> 16) & 0xf);
413 printk(BIOS_DEBUG
, " MASK = 0x%08x\n", mask
);
414 printk(BIOS_DEBUG
, " read/write: %s\n",
415 (trap_cycle
& (1 << 24)) ? "read" : "write");
417 if (!(trap_cycle
& (1 << 24))) {
419 printk(BIOS_DEBUG
, " iotrap written data = 0x%08x\n", RCBA32(0x1e18));
424 typedef void (*smi_handler_t
)(void);
426 static smi_handler_t southbridge_smi
[32] = {
427 NULL
, // [0] reserved
428 NULL
, // [1] reserved
429 NULL
, // [2] BIOS_STS
430 NULL
, // [3] LEGACY_USB_STS
431 southbridge_smi_sleep
, // [4] SLP_SMI_STS
432 southbridge_smi_apmc
, // [5] APM_STS
433 NULL
, // [6] SWSMI_TMR_STS
434 NULL
, // [7] reserved
435 southbridge_smi_pm1
, // [8] PM1_STS
436 southbridge_smi_gpe0
, // [9] GPE0_STS
437 southbridge_smi_gpi
, // [10] GPI_STS
438 southbridge_smi_mc
, // [11] MCSMI_STS
439 NULL
, // [12] DEVMON_STS
440 southbridge_smi_tco
, // [13] TCO_STS
441 southbridge_smi_periodic
, // [14] PERIODIC_STS
442 NULL
, // [15] SERIRQ_SMI_STS
443 NULL
, // [16] SMBUS_SMI_STS
444 NULL
, // [17] LEGACY_USB2_STS
445 NULL
, // [18] INTEL_USB2_STS
446 NULL
, // [19] reserved
447 NULL
, // [20] PCI_EXP_SMI_STS
448 southbridge_smi_monitor
, // [21] MONITOR_STS
449 NULL
, // [22] reserved
450 NULL
, // [23] reserved
451 NULL
, // [24] reserved
452 NULL
, // [25] EL_SMI_STS
453 NULL
, // [26] SPI_STS
454 NULL
, // [27] reserved
455 NULL
, // [28] reserved
456 NULL
, // [29] reserved
457 NULL
, // [30] reserved
458 NULL
// [31] reserved
462 * @brief Interrupt handler for SMI#
464 void southbridge_smi_handler(void)
469 /* We need to clear the SMI status registers, or we won't see what's
470 * happening in the following calls.
472 smi_sts
= clear_smi_status();
474 /* Call SMI sub handler for each of the status bits */
475 for (i
= 0; i
< 31; i
++) {
476 if (smi_sts
& (1 << i
)) {
477 if (southbridge_smi
[i
]) {
478 southbridge_smi
[i
]();
481 "SMI_STS[%d] occurred, but no "
482 "handler available.\n", i
);