broadwell: Update and unify the finalize steps

- Move all of the finalize steps from cpu/northbridge/southbridge
into this one file and convert it to (largely) use reg_script format.
- Add a BOOT_STATE_INIT_ENTRY to have this function called as the
last step before boot and resume instead of triggering it from SMI.
- Re-initialize the SPI controller after lockdown so it still works.
- Issue IO write to finalize SMM which will tell SMM to re-init SPI
controller driver after lockdown.

BUG=chrome-os-partner:28234
TEST=None

Change-Id: I0ef6506954c193ae668b26ed10160ad4852af5e2
Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/199390
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
Duncan Laurie 2014-05-02 14:34:12 -07:00 committed by chrome-internal-fetch
commit ddc4c116b4
2 changed files with 118 additions and 27 deletions

View file

@ -18,38 +18,110 @@
*/
#include <arch/io.h>
#include <bootstate.h>
#include <console/console.h>
#include <console/post_codes.h>
#include <cpu/x86/smm.h>
#include <reg_script.h>
#include <spi-generic.h>
#include <stdlib.h>
#include "haswell.h"
#include <broadwell/pci_devs.h>
#include <broadwell/lpc.h>
#include <broadwell/me.h>
#include <broadwell/rcba.h>
#include <broadwell/spi.h>
#include <broadwell/systemagent.h>
#define PCI_DEV_HSW PCI_DEV(0, 0, 0)
const struct reg_script system_agent_finalize_script[] = {
REG_PCI_OR16(0x50, 1 << 0), /* GGC */
REG_PCI_OR32(0x5c, 1 << 0), /* DPR */
REG_PCI_OR32(0x78, 1 << 10), /* ME */
REG_PCI_OR32(0x90, 1 << 0), /* REMAPBASE */
REG_PCI_OR32(0x98, 1 << 0), /* REMAPLIMIT */
REG_PCI_OR32(0xa0, 1 << 0), /* TOM */
REG_PCI_OR32(0xa8, 1 << 0), /* TOUUD */
REG_PCI_OR32(0xb0, 1 << 0), /* BDSM */
REG_PCI_OR32(0xb4, 1 << 0), /* BGSM */
REG_PCI_OR32(0xb8, 1 << 0), /* TSEGMB */
REG_PCI_OR32(0xbc, 1 << 0), /* TOLUD */
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x5500, 1 << 0), /* PAVP */
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x5f00, 1 << 31), /* SA PM */
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x6020, 1 << 0), /* UMA GFX */
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x63fc, 1 << 0), /* VTDTRK */
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x6800, 1 << 31),
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x7000, 1 << 31),
REG_MMIO_OR32(MCH_BASE_ADDRESS + 0x77fc, 1 << 0),
REG_MMIO_WRITE8(MCH_BASE_ADDRESS + 0x50fc, 0x8f), /* MC */
void intel_northbridge_haswell_finalize_smm(void)
REG_SCRIPT_END
};
const struct reg_script pch_finalize_script[] = {
/* Set SPI opcode menu */
REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_PREOP,
SPI_OPPREFIX),
REG_MMIO_WRITE16(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_OPTYPE,
SPI_OPTYPE),
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET +
SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER),
REG_MMIO_WRITE32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET +
SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER),
/* Lock SPIBAR */
REG_MMIO_OR32(RCBA_BASE_ADDRESS + SPIBAR_OFFSET + SPIBAR_HSFS,
SPIBAR_HSFS_FLOCKDN),
/* TC Lockdown */
REG_MMIO_OR32(RCBA_BASE_ADDRESS + 0x0050, (1 << 31)),
/* BIOS Interface Lockdown */
REG_MMIO_OR32(RCBA_BASE_ADDRESS + GCS, (1 << 0)),
/* Function Disable SUS Well Lockdown */
REG_MMIO_OR8(RCBA_BASE_ADDRESS + FDSW, (1 << 7)),
/* Global SMI Lock */
REG_PCI_OR16(GEN_PMCON_1, SMI_LOCK),
/* GEN_PMCON Lock */
REG_PCI_OR8(GEN_PMCON_LOCK, SLP_STR_POL_LOCK | ACPI_BASE_LOCK),
/* PMSYNC */
REG_MMIO_OR32(RCBA_BASE_ADDRESS + PMSYNC_CONFIG, (1 << 31)),
REG_SCRIPT_END
};
static void broadwell_finalize(void *unused)
{
pci_or_config16(PCI_DEV_HSW, 0x50, 1 << 0); /* GGC */
pci_or_config32(PCI_DEV_HSW, 0x5c, 1 << 0); /* DPR */
pci_or_config32(PCI_DEV_HSW, 0x78, 1 << 10); /* ME */
pci_or_config32(PCI_DEV_HSW, 0x90, 1 << 0); /* REMAPBASE */
pci_or_config32(PCI_DEV_HSW, 0x98, 1 << 0); /* REMAPLIMIT */
pci_or_config32(PCI_DEV_HSW, 0xa0, 1 << 0); /* TOM */
pci_or_config32(PCI_DEV_HSW, 0xa8, 1 << 0); /* TOUUD */
pci_or_config32(PCI_DEV_HSW, 0xb0, 1 << 0); /* BDSM */
pci_or_config32(PCI_DEV_HSW, 0xb4, 1 << 0); /* BGSM */
pci_or_config32(PCI_DEV_HSW, 0xb8, 1 << 0); /* TSEGMB */
pci_or_config32(PCI_DEV_HSW, 0xbc, 1 << 0); /* TOLUD */
printk(BIOS_DEBUG, "Finalizing chipset.\n");
MCHBAR32_OR(0x5500, 1 << 0); /* PAVP */
MCHBAR32_OR(0x5f00, 1 << 31); /* SA PM */
MCHBAR32_OR(0x6020, 1 << 0); /* UMA GFX */
MCHBAR32_OR(0x63fc, 1 << 0); /* VTDTRK */
MCHBAR32_OR(0x6800, 1 << 31);
MCHBAR32_OR(0x7000, 1 << 31);
MCHBAR32_OR(0x77fc, 1 << 0);
reg_script_run_on_dev(SA_DEV_ROOT, system_agent_finalize_script);
reg_script_run_on_dev(PCH_DEV_LPC, pch_finalize_script);
/* Memory Controller Lockdown */
MCHBAR8(0x50fc) = 0x8f;
/* Read+write the following */
/* Read+Write the following registers */
MCHBAR32(0x6030) = MCHBAR32(0x6030);
MCHBAR32(0x6034) = MCHBAR32(0x6034);
MCHBAR32(0x6008) = MCHBAR32(0x6008);
RCBA32(0x21a4) = RCBA32(0x21a4);
/* Re-init SPI after lockdown */
spi_init();
/* Lock down management engine */
intel_me_finalize();
printk(BIOS_DEBUG, "Finalizing SMM.\n");
outb(APM_CNT_FINALIZE, APM_CNT);
/* Indicate finalize step with post code */
post_code(POST_OS_BOOT);
}
BOOT_STATE_INIT_ENTRIES(finalize) = {
BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,
broadwell_finalize, NULL),
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT,
broadwell_finalize, NULL),
};

View file

@ -269,6 +269,22 @@ static void southbridge_smi_gsmi(void)
}
#endif
static void finalize(void)
{
static int finalize_done;
if (finalize_done) {
printk(BIOS_DEBUG, "SMM already finalized.\n");
return;
}
finalize_done = 1;
#if CONFIG_SPI_FLASH_SMM
/* Re-init SPI driver to handle locked BAR */
spi_init();
#endif
}
static void southbridge_smi_apmc(void)
{
u8 reg8;
@ -300,6 +316,9 @@ static void southbridge_smi_apmc(void)
enable_pm1_control(SCI_EN);
printk(BIOS_DEBUG, "SMI#: ACPI enabled.\n");
break;
case APM_CNT_FINALIZE:
finalize();
break;
case APM_CNT_GNVS_UPDATE:
if (smm_initialized) {
printk(BIOS_DEBUG,