broadwell: Clean up SMM code
- Use device macros from pci_devs.h - Use base addresses from iobase.h - Clean up some code and comment formatting - Remove the SMI that would route USB to XHCI since this is now done by default at boot time. BUG=chrome-os-partner:28234 TEST=None Change-Id: If448b28f2c41c4533c449da8cf63f261c38b5939 Signed-off-by: Duncan Laurie <dlaurie@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/199391 Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
ddc4c116b4
commit
8295e56c9b
3 changed files with 40 additions and 67 deletions
|
|
@ -26,16 +26,19 @@
|
|||
#include <cpu/x86/cache.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <string.h>
|
||||
#include "pch.h"
|
||||
#include <broadwell/iomap.h>
|
||||
#include <broadwell/pch.h>
|
||||
#include <broadwell/pm.h>
|
||||
#include <broadwell/smm.h>
|
||||
|
||||
void southbridge_smm_clear_state(void)
|
||||
{
|
||||
u32 smi_en;
|
||||
|
||||
printk(BIOS_DEBUG, "Initializing Southbridge SMI...");
|
||||
printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", get_pmbase());
|
||||
printk(BIOS_SPEW, " ... pmbase = 0x%04x\n", ACPI_BASE_ADDRESS);
|
||||
|
||||
smi_en = inl(get_pmbase() + SMI_EN);
|
||||
smi_en = inl(ACPI_BASE_ADDRESS + SMI_EN);
|
||||
if (smi_en & APMC_EN) {
|
||||
printk(BIOS_INFO, "SMI# handler already enabled?\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -26,16 +26,21 @@
|
|||
#include <cpu/x86/cache.h>
|
||||
#include <device/pci_def.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <spi-generic.h>
|
||||
#include <elog.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include "pch.h"
|
||||
|
||||
#include "nvs.h"
|
||||
|
||||
#include <broadwell/lpc.h>
|
||||
#include <broadwell/nvs.h>
|
||||
#include <broadwell/pci_devs.h>
|
||||
#include <broadwell/pm.h>
|
||||
#include <broadwell/rcba.h>
|
||||
#include <broadwell/smm.h>
|
||||
#include <broadwell/xhci.h>
|
||||
|
||||
static u8 smm_initialized = 0;
|
||||
|
||||
/* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
|
||||
/*
|
||||
* GNVS needs to be updated by an 0xEA PM Trap (B2) after it has been located
|
||||
* by coreboot.
|
||||
*/
|
||||
static global_nvs_t *gnvs;
|
||||
|
|
@ -111,9 +116,8 @@ static void southbridge_smi_sleep(void)
|
|||
u32 reg32;
|
||||
u8 slp_typ;
|
||||
u8 s5pwr = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
|
||||
u16 pmbase = get_pmbase();
|
||||
|
||||
// save and recover RTC port values
|
||||
/* save and recover RTC port values */
|
||||
u8 tmp70, tmp72;
|
||||
tmp70 = inb(0x70);
|
||||
tmp72 = inb(0x72);
|
||||
|
|
@ -125,7 +129,7 @@ static void southbridge_smi_sleep(void)
|
|||
disable_smi(SLP_SMI_EN);
|
||||
|
||||
/* Figure out SLP_TYP */
|
||||
reg32 = inl(pmbase + PM1_CNT);
|
||||
reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
|
||||
printk(BIOS_SPEW, "SMI#: SLP = 0x%08x\n", reg32);
|
||||
slp_typ = (reg32 >> 10) & 7;
|
||||
|
||||
|
|
@ -133,11 +137,7 @@ static void southbridge_smi_sleep(void)
|
|||
mainboard_smi_sleep(slp_typ-2);
|
||||
|
||||
/* USB sleep preparations */
|
||||
#if !CONFIG_FINALIZE_USB_ROUTE_XHCI
|
||||
usb_ehci_sleep_prepare(PCH_EHCI1_DEV, slp_typ);
|
||||
usb_ehci_sleep_prepare(PCH_EHCI2_DEV, slp_typ);
|
||||
#endif
|
||||
usb_xhci_sleep_prepare(PCH_XHCI_DEV, slp_typ);
|
||||
usb_xhci_sleep_prepare(PCH_DEV_XHCI, slp_typ);
|
||||
|
||||
#if CONFIG_ELOG_GSMI
|
||||
/* Log S3, S4, and S5 entry */
|
||||
|
|
@ -173,13 +173,12 @@ static void southbridge_smi_sleep(void)
|
|||
/* Always set the flag in case CMOS was changed on runtime. For
|
||||
* "KEEP", switch to "OFF" - KEEP is software emulated
|
||||
*/
|
||||
reg8 = pci_read_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3);
|
||||
if (s5pwr == MAINBOARD_POWER_ON) {
|
||||
reg8 = pci_read_config8(PCH_DEV_LPC, GEN_PMCON_3);
|
||||
if (s5pwr == MAINBOARD_POWER_ON)
|
||||
reg8 &= ~1;
|
||||
} else {
|
||||
else
|
||||
reg8 |= 1;
|
||||
}
|
||||
pci_write_config8(PCI_DEV(0, 0x1f, 0), GEN_PMCON_3, reg8);
|
||||
pci_write_config8(PCH_DEV_LPC, GEN_PMCON_3, reg8);
|
||||
|
||||
/* also iterates over all bridges on bus 0 */
|
||||
busmaster_disable_on_bus(0);
|
||||
|
|
@ -189,7 +188,8 @@ static void southbridge_smi_sleep(void)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Write back to the SLP register to cause the originally intended
|
||||
/*
|
||||
* Write back to the SLP register to cause the originally intended
|
||||
* event again. We need to set BIT13 (SLP_EN) though to make the
|
||||
* sleep happen.
|
||||
*/
|
||||
|
|
@ -199,11 +199,12 @@ static void southbridge_smi_sleep(void)
|
|||
if (slp_typ > 1)
|
||||
hlt();
|
||||
|
||||
/* In most sleep states, the code flow of this function ends at
|
||||
/*
|
||||
* In most sleep states, the code flow of this function ends at
|
||||
* 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(pmbase + PM1_CNT);
|
||||
reg32 = inl(ACPI_BASE_ADDRESS + PM1_CNT);
|
||||
if (reg32 & SCI_EN) {
|
||||
/* The OS is not an ACPI OS, so we set the state to S0 */
|
||||
disable_pm1_control(SLP_EN | SLP_TYP);
|
||||
|
|
@ -295,17 +296,9 @@ static void southbridge_smi_apmc(void)
|
|||
reg8 = inb(APM_CNT);
|
||||
switch (reg8) {
|
||||
case APM_CNT_CST_CONTROL:
|
||||
/* Calling this function seems to cause
|
||||
* some kind of race condition in Linux
|
||||
* and causes a kernel oops
|
||||
*/
|
||||
printk(BIOS_DEBUG, "C-state control\n");
|
||||
break;
|
||||
case APM_CNT_PST_CONTROL:
|
||||
/* Calling this function seems to cause
|
||||
* some kind of race condition in Linux
|
||||
* and causes a kernel oops
|
||||
*/
|
||||
printk(BIOS_DEBUG, "P-state control\n");
|
||||
break;
|
||||
case APM_CNT_ACPI_DISABLE:
|
||||
|
|
@ -333,9 +326,6 @@ static void southbridge_smi_apmc(void)
|
|||
printk(BIOS_DEBUG, "SMI#: Setting GNVS to %p\n", gnvs);
|
||||
}
|
||||
break;
|
||||
case 0xca:
|
||||
usb_xhci_route_all();
|
||||
break;
|
||||
#if CONFIG_ELOG_GSMI
|
||||
case ELOG_GSMI_APM_CNT:
|
||||
southbridge_smi_gsmi();
|
||||
|
|
@ -354,7 +344,7 @@ static void southbridge_smi_pm1(void)
|
|||
* on a power button event.
|
||||
*/
|
||||
if (pm1_sts & PWRBTN_STS) {
|
||||
// power button pressed
|
||||
/* power button pressed */
|
||||
#if CONFIG_ELOG_GSMI
|
||||
elog_add_event(ELOG_TYPE_POWER_BUTTON);
|
||||
#endif
|
||||
|
|
@ -378,9 +368,7 @@ static void southbridge_smi_gpi(void)
|
|||
|
||||
static void southbridge_smi_mc(void)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
reg32 = inl(get_pmbase() + SMI_EN);
|
||||
u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
|
||||
|
||||
/* Are microcontroller SMIs enabled? */
|
||||
if ((reg32 & MCSMI_EN) == 0)
|
||||
|
|
@ -389,8 +377,6 @@ static void southbridge_smi_mc(void)
|
|||
printk(BIOS_DEBUG, "Microcontroller SMI.\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void southbridge_smi_tco(void)
|
||||
{
|
||||
u32 tco_sts = clear_tco_status();
|
||||
|
|
@ -400,23 +386,21 @@ static void southbridge_smi_tco(void)
|
|||
return;
|
||||
|
||||
if (tco_sts & (1 << 8)) { // BIOSWR
|
||||
u8 bios_cntl;
|
||||
|
||||
bios_cntl = pci_read_config16(PCI_DEV(0, 0x1f, 0), 0xdc);
|
||||
u8 bios_cntl = pci_read_config16(PCH_DEV_LPC, BIOS_CNTL);
|
||||
|
||||
if (bios_cntl & 1) {
|
||||
/* BWE is RW, so the SMI was caused by a
|
||||
/*
|
||||
* BWE is RW, so the SMI was caused by a
|
||||
* write to BWE, not by a write to the BIOS
|
||||
*/
|
||||
|
||||
/* This is the place where we notice someone
|
||||
*
|
||||
* This is the place where we notice someone
|
||||
* is trying to tinker with the BIOS. We are
|
||||
* trying to be nice and just ignore it. A more
|
||||
* resolute answer would be to power down the
|
||||
* box.
|
||||
*/
|
||||
printk(BIOS_DEBUG, "Switching back to RO\n");
|
||||
pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xdc,
|
||||
pci_write_config32(PCH_DEV_LPC, BIOS_CNTL,
|
||||
(bios_cntl & ~1));
|
||||
} /* No else for now? */
|
||||
} else if (tco_sts & (1 << 3)) { /* TIMEOUT */
|
||||
|
|
@ -427,9 +411,7 @@ static void southbridge_smi_tco(void)
|
|||
|
||||
static void southbridge_smi_periodic(void)
|
||||
{
|
||||
u32 reg32;
|
||||
|
||||
reg32 = inl(get_pmbase() + SMI_EN);
|
||||
u32 reg32 = inl(ACPI_BASE_ADDRESS + SMI_EN);
|
||||
|
||||
/* Are periodic SMIs enabled? */
|
||||
if ((reg32 & PERIODIC_EN) == 0)
|
||||
|
|
|
|||
|
|
@ -29,12 +29,9 @@
|
|||
#include <cpu/x86/mtrr.h>
|
||||
#include <cpu/x86/smm.h>
|
||||
#include <console/console.h>
|
||||
#include <northbridge/intel/haswell/haswell.h>
|
||||
#include <southbridge/intel/lynxpoint/pch.h>
|
||||
#include "haswell.h"
|
||||
|
||||
#include <broadwell/cpu.h>
|
||||
#include <broadwell/msr.h>
|
||||
#include <broadwell/pci_devs.h>
|
||||
#include <broadwell/smm.h>
|
||||
#include <broadwell/systemagent.h>
|
||||
|
||||
|
|
@ -326,11 +323,6 @@ static void setup_ied_area(struct smm_relocation_params *params)
|
|||
|
||||
/* Zero out 32KiB at IEDBASE + 1MiB */
|
||||
memset(ied_base + (1 << 20), 0, (32 << 10));
|
||||
|
||||
/* According to the BWG MP init section 2MiB of memory at IEDBASE +
|
||||
* 2MiB should be zeroed as well. However, I suspect what is inteneded
|
||||
* is to clear the memory covered by EMRR. TODO(adurbin): figure out if * this is really required. */
|
||||
//memset(ied_base + (2 << 20), 0, (2 << 20));
|
||||
}
|
||||
|
||||
static int install_permanent_handler(int num_cpus,
|
||||
|
|
@ -359,14 +351,12 @@ static int install_permanent_handler(int num_cpus,
|
|||
|
||||
static int cpu_smm_setup(void)
|
||||
{
|
||||
device_t dev;
|
||||
device_t dev = SA_DEV_ROOT;
|
||||
int num_cpus;
|
||||
msr_t msr;
|
||||
|
||||
printk(BIOS_DEBUG, "Setting up SMI for CPU\n");
|
||||
|
||||
dev = dev_find_slot(0, PCI_DEVFN(0, 0));
|
||||
|
||||
fill_in_relocation_params(dev, &smm_reloc_params);
|
||||
|
||||
setup_ied_area(&smm_reloc_params);
|
||||
|
|
@ -445,7 +435,5 @@ void smm_lock(void)
|
|||
* 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);
|
||||
pci_write_config8(SA_DEV_ROOT, SMRAM, D_LCK | G_SMRAME | C_BASE_SEG);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue