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:
parent
9c3a7b6a17
commit
47a655cde3
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue