soc/intel/common: Add missing SoC common function into SMM library

Modify SMM common code in order to accommodate SKL, CNL, APL, GLK
SOC code.

Change-Id: Ie9f90df3336c1278b73284815b5197400512c1d2
Signed-off-by: Subrata Banik <subrata.banik@intel.com>
Reviewed-on: https://review.coreboot.org/22869
Reviewed-by: Furquan Shaikh <furquan@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2017-12-14 18:22:13 +05:30
parent 9c3a7b6a17
commit 47a655cde3
8 changed files with 76 additions and 8 deletions

View File

@ -238,7 +238,7 @@ static void relocation_handler(int cpu, uintptr_t curr_smbase,
static void post_mp_init(void)
{
smm_southbridge_enable();
smm_southbridge_enable(PWRBTN_EN | GBL_EN);
if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX))
mp_run_on_all_cpus(sgx_configure, 2000);

View File

@ -34,6 +34,16 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void)
return &em64t100_smm_ops;
}
/* SMI handlers that should be serviced in SCI mode too. */
uint32_t smi_handler_get_sci_mask(void)
{
uint32_t sci_mask =
SMI_HANDLER_SCI_EN(APM_SMI_STS) |
SMI_HANDLER_SCI_EN(SLP_SMI_STS);
return sci_mask;
}
const smi_handler_t southbridge_smi[32] = {
[SLP_SMI_STS] = smihandler_southbridge_sleep,
[APM_SMI_STS] = smihandler_southbridge_apmc,

View File

@ -26,6 +26,7 @@
#include <soc/cpu.h>
#include <soc/msr.h>
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/smm.h>
static void soc_fsp_load(void)
@ -216,7 +217,7 @@ static void post_mp_init(void)
* Now that all APs have been relocated as well as the BSP let SMIs
* start flowing.
*/
smm_southbridge_enable();
smm_southbridge_enable(PWRBTN_EN | GBL_EN);
/* Lock down the SMRAM space. */
smm_lock();

View File

@ -23,6 +23,16 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void)
return &em64t101_smm_ops;
}
/* SMI handlers that should be serviced in SCI mode too. */
uint32_t smi_handler_get_sci_mask(void)
{
uint32_t sci_mask =
SMI_HANDLER_SCI_EN(APM_STS_BIT) |
SMI_HANDLER_SCI_EN(SMI_ON_SLP_EN_STS_BIT);
return sci_mask;
}
const smi_handler_t southbridge_smi[SMI_STS_BITS] = {
[SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,
[APM_STS_BIT] = smihandler_southbridge_apmc,

View File

@ -60,6 +60,11 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void);
*/
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. */
uint32_t smi_handler_get_sci_mask(void);
/*
* This function should be implemented in SOC specific code to handle
* the SMI event on SLP_EN. The default functionality is provided in
@ -144,6 +149,12 @@ void smihandler_southbridge_espi(
*/
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
*/

View File

@ -29,7 +29,7 @@
* SMIs.
*/
void smm_southbridge_clear_state(void);
void smm_southbridge_enable(void);
void smm_southbridge_enable(uint16_t pm1_events);
/* API to get SMM region start and size based on Host Bridge register */
void smm_region_info(void **start, size_t *size);

View File

@ -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>
@ -35,11 +36,28 @@
/* GNVS needs to be set by coreboot initiating a software SMI. */
static struct global_nvs_t *gnvs;
/* SoC overrides. */
__attribute__((weak)) int smihandler_disable_busmaster(device_t dev)
{
return 1;
}
/* SMI handlers that should be serviced in SCI mode too. */
__attribute__((weak)) uint32_t smi_handler_get_sci_mask(void)
{
return 0; /* No valid SCI mask for SMI handler */
}
/*
* 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,
int cmd)
{
@ -175,6 +193,8 @@ void smihandler_southbridge_sleep(
/* 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 +221,7 @@ void smihandler_southbridge_sleep(
* 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 +259,9 @@ static void finalize(void)
}
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 +330,13 @@ void smihandler_southbridge_pm1(
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);
@ -337,6 +360,8 @@ void smihandler_southbridge_tco(
if (!tco_sts)
return;
smihandler_check_illegal_access(tco_sts);
if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
/* Handle TCO timeout */
printk(BIOS_DEBUG, "TCO Timeout.\n");
@ -391,6 +416,17 @@ void southbridge_smi_handler(void)
*/
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_get_sci_mask.
*/
if (pmc_read_pm1_control() & SCI_EN)
smi_sts &= smi_handler_get_sci_mask();
if (!smi_sts)
return;
save_state_ops = get_smm_save_state_ops();
/* Call SMI sub handler for each of the status bits */

View File

@ -38,11 +38,11 @@ void smm_southbridge_clear_state(void)
pmc_clear_all_gpe_status();
}
void smm_southbridge_enable(void)
void smm_southbridge_enable(uint16_t pm1_events)
{
printk(BIOS_DEBUG, "Enabling SMIs.\n");
/* Configure events */
pmc_enable_pm1(PWRBTN_EN | GBL_EN);
pmc_enable_pm1(pm1_events);
pmc_disable_std_gpe(PME_B0_EN);
/*