2 * This file is part of the coreboot project.
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2014 Google Inc.
6 * Copyright (C) 2015 Intel Corporation.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
22 #include <console/console.h>
23 #include <cpu/x86/cache.h>
24 #include <device/pci_def.h>
25 #include <cpu/x86/smm.h>
26 #include <spi-generic.h>
28 #include <pc80/mc146818rtc.h>
29 #include <soc/iomap.h>
32 #include <soc/pci_devs.h>
39 static u8 smm_initialized
= 0;
42 * GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
45 static global_nvs_t
*gnvs
;
46 global_nvs_t
*smm_get_gnvs(void)
51 int southbridge_io_trap_handler(int smif
)
55 printk(BIOS_DEBUG
, "OS Init\n");
58 * - On success, the IO Trap Handler returns 0
59 * - On failure, the IO Trap Handler returns a value != 0
62 return 1; /* IO trap handled */
70 void southbridge_smi_set_eos(void)
75 static void busmaster_disable_on_bus(int bus
)
81 for (slot
= 0; slot
< 0x20; slot
++) {
82 for (func
= 0; func
< 8; func
++) {
84 device_t dev
= PCI_DEV(bus
, slot
, func
);
86 val
= pci_read_config32(dev
, PCI_VENDOR_ID
);
88 if (val
== 0xffffffff || val
== 0x00000000 ||
89 val
== 0x0000ffff || val
== 0xffff0000)
92 /* Disable Bus Mastering for this one device */
93 reg32
= pci_read_config32(dev
, PCI_COMMAND
);
94 reg32
&= ~PCI_COMMAND_MASTER
;
95 pci_write_config32(dev
, PCI_COMMAND
, reg32
);
97 /* If this is a bridge, then follow it. */
98 hdr
= pci_read_config8(dev
, PCI_HEADER_TYPE
);
100 if (hdr
== PCI_HEADER_TYPE_BRIDGE
||
101 hdr
== PCI_HEADER_TYPE_CARDBUS
) {
103 buses
= pci_read_config32(dev
, PCI_PRIMARY_BUS
);
104 busmaster_disable_on_bus((buses
>> 8) & 0xff);
111 static void southbridge_smi_sleep(void)
116 u8 s5pwr
= CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
;
118 /* save and recover RTC port values */
122 get_option(&s5pwr
, "power_on_after_fail");
126 /* First, disable further SMIs */
127 disable_smi(SLP_SMI_EN
);
129 /* Figure out SLP_TYP */
130 reg32
= inl(ACPI_BASE_ADDRESS
+ PM1_CNT
);
131 printk(BIOS_SPEW
, "SMI#: SLP = 0x%08x\n", reg32
);
132 slp_typ
= (reg32
>> 10) & 7;
134 /* Do any mainboard sleep handling */
135 mainboard_smi_sleep(slp_typ
-2);
137 if (IS_ENABLED(CONFIG_ELOG_GSMI
))
138 /* Log S3, S4, and S5 entry */
140 elog_add_event_byte(ELOG_TYPE_ACPI_ENTER
, slp_typ
-2);
142 /* Clear pending GPE events */
145 /* Next, do the deed. */
148 printk(BIOS_DEBUG
, "SMI#: Entering S0 (On)\n");
151 printk(BIOS_DEBUG
, "SMI#: Entering S1 (Assert STPCLK#)\n");
154 printk(BIOS_DEBUG
, "SMI#: Entering S3 (Suspend-To-RAM)\n");
156 /* Invalidate the cache before going to S3 */
160 printk(BIOS_DEBUG
, "SMI#: Entering S5 (Soft Power off)\n");
161 /*TODO: cmos_layout.bin need to verify; cause wrong CMOS setup*/
162 s5pwr
= MAINBOARD_POWER_ON
;
163 /* Disable all GPE */
167 * Always set the flag in case CMOS was changed on runtime. For
168 * "KEEP", switch to "OFF" - KEEP is software emulated
170 reg8
= pci_read_config8(PCH_DEV_PMC
, GEN_PMCON_B
);
171 if (s5pwr
== MAINBOARD_POWER_ON
)
175 pci_write_config8(PCH_DEV_PMC
, GEN_PMCON_B
, reg8
);
177 /* also iterates over all bridges on bus 0 */
178 busmaster_disable_on_bus(0);
181 printk(BIOS_DEBUG
, "SMI#: ERROR: SLP_TYP reserved\n");
186 * Write back to the SLP register to cause the originally intended
187 * event again. We need to set BIT13 (SLP_EN) though to make the
190 enable_pm1_control(SLP_EN
);
192 /* Make sure to stop executing code here for S3/S4/S5 */
197 * In most sleep states, the code flow of this function ends at
198 * the line above. However, if we entered sleep state S1 and wake
199 * up again, we will continue to execute code in this function.
201 reg32
= inl(ACPI_BASE_ADDRESS
+ PM1_CNT
);
202 if (reg32
& SCI_EN
) {
203 /* The OS is not an ACPI OS, so we set the state to S0 */
204 disable_pm1_control(SLP_EN
| SLP_TYP
);
209 * Look for Synchronous IO SMI and use save state from that
210 * core in case we are not running on the same core that
211 * initiated the IO transaction.
213 static em64t101_smm_state_save_area_t
*smi_apmc_find_state_save(u8 cmd
)
215 em64t101_smm_state_save_area_t
*state
;
218 /* Check all nodes looking for the one that issued the IO */
219 for (node
= 0; node
< CONFIG_MAX_CPUS
; node
++) {
220 state
= smm_get_save_state(node
);
222 /* Check for Synchronous IO (bit0==1) */
223 if (!(state
->io_misc_info
& (1 << 0)))
226 /* Make sure it was a write (bit4==0) */
227 if (state
->io_misc_info
& (1 << 4))
230 /* Check for APMC IO port */
231 if (((state
->io_misc_info
>> 16) & 0xff) != APM_CNT
)
234 /* Check AX against the requested command */
235 if ((state
->rax
& 0xff) != cmd
)
244 static void southbridge_smi_gsmi(void)
246 #if IS_ENABLED(CONFIG_ELOG_GSMI)
249 em64t101_smm_state_save_area_t
*io_smi
=
250 smi_apmc_find_state_save(ELOG_GSMI_APM_CNT
);
255 /* Command and return value in EAX */
256 ret
= (u32
*)&io_smi
->rax
;
257 sub_command
= (u8
)(*ret
>> 8);
259 /* Parameter buffer in EBX */
260 param
= (u32
*)&io_smi
->rbx
;
262 /* drivers/elog/gsmi.c */
263 *ret
= gsmi_exec(sub_command
, param
);
267 static void finalize(void)
269 static int finalize_done
;
272 printk(BIOS_DEBUG
, "SMM already finalized.\n");
277 if (IS_ENABLED(CONFIG_SPI_FLASH_SMM
))
278 /* Re-init SPI driver to handle locked BAR */
282 static void southbridge_smi_apmc(void)
285 em64t101_smm_state_save_area_t
*state
;
287 /* Emulate B2 register as the FADT / Linux expects it */
291 case APM_CNT_PST_CONTROL
:
292 printk(BIOS_DEBUG
, "P-state control\n");
294 case APM_CNT_ACPI_DISABLE
:
295 disable_pm1_control(SCI_EN
);
296 printk(BIOS_DEBUG
, "SMI#: ACPI disabled.\n");
298 case APM_CNT_ACPI_ENABLE
:
299 enable_pm1_control(SCI_EN
);
300 printk(BIOS_DEBUG
, "SMI#: ACPI enabled.\n");
302 case APM_CNT_FINALIZE
:
305 case APM_CNT_GNVS_UPDATE
:
306 if (smm_initialized
) {
308 "SMI#: SMM structures already initialized!\n");
311 state
= smi_apmc_find_state_save(reg8
);
313 /* EBX in the state save contains the GNVS pointer */
314 gnvs
= (global_nvs_t
*)((u32
)state
->rbx
);
316 printk(BIOS_DEBUG
, "SMI#: Setting GNVS to %p\n", gnvs
);
319 case ELOG_GSMI_APM_CNT
:
320 if (IS_ENABLED(CONFIG_ELOG_GSMI
))
321 southbridge_smi_gsmi();
325 mainboard_smi_apmc(reg8
);
328 static void southbridge_smi_pm1(void)
330 u16 pm1_sts
= clear_pm1_status();
333 * While OSPM is not active, poweroff immediately on a power button
336 if (pm1_sts
& PWRBTN_STS
) {
337 /* power button pressed */
338 if (IS_ENABLED(CONFIG_ELOG_GSMI
))
339 elog_add_event(ELOG_TYPE_POWER_BUTTON
);
340 disable_pm1_control(-1UL);
341 enable_pm1_control(SLP_EN
| (SLP_TYP_S5
<< 10));
345 static void southbridge_smi_gpe0(void)
350 void __attribute__((weak
))
351 mainboard_smi_gpi_handler(const struct gpi_status
*sts
) { }
353 static void southbridge_smi_gpi(void)
355 struct gpi_status smi_sts
;
357 gpi_clear_get_smi_status(&smi_sts
);
358 mainboard_smi_gpi_handler(&smi_sts
);
360 /* Clear again after mainboard handler */
361 gpi_clear_get_smi_status(&smi_sts
);
364 static void southbridge_smi_mc(void)
366 u32 reg32
= inl(ACPI_BASE_ADDRESS
+ SMI_EN
);
368 /* Are microcontroller SMIs enabled? */
369 if ((reg32
& MCSMI_EN
) == 0)
372 printk(BIOS_DEBUG
, "Microcontroller SMI.\n");
375 static void southbridge_smi_tco(void)
377 u32 tco_sts
= clear_tco_status();
383 if (tco_sts
& (1 << 8)) { /* BIOSWR */
384 u8 bios_cntl
= pci_read_config16(PCH_DEV_SPI
, BIOS_CNTL
);
388 * BWE is RW, so the SMI was caused by a
389 * write to BWE, not by a write to the BIOS
391 * This is the place where we notice someone
392 * is trying to tinker with the BIOS. We are
393 * trying to be nice and just ignore it. A more
394 * resolute answer would be to power down the
397 printk(BIOS_DEBUG
, "Switching back to RO\n");
398 pci_write_config32(PCH_DEV_SPI
, BIOS_CNTL
,
400 } /* No else for now? */
401 } else if (tco_sts
& (1 << 3)) { /* TIMEOUT */
402 /* Handle TCO timeout */
403 printk(BIOS_DEBUG
, "TCO Timeout.\n");
407 static void southbridge_smi_periodic(void)
409 u32 reg32
= inl(ACPI_BASE_ADDRESS
+ SMI_EN
);
411 /* Are periodic SMIs enabled? */
412 if ((reg32
& PERIODIC_EN
) == 0)
415 printk(BIOS_DEBUG
, "Periodic SMI.\n");
418 static void southbridge_smi_monitor(void)
420 #define IOTRAP(x) (trap_sts & (1 << x))
421 u32 trap_sts
, trap_cycle
;
424 /* TRSR - Trap Status Register */
425 pcr_read32(PID_PSTH
, R_PCH_PCR_PSTH_TRPST
, &trap_sts
);
426 /* Clear trap(s) in TRSR */
427 pcr_write8(PID_PSTH
, R_PCH_PCR_PSTH_TRPST
, trap_sts
);
429 /* TRPC - Trapped cycle */
430 pcr_read32(PID_PSTH
, R_PCH_PCR_PSTH_TRPC
, &trap_cycle
);
431 for (i
= 16; i
< 20; i
++) {
432 if (trap_cycle
& (1 << i
))
433 mask
|= (0xff << ((i
- 16) << 2));
437 /* IOTRAP(3) SMI function call */
439 if (gnvs
&& gnvs
->smif
)
440 io_trap_handler(gnvs
->smif
); /* call function smif */
445 * IOTRAP(2) currently unused
446 * IOTRAP(1) currently unused
451 if (!(trap_cycle
& (1 << 24))) { /* It's a write */
452 printk(BIOS_DEBUG
, "SMI1 command\n");
453 /* Trapped write data */
454 pcr_read32(PID_PSTH
, R_PCH_PCR_PSTH_TRPD
, &data
);
459 printk(BIOS_DEBUG
, " trapped io address = 0x%x\n",
460 trap_cycle
& 0xfffc);
461 for (i
= 0; i
< 4; i
++)
463 printk(BIOS_DEBUG
, " TRAP = %d\n", i
);
464 printk(BIOS_DEBUG
, " AHBE = %x\n", (trap_cycle
>> 16) & 0xf);
465 printk(BIOS_DEBUG
, " MASK = 0x%08x\n", mask
);
466 printk(BIOS_DEBUG
, " read/write: %s\n",
467 (trap_cycle
& (1 << 24)) ? "read" : "write");
469 if (!(trap_cycle
& (1 << 24))) {
471 pcr_read32(PID_PSTH
, R_PCH_PCR_PSTH_TRPD
, &data
);
472 printk(BIOS_DEBUG
, " iotrap written data = 0x%08x\n", data
);
477 typedef void (*smi_handler_t
)(void);
479 static smi_handler_t southbridge_smi
[SMI_STS_BITS
] = {
480 [SMI_ON_SLP_EN_STS_BIT
] = southbridge_smi_sleep
,
481 [APM_STS_BIT
] = southbridge_smi_apmc
,
482 [PM1_STS_BIT
] = southbridge_smi_pm1
,
483 [GPE0_STS_BIT
] = southbridge_smi_gpe0
,
484 [GPIO_STS_BIT
] = southbridge_smi_gpi
,
485 [MCSMI_STS_BIT
] = southbridge_smi_mc
,
486 [TCO_STS_BIT
] = southbridge_smi_tco
,
487 [PERIODIC_STS_BIT
] = southbridge_smi_periodic
,
488 [MONITOR_STS_BIT
] = southbridge_smi_monitor
,
492 * Interrupt handler for SMI#
494 void southbridge_smi_handler(void)
500 * We need to clear the SMI status registers, or we won't see what's
501 * happening in the following calls.
503 smi_sts
= clear_smi_status();
505 /* Call SMI sub handler for each of the status bits */
506 for (i
= 0; i
< ARRAY_SIZE(southbridge_smi
); i
++) {
507 if (smi_sts
& (1 << i
)) {
508 if (southbridge_smi
[i
]) {
509 southbridge_smi
[i
]();
512 "SMI_STS[%d] occured, but no handler available.\n",