diff options
author | Aaron Durbin <adurbin@chromium.org> | 2012-12-21 21:21:48 -0600 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2013-03-18 17:07:50 +0100 |
commit | 29ffa54969414b833de5c61b507b061f920d650b (patch) | |
tree | e359cc2f27216e9d10e980cce2a2d7c0745729e5 /src/southbridge/intel/lynxpoint/smihandler.c | |
parent | b7ecf6d83047e70ed5846ac35833a04983318b9c (diff) |
haswell: Use SMM Modules
This commit adds support for using the SMM modules for haswell-based
boards. The SMI handling was also refactored to put the relocation
handler and permanent SMM handler loading in the cpu directory. All
tseg adjustment support is dropped by relying on the SMM module support
to perform the necessary relocations.
Change-Id: I8dd23610772fc4408567d9f4adf339596eac7b1f
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/2728
Tested-by: build bot (Jenkins)
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Diffstat (limited to 'src/southbridge/intel/lynxpoint/smihandler.c')
-rw-r--r-- | src/southbridge/intel/lynxpoint/smihandler.c | 82 |
1 files changed, 17 insertions, 65 deletions
diff --git a/src/southbridge/intel/lynxpoint/smihandler.c b/src/southbridge/intel/lynxpoint/smihandler.c index 7c982d129a..48dca2c8fd 100644 --- a/src/southbridge/intel/lynxpoint/smihandler.c +++ b/src/southbridge/intel/lynxpoint/smihandler.c @@ -33,12 +33,6 @@ #include "nvs.h" -/* We are using PCIe accesses for now - * 1. the chipset can do it - * 2. we don't need to worry about how we leave 0xcf8/0xcfc behind - */ -#include <northbridge/intel/haswell/haswell.h> - /* While we read PMBASE dynamically in case it changed, let's * initialize it with a sane value */ @@ -53,28 +47,12 @@ static u8 smm_initialized = 0; /* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located * by coreboot. */ -static global_nvs_t *gnvs = (global_nvs_t *)0x0; +static global_nvs_t *gnvs; global_nvs_t *smm_get_gnvs(void) { return gnvs; } -#if CONFIG_SMM_TSEG -static u32 tseg_base = 0; -u32 smi_get_tseg_base(void) -{ - if (!tseg_base) - tseg_base = pci_read_config32(PCI_DEV(0, 0, 0), TSEG) & ~1; - return tseg_base; -} -void tseg_relocate(void **ptr) -{ - /* Adjust pointer with TSEG base */ - if (*ptr && *ptr < (void*)smi_get_tseg_base()) - *ptr = (void *)(((u8*)*ptr) + smi_get_tseg_base()); -} -#endif - /** * @brief read and clear PM1_STS * @return PM1_STS register @@ -290,7 +268,7 @@ static void busmaster_disable_on_bus(int bus) } } -static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_sleep(void) { u8 reg8; u32 reg32; @@ -305,8 +283,6 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat outb(tmp70, 0x70); outb(tmp72, 0x72); - void (*mainboard_sleep)(u8 slp_typ) = mainboard_smi_sleep; - /* First, disable further SMIs */ reg8 = inb(pmbase + SMI_EN); reg8 &= ~SLP_SMI_EN; @@ -318,9 +294,7 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat slp_typ = (reg32 >> 10) & 7; /* Do any mainboard sleep handling */ - tseg_relocate((void **)&mainboard_sleep); - if (mainboard_sleep) - mainboard_sleep(slp_typ-2); + mainboard_smi_sleep(slp_typ-2); #if CONFIG_ELOG_GSMI /* Log S3, S4, and S5 entry */ @@ -390,17 +364,14 @@ static void southbridge_smi_sleep(unsigned int node, smm_state_save_area_t *stat * core in case we are not running on the same core that * initiated the IO transaction. */ -/* FIXME: Confirm Haswell's SMM save state area structure. */ static em64t101_smm_state_save_area_t *smi_apmc_find_state_save(u8 cmd) { em64t101_smm_state_save_area_t *state; - u32 base = smi_get_tseg_base() + 0x8000 + 0x7d00; int node; /* Check all nodes looking for the one that issued the IO */ for (node = 0; node < CONFIG_MAX_CPUS; node++) { - state = (em64t101_smm_state_save_area_t *) - (base - (node * 0x400)); + state = smm_get_save_state(node); /* Check for Synchronous IO (bit0==1) */ if (!(state->io_misc_info & (1 << 0))) @@ -447,11 +418,10 @@ static void southbridge_smi_gsmi(void) } #endif -static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_apmc(void) { u32 pmctrl; u8 reg8; - int (*mainboard_apmc)(u8 apmc) = mainboard_smi_apmc; em64t101_smm_state_save_area_t *state; /* Emulate B2 register as the FADT / Linux expects it */ @@ -504,12 +474,10 @@ static void southbridge_smi_apmc(unsigned int node, smm_state_save_area_t *state #endif } - tseg_relocate((void **)&mainboard_apmc); - if (mainboard_apmc) - mainboard_apmc(reg8); + mainboard_smi_apmc(reg8); } -static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_pm1(void) { u16 pm1_sts; @@ -530,7 +498,7 @@ static void southbridge_smi_pm1(unsigned int node, smm_state_save_area_t *state_ } } -static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_gpe0(void) { u32 gpe0_sts; @@ -538,27 +506,20 @@ static void southbridge_smi_gpe0(unsigned int node, smm_state_save_area_t *state dump_gpe0_status(gpe0_sts); } -static void southbridge_smi_gpi(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_gpi(void) { - void (*mainboard_gpi)(u16 gpi_sts) = mainboard_smi_gpi; u16 reg16; reg16 = inw(pmbase + ALT_GP_SMI_STS); outw(reg16, pmbase + ALT_GP_SMI_STS); reg16 &= inw(pmbase + ALT_GP_SMI_EN); - tseg_relocate((void **)&mainboard_gpi); - if (mainboard_gpi) { - mainboard_gpi(reg16); - } else { - if (reg16) - printk(BIOS_DEBUG, "GPI (mask %04x)\n",reg16); - } + mainboard_smi_gpi(reg16); outw(reg16, pmbase + ALT_GP_SMI_STS); } -static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_mc(void) { u32 reg32; @@ -573,7 +534,7 @@ static void southbridge_smi_mc(unsigned int node, smm_state_save_area_t *state_s -static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_tco(void) { u32 tco_sts; @@ -610,7 +571,7 @@ static void southbridge_smi_tco(unsigned int node, smm_state_save_area_t *state_ } } -static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_periodic(void) { u32 reg32; @@ -623,7 +584,7 @@ static void southbridge_smi_periodic(unsigned int node, smm_state_save_area_t *s printk(BIOS_DEBUG, "Periodic SMI.\n"); } -static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *state_save) +static void southbridge_smi_monitor(void) { #define IOTRAP(x) (trap_sts & (1 << x)) u32 trap_sts, trap_cycle; @@ -677,8 +638,7 @@ static void southbridge_smi_monitor(unsigned int node, smm_state_save_area_t *st #undef IOTRAP } -typedef void (*smi_handler_t)(unsigned int node, - smm_state_save_area_t *state_save); +typedef void (*smi_handler_t)(void); static smi_handler_t southbridge_smi[32] = { NULL, // [0] reserved @@ -721,7 +681,7 @@ static smi_handler_t southbridge_smi[32] = { * @param smm_revision revision of the smm state save map */ -void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_save) +void southbridge_smi_handler(void) { int i, dump = 0; u32 smi_sts; @@ -738,15 +698,7 @@ void southbridge_smi_handler(unsigned int node, smm_state_save_area_t *state_sav for (i = 0; i < 31; i++) { if (smi_sts & (1 << i)) { if (southbridge_smi[i]) { -#if CONFIG_SMM_TSEG - smi_handler_t handler = (smi_handler_t) - ((u8*)southbridge_smi[i] + - smi_get_tseg_base()); - if (handler) - handler(node, state_save); -#else - southbridge_smi[i](node, state_save); -#endif + southbridge_smi[i](); } else { printk(BIOS_DEBUG, "SMI_STS[%d] occured, but no " "handler available.\n", i); |