Subrata Banik has uploaded this change for review. ( https://review.coreboot.org/22869
Change subject: soc/intel/common: Add missing SoC common function into SMM library ......................................................................
soc/intel/common: Add missing SoC common function into SMM library
Modify SMM common code in order to accommodate Skylake SOC code.
Change-Id: Ie9f90df3336c1278b73284815b5197400512c1d2 Signed-off-by: Subrata Banik subrata.banik@intel.com --- M src/soc/intel/common/block/include/intelblocks/smihandler.h M src/soc/intel/common/block/include/intelblocks/smm.h M src/soc/intel/common/block/smm/smihandler.c M src/soc/intel/common/block/smm/smm.c 4 files changed, 45 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/69/22869/1
diff --git a/src/soc/intel/common/block/include/intelblocks/smihandler.h b/src/soc/intel/common/block/include/intelblocks/smihandler.h index 5df5552..cab8a1e 100644 --- a/src/soc/intel/common/block/include/intelblocks/smihandler.h +++ b/src/soc/intel/common/block/include/intelblocks/smihandler.h @@ -60,6 +60,11 @@ */ extern const smi_handler_t southbridge_smi[32];
+#define SMI_HANDLER_SCI_EN(__bit) (1 << (__bit)) + +/* SMI handlers that should be serviced in SCI mode too. */ +extern uint32_t smi_handler_sci_mask; + /* * This function should be implemented in SOC specific code to handle * the SMI event on SLP_EN. The default functionality is provided in @@ -145,6 +150,12 @@ int smihandler_disable_busmaster(device_t dev);
/* + * SoC needs to implement the mechanism to know if an illegal attempt + * has been made to write to the BIOS area. + */ +void smihandler_check_illegal_access(uint32_t tco_sts); + +/* * Returns gnvs pointer within SMM context */ struct global_nvs_t *smm_get_gnvs(void); diff --git a/src/soc/intel/common/block/include/intelblocks/smm.h b/src/soc/intel/common/block/include/intelblocks/smm.h index 84f34a5..54f9005 100644 --- a/src/soc/intel/common/block/include/intelblocks/smm.h +++ b/src/soc/intel/common/block/include/intelblocks/smm.h @@ -29,7 +29,7 @@ * SMIs. */ void smm_southbridge_clear_state(void); -void smm_southbridge_enable(void); +void smm_southbridge_enable(uint16_t events); /* API to get SMM region start and size based on Host Bridge register */ void smm_region_info(void **start, size_t *size);
diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index 7821dba..c01ed4f 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -21,6 +21,7 @@ #include <cpu/x86/smm.h> #include <device/pci_def.h> #include <elog.h> +#include <intelblocks/fast_spi.h> #include <intelblocks/pmclib.h> #include <intelblocks/smihandler.h> #include <intelblocks/uart.h> @@ -38,6 +39,15 @@ __attribute__((weak)) int smihandler_disable_busmaster(device_t dev) { return 1; +} + +/* + * SoC needs to implement the mechanism to know if an illegal attempt + * has been made to write to the BIOS area. + */ +__attribute__((weak)) void smihandler_check_illegal_access(uint32_t tco_sts) +{ + return; }
static void *find_save_state(const struct smm_save_state_ops *save_state_ops, @@ -175,6 +185,8 @@
/* Disable all GPE */ pmc_disable_all_gpe(); + /* Set which state system will be after power reapplied */ + pmc_soc_restore_power_failure(); /* also iterates over all bridges on bus 0 */ busmaster_disable_on_bus(0); break; @@ -201,8 +213,7 @@ * the line above. However, if we entered sleep state S1 and wake * up again, we will continue to execute code in this function. */ - reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT); - if (reg32 & SCI_EN) { + if (pmc_read_pm1_control() & SCI_EN) { /* The OS is not an ACPI OS, so we set the state to S0 */ pmc_disable_pm1_control(SLP_EN | SLP_TYP); } @@ -240,6 +251,9 @@ } finalize_done = 1;
+ if (IS_ENABLED(CONFIG_SPI_FLASH_SMM)) + /* Re-init SPI driver to handle locked BAR */ + fast_spi_init(); }
void smihandler_southbridge_apmc( @@ -308,12 +322,13 @@ const struct smm_save_state_ops *save_state_ops) { uint16_t pm1_sts = pmc_clear_pm1_status(); + u16 pm1_en = pmc_read_pm1_enable();
/* * While OSPM is not active, poweroff immediately * on a power button event. */ - if (pm1_sts & PWRBTN_STS) { + if ((pm1_sts & PWRBTN_STS) && (pm1_en & PWRBTN_EN)) { /* power button pressed */ if (IS_ENABLED(CONFIG_ELOG_GSMI)) elog_add_event(ELOG_TYPE_POWER_BUTTON); @@ -336,6 +351,8 @@ /* Any TCO event? */ if (!tco_sts) return; + + smihandler_check_illegal_access(tco_sts);
if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */ /* Handle TCO timeout */ @@ -391,6 +408,17 @@ */ smi_sts = pmc_clear_smi_status();
+ /* + * In SCI mode, execute only those SMI handlers that have + * declared themselves as available for service in that mode + * using smi_handler_sci_mask. + */ + if (pmc_read_pm1_control() & SCI_EN) + smi_sts &= smi_handler_sci_mask; + + if (!smi_sts) + return; + save_state_ops = get_smm_save_state_ops();
/* Call SMI sub handler for each of the status bits */ diff --git a/src/soc/intel/common/block/smm/smm.c b/src/soc/intel/common/block/smm/smm.c index d5f42a7..feb6ad0 100644 --- a/src/soc/intel/common/block/smm/smm.c +++ b/src/soc/intel/common/block/smm/smm.c @@ -38,11 +38,11 @@ pmc_clear_all_gpe_status(); }
-void smm_southbridge_enable(void) +void smm_southbridge_enable(uint16_t events) { printk(BIOS_DEBUG, "Enabling SMIs.\n"); /* Configure events */ - pmc_enable_pm1(PWRBTN_EN | GBL_EN); + pmc_enable_pm1(events); pmc_disable_std_gpe(PME_B0_EN);
/*