From a3e41c089602c58409e8dfd4aceecbdd7d4f4a5b Mon Sep 17 00:00:00 2001 From: Vladimir Serbinenko Date: Thu, 28 May 2015 16:04:17 +0200 Subject: Migrate 206ax to SMM_MODULES This gets rid of ugly tseg_relocate for bd82x6x. This is backport of 29ffa54969414b833de5c61b507b061f920d650b to bd82x6x. Change-Id: I0f52540851ce8a7edaac257a2aa83d543bb5e530 Signed-off-by: Vladimir Serbinenko Reviewed-on: http://review.coreboot.org/10351 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin --- src/southbridge/intel/bd82x6x/smi.c | 99 +++++++------------------------------ 1 file changed, 18 insertions(+), 81 deletions(-) (limited to 'src/southbridge/intel/bd82x6x/smi.c') diff --git a/src/southbridge/intel/bd82x6x/smi.c b/src/southbridge/intel/bd82x6x/smi.c index b60c3648ff..59a9c012e5 100644 --- a/src/southbridge/intel/bd82x6x/smi.c +++ b/src/southbridge/intel/bd82x6x/smi.c @@ -28,10 +28,6 @@ #include #include #include "pch.h" -#include "northbridge/intel/sandybridge/sandybridge.h" - -extern unsigned char _binary_smm_start; -extern unsigned char _binary_smm_end; /* While we read PMBASE dynamically in case it changed, let's * initialize it with a sane value @@ -228,15 +224,18 @@ static void smi_set_eos(void) outb(reg8, pmbase + SMI_EN); } -extern uint8_t smm_relocation_start, smm_relocation_end; - -static void smm_relocate(void) +void southbridge_smm_init(void) { u32 smi_en; u16 pm1_en; u32 gpe0_en; - printk(BIOS_DEBUG, "Initializing SMM handler..."); +#if CONFIG_ELOG + /* Log events from chipset before clearing */ + pch_log_state(); +#endif + + printk(BIOS_DEBUG, "Initializing southbridge SMI..."); pmbase = pci_read_config32(dev_find_slot(0, PCI_DEVFN(0x1f, 0)), PMBASE) & 0xff80; @@ -249,10 +248,6 @@ static void smm_relocate(void) return; } - /* copy the SMM relocation code */ - memcpy((void *)0x38000, &smm_relocation_start, - &smm_relocation_end - &smm_relocation_start); - printk(BIOS_DEBUG, "\n"); dump_smi_status(reset_smi_status()); dump_pm1_status(reset_pm1_status()); @@ -301,7 +296,10 @@ static void smm_relocate(void) smi_en |= EOS | GBL_SMI_EN; outl(smi_en, pmbase + SMI_EN); +} +void southbridge_trigger_smi(void) +{ /** * There are several methods of raising a controlled SMI# via * software, among them: @@ -320,79 +318,18 @@ static void smm_relocate(void) outb(0x00, 0xb2); } -static int smm_handler_copied = 0; - -static void smm_install(void) +void southbridge_clear_smi_status(void) { - device_t dev = dev_find_slot(0, PCI_DEVFN(0, 0)); - u32 smm_base = 0xa0000; - struct ied_header ied = { - .signature = "INTEL RSVD", - .size = IED_SIZE, - .reserved = {0}, - }; - - /* The first CPU running this gets to copy the SMM handler. But not all - * of them. - */ - if (smm_handler_copied) - return; - smm_handler_copied = 1; - - /* enable the SMM memory window */ - pci_write_config8(dev, SMRAM, D_OPEN | G_SMRAME | C_BASE_SEG); - -#if CONFIG_SMM_TSEG - smm_base = pci_read_config32(dev, TSEG) & ~1; -#endif - - /* copy the real SMM handler */ - printk(BIOS_DEBUG, "Installing SMM handler to 0x%08x\n", smm_base); - memcpy((void *)smm_base, &_binary_smm_start, - (size_t)(&_binary_smm_end - &_binary_smm_start)); - - /* copy the IED header into place */ - if (CONFIG_SMM_TSEG_SIZE > IED_SIZE) { - /* Top of TSEG region */ - smm_base += CONFIG_SMM_TSEG_SIZE - IED_SIZE; - printk(BIOS_DEBUG, "Installing IED header to 0x%08x\n", - smm_base); - memcpy((void *)smm_base, &ied, sizeof(ied)); - } - wbinvd(); - - /* close the SMM memory window and enable normal SMM */ - pci_write_config8(dev, SMRAM, G_SMRAME | C_BASE_SEG); -} - -void smm_init(void) -{ -#if CONFIG_ELOG - /* Log events from chipset before clearing */ - pch_log_state(); -#endif - - /* Put SMM code to 0xa0000 */ - smm_install(); - - /* Put relocation code to 0x38000 and relocate SMBASE */ - smm_relocate(); - - /* We're done. Make sure SMIs can happen! */ + /* Clear SMI status */ + reset_smi_status(); + + /* Clear PM1 status */ + reset_pm1_status(); + + /* Set EOS bit so other SMIs can occur. */ smi_set_eos(); } -void smm_lock(void) -{ - /* LOCK the SMM memory window and enable normal SMM. - * After running this function, only a full reset can - * make the SMM registers writable again. - */ - printk(BIOS_DEBUG, "Locking SMM.\n"); - pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM, - D_LCK | G_SMRAME | C_BASE_SEG); -} - void smm_setup_structures(void *gnvs, void *tcg, void *smi1) { /* -- cgit v1.2.3