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)
|
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))
|
if (IS_ENABLED(CONFIG_SOC_INTEL_COMMON_BLOCK_SGX))
|
||||||
mp_run_on_all_cpus(sgx_configure, 2000);
|
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;
|
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] = {
|
const smi_handler_t southbridge_smi[32] = {
|
||||||
[SLP_SMI_STS] = smihandler_southbridge_sleep,
|
[SLP_SMI_STS] = smihandler_southbridge_sleep,
|
||||||
[APM_SMI_STS] = smihandler_southbridge_apmc,
|
[APM_SMI_STS] = smihandler_southbridge_apmc,
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <soc/cpu.h>
|
#include <soc/cpu.h>
|
||||||
#include <soc/msr.h>
|
#include <soc/msr.h>
|
||||||
#include <soc/pci_devs.h>
|
#include <soc/pci_devs.h>
|
||||||
|
#include <soc/pm.h>
|
||||||
#include <soc/smm.h>
|
#include <soc/smm.h>
|
||||||
|
|
||||||
static void soc_fsp_load(void)
|
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
|
* Now that all APs have been relocated as well as the BSP let SMIs
|
||||||
* start flowing.
|
* start flowing.
|
||||||
*/
|
*/
|
||||||
smm_southbridge_enable();
|
smm_southbridge_enable(PWRBTN_EN | GBL_EN);
|
||||||
|
|
||||||
/* Lock down the SMRAM space. */
|
/* Lock down the SMRAM space. */
|
||||||
smm_lock();
|
smm_lock();
|
||||||
|
|
|
@ -23,6 +23,16 @@ const struct smm_save_state_ops *get_smm_save_state_ops(void)
|
||||||
return &em64t101_smm_ops;
|
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] = {
|
const smi_handler_t southbridge_smi[SMI_STS_BITS] = {
|
||||||
[SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,
|
[SMI_ON_SLP_EN_STS_BIT] = smihandler_southbridge_sleep,
|
||||||
[APM_STS_BIT] = smihandler_southbridge_apmc,
|
[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];
|
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
|
* This function should be implemented in SOC specific code to handle
|
||||||
* the SMI event on SLP_EN. The default functionality is provided in
|
* 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);
|
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
|
* Returns gnvs pointer within SMM context
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
* SMIs.
|
* SMIs.
|
||||||
*/
|
*/
|
||||||
void smm_southbridge_clear_state(void);
|
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 */
|
/* API to get SMM region start and size based on Host Bridge register */
|
||||||
void smm_region_info(void **start, size_t *size);
|
void smm_region_info(void **start, size_t *size);
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <elog.h>
|
#include <elog.h>
|
||||||
|
#include <intelblocks/fast_spi.h>
|
||||||
#include <intelblocks/pmclib.h>
|
#include <intelblocks/pmclib.h>
|
||||||
#include <intelblocks/smihandler.h>
|
#include <intelblocks/smihandler.h>
|
||||||
#include <intelblocks/uart.h>
|
#include <intelblocks/uart.h>
|
||||||
|
@ -35,11 +36,28 @@
|
||||||
/* GNVS needs to be set by coreboot initiating a software SMI. */
|
/* GNVS needs to be set by coreboot initiating a software SMI. */
|
||||||
static struct global_nvs_t *gnvs;
|
static struct global_nvs_t *gnvs;
|
||||||
|
|
||||||
|
/* SoC overrides. */
|
||||||
|
|
||||||
__attribute__((weak)) int smihandler_disable_busmaster(device_t dev)
|
__attribute__((weak)) int smihandler_disable_busmaster(device_t dev)
|
||||||
{
|
{
|
||||||
return 1;
|
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,
|
static void *find_save_state(const struct smm_save_state_ops *save_state_ops,
|
||||||
int cmd)
|
int cmd)
|
||||||
{
|
{
|
||||||
|
@ -175,6 +193,8 @@ void smihandler_southbridge_sleep(
|
||||||
|
|
||||||
/* Disable all GPE */
|
/* Disable all GPE */
|
||||||
pmc_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 */
|
/* also iterates over all bridges on bus 0 */
|
||||||
busmaster_disable_on_bus(0);
|
busmaster_disable_on_bus(0);
|
||||||
break;
|
break;
|
||||||
|
@ -201,8 +221,7 @@ void smihandler_southbridge_sleep(
|
||||||
* the line above. However, if we entered sleep state S1 and wake
|
* the line above. However, if we entered sleep state S1 and wake
|
||||||
* up again, we will continue to execute code in this function.
|
* up again, we will continue to execute code in this function.
|
||||||
*/
|
*/
|
||||||
reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
|
if (pmc_read_pm1_control() & SCI_EN) {
|
||||||
if (reg32 & SCI_EN) {
|
|
||||||
/* The OS is not an ACPI OS, so we set the state to S0 */
|
/* The OS is not an ACPI OS, so we set the state to S0 */
|
||||||
pmc_disable_pm1_control(SLP_EN | SLP_TYP);
|
pmc_disable_pm1_control(SLP_EN | SLP_TYP);
|
||||||
}
|
}
|
||||||
|
@ -240,6 +259,9 @@ static void finalize(void)
|
||||||
}
|
}
|
||||||
finalize_done = 1;
|
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(
|
void smihandler_southbridge_apmc(
|
||||||
|
@ -308,12 +330,13 @@ void smihandler_southbridge_pm1(
|
||||||
const struct smm_save_state_ops *save_state_ops)
|
const struct smm_save_state_ops *save_state_ops)
|
||||||
{
|
{
|
||||||
uint16_t pm1_sts = pmc_clear_pm1_status();
|
uint16_t pm1_sts = pmc_clear_pm1_status();
|
||||||
|
u16 pm1_en = pmc_read_pm1_enable();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* While OSPM is not active, poweroff immediately
|
* While OSPM is not active, poweroff immediately
|
||||||
* on a power button event.
|
* on a power button event.
|
||||||
*/
|
*/
|
||||||
if (pm1_sts & PWRBTN_STS) {
|
if ((pm1_sts & PWRBTN_STS) && (pm1_en & PWRBTN_EN)) {
|
||||||
/* power button pressed */
|
/* power button pressed */
|
||||||
if (IS_ENABLED(CONFIG_ELOG_GSMI))
|
if (IS_ENABLED(CONFIG_ELOG_GSMI))
|
||||||
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
||||||
|
@ -337,6 +360,8 @@ void smihandler_southbridge_tco(
|
||||||
if (!tco_sts)
|
if (!tco_sts)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
smihandler_check_illegal_access(tco_sts);
|
||||||
|
|
||||||
if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
|
if (tco_sts & TCO_TIMEOUT) { /* TIMEOUT */
|
||||||
/* Handle TCO timeout */
|
/* Handle TCO timeout */
|
||||||
printk(BIOS_DEBUG, "TCO Timeout.\n");
|
printk(BIOS_DEBUG, "TCO Timeout.\n");
|
||||||
|
@ -391,6 +416,17 @@ void southbridge_smi_handler(void)
|
||||||
*/
|
*/
|
||||||
smi_sts = pmc_clear_smi_status();
|
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();
|
save_state_ops = get_smm_save_state_ops();
|
||||||
|
|
||||||
/* Call SMI sub handler for each of the status bits */
|
/* 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();
|
pmc_clear_all_gpe_status();
|
||||||
}
|
}
|
||||||
|
|
||||||
void smm_southbridge_enable(void)
|
void smm_southbridge_enable(uint16_t pm1_events)
|
||||||
{
|
{
|
||||||
printk(BIOS_DEBUG, "Enabling SMIs.\n");
|
printk(BIOS_DEBUG, "Enabling SMIs.\n");
|
||||||
/* Configure events */
|
/* Configure events */
|
||||||
pmc_enable_pm1(PWRBTN_EN | GBL_EN);
|
pmc_enable_pm1(pm1_events);
|
||||||
pmc_disable_std_gpe(PME_B0_EN);
|
pmc_disable_std_gpe(PME_B0_EN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue