summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/skylake/chip.c89
-rw-r--r--src/soc/intel/skylake/chip.h90
-rw-r--r--src/soc/intel/skylake/finalize.c70
-rw-r--r--src/soc/intel/skylake/include/soc/lpc.h3
-rw-r--r--src/soc/intel/skylake/include/soc/pcr.h5
-rw-r--r--src/soc/intel/skylake/include/soc/spi.h5
6 files changed, 250 insertions, 12 deletions
diff --git a/src/soc/intel/skylake/chip.c b/src/soc/intel/skylake/chip.c
index 01279b8a4d..951e461ee1 100644
--- a/src/soc/intel/skylake/chip.c
+++ b/src/soc/intel/skylake/chip.c
@@ -321,9 +321,29 @@ void soc_silicon_init_params(SILICON_INIT_UPD *params)
params->DspEnable = config->DspEnable;
params->XdciEnable = config->XdciEnable;
params->Device4Enable = config->Device4Enable;
- params->RtcLock = config->RtcLock;
params->EnableSata = config->EnableSata;
params->SataMode = config->SataMode;
+ params->LockDownConfigGlobalSmi = config->LockDownConfigGlobalSmi;
+ params->LockDownConfigBiosInterface = config->LockDownConfigBiosInterface;
+ params->LockDownConfigRtcLock = config->LockDownConfigRtcLock;
+ params->LockDownConfigBiosLock = config->LockDownConfigBiosLock;
+ params->LockDownConfigSpiEiss = config->LockDownConfigSpiEiss;
+ params->PchConfigSubSystemVendorId = config->PchConfigSubSystemVendorId;
+ params->PchConfigSubSystemId = config->PchConfigSubSystemId;
+ params->WakeConfigWolEnableOverride = config->WakeConfigWolEnableOverride;
+ params->WakeConfigPcieWakeFromDeepSx = config->WakeConfigPcieWakeFromDeepSx;
+ params->PmConfigDeepSxPol = config->PmConfigDeepSxPol;
+ params->PmConfigSlpS3MinAssert = config->PmConfigSlpS3MinAssert;
+ params->PmConfigSlpS4MinAssert = config->PmConfigSlpS4MinAssert;
+ params->PmConfigSlpSusMinAssert = config->PmConfigSlpSusMinAssert;
+ params->PmConfigSlpAMinAssert = config->PmConfigSlpAMinAssert;
+ params->PmConfigPciClockRun = config->PmConfigPciClockRun;
+ params->PmConfigSlpStrchSusUp = config->PmConfigSlpStrchSusUp;
+ params->PmConfigPwrBtnOverridePeriod = config->PmConfigPwrBtnOverridePeriod;
+ params->PmConfigPwrCycDur = config->PmConfigPwrCycDur;
+ params->SerialIrqConfigSirqEnable = config->SerialIrqConfigSirqEnable;
+ params->SerialIrqConfigSirqMode = config->SerialIrqConfigSirqMode;
+ params->SerialIrqConfigStartFramePulse = config->SerialIrqConfigStartFramePulse;
/* Show SPI controller if enabled in devicetree.cb */
dev = dev_find_slot(0, PCH_DEVFN_SPI);
@@ -697,8 +717,6 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *original,
params->HsioMessaging);
fsp_display_upd_value("Heci3Enabled", 1, original->Heci3Enabled,
params->Heci3Enabled);
- fsp_display_upd_value("RtcLock", 1, original->RtcLock,
- params->RtcLock);
fsp_display_upd_value("EnableSata", 1, original->EnableSata,
params->EnableSata);
fsp_display_upd_value("SataMode", 1, original->SataMode,
@@ -742,6 +760,71 @@ void soc_display_silicon_init_params(const SILICON_INIT_UPD *original,
fsp_display_upd_value("TcoIrqEnable", 1,
original->TcoIrqEnable,
params->TcoIrqEnable);
+
+ fsp_display_upd_value("LockDownConfigGlobalSmi", 1,
+ original->LockDownConfigGlobalSmi,
+ params->LockDownConfigGlobalSmi);
+ fsp_display_upd_value("LockDownConfigBiosInterface", 1,
+ original->LockDownConfigBiosInterface,
+ params->LockDownConfigBiosInterface);
+ fsp_display_upd_value("LockDownConfigRtcLock", 1,
+ original->LockDownConfigRtcLock,
+ params->LockDownConfigRtcLock);
+ fsp_display_upd_value("LockDownConfigBiosLock", 1,
+ original->LockDownConfigBiosLock,
+ params->LockDownConfigBiosLock);
+ fsp_display_upd_value("LockDownConfigSpiEiss", 1,
+ original->LockDownConfigSpiEiss,
+ params->LockDownConfigSpiEiss);
+ fsp_display_upd_value("PchConfigSubSystemVendorId", 1,
+ original->PchConfigSubSystemVendorId,
+ params->PchConfigSubSystemVendorId);
+ fsp_display_upd_value("PchConfigSubSystemId", 1,
+ original->PchConfigSubSystemId,
+ params->PchConfigSubSystemId);
+ fsp_display_upd_value("WakeConfigWolEnableOverride", 1,
+ original->WakeConfigWolEnableOverride,
+ params->WakeConfigWolEnableOverride);
+ fsp_display_upd_value("WakeConfigPcieWakeFromDeepSx", 1,
+ original->WakeConfigPcieWakeFromDeepSx,
+ params->WakeConfigPcieWakeFromDeepSx);
+ fsp_display_upd_value("PmConfigDeepSxPol", 1,
+ original->PmConfigDeepSxPol,
+ params->PmConfigDeepSxPol);
+ fsp_display_upd_value("PmConfigSlpS3MinAssert", 1,
+ original->PmConfigSlpS3MinAssert,
+ params->PmConfigSlpS3MinAssert);
+ fsp_display_upd_value("PmConfigSlpS4MinAssert", 1,
+ original->PmConfigSlpS4MinAssert,
+ params->PmConfigSlpS4MinAssert);
+ fsp_display_upd_value("PmConfigSlpSusMinAssert", 1,
+ original->PmConfigSlpSusMinAssert,
+ params->PmConfigSlpSusMinAssert);
+ fsp_display_upd_value("PmConfigSlpAMinAssert", 1,
+ original->PmConfigSlpAMinAssert,
+ params->PmConfigSlpAMinAssert);
+ fsp_display_upd_value("PmConfigPciClockRun", 1,
+ original->PmConfigPciClockRun,
+ params->PmConfigPciClockRun);
+ fsp_display_upd_value("PmConfigSlpStrchSusUp", 1,
+ original->PmConfigSlpStrchSusUp,
+ params->PmConfigSlpStrchSusUp);
+ fsp_display_upd_value("PmConfigPwrBtnOverridePeriod", 1,
+ original->PmConfigPwrBtnOverridePeriod,
+ params->PmConfigPwrBtnOverridePeriod);
+ fsp_display_upd_value("PmConfigPwrCycDur", 1,
+ original->PmConfigPwrCycDur,
+ params->PmConfigPwrCycDur);
+ fsp_display_upd_value("SerialIrqConfigSirqEnable", 1,
+ original->SerialIrqConfigSirqEnable,
+ params->SerialIrqConfigSirqEnable);
+ fsp_display_upd_value("SerialIrqConfigSirqMode", 1,
+ original->SerialIrqConfigSirqMode,
+ params->SerialIrqConfigSirqMode);
+ fsp_display_upd_value("SerialIrqConfigStartFramePulse", 1,
+ original->SerialIrqConfigStartFramePulse,
+ params->SerialIrqConfigStartFramePulse);
+
}
static void pci_set_subsystem(device_t dev, unsigned vendor, unsigned device)
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index 0738b4cadd..94a2b73dcf 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -234,6 +234,96 @@ struct soc_intel_skylake_config {
/* TCO IRQ Select The valid values is 9, 10, 11, 20 21, 22, 23*/
u8 TcoIrqSelect;
u8 TcoIrqEnable;
+ /* Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit.*/
+ u8 LockDownConfigGlobalSmi;
+ /*
+ * Enable BIOS Interface Lock Down bit to prevent writes to the Backup
+ * Control Register. Top Swap bit and the General Control and Status
+ * Registers Boot BIOS Straps.
+ */
+ u8 LockDownConfigBiosInterface;
+ /*
+ * Enable RTC lower and upper 128 byte Lock bits to lock Bytes 38h-3Fh
+ * in the upper and and lower 128-byte bank of RTC RAM.
+ */
+ u8 LockDownConfigRtcLock;
+ /*
+ * When enabled, the BIOS Region can only be modified from SMM after
+ * EndOfDxe protocol is installed
+ */
+ u8 LockDownConfigBiosLock;
+ /*
+ * Enable InSMM.STS (EISS) in SPI If this bit is set, then WPD must be a
+ * '1' and InSMM.STS must be '1' also in order to write to BIOS regions of
+ * SPI Flash. If this bit is clear, then the InSMM.STS is a don't care. The
+ * BIOS must set the EISS bit while BIOS Guard support is enabled.
+ */
+ u8 LockDownConfigSpiEiss;
+ /* Subsystem Vendor ID of the PCH devices*/
+ u16 PchConfigSubSystemVendorId;
+ /* Subsystem ID of the PCH devices*/
+ u16 PchConfigSubSystemId;
+ /*
+ * Corresponds to the "WOL Enable Override" bit in the General PM
+ * Configuration B (GEN_PMCON_B) register
+ */
+ u8 WakeConfigWolEnableOverride;
+ /* Determine if enable PCIe to wake from deep Sx*/
+ u8 WakeConfigPcieWakeFromDeepSx;
+ /* Deep Sx Policy. Values 0: PchDeepSxPolDisable,
+ * 1: PchDpS5BatteryEn, 2: PchDpS5AlwaysEn, 3: PchDpS4S5BatteryEn,
+ * 4: PchDpS4S5AlwaysEn, 5: PchDpS3S4S5BatteryEn, 6: PchDpS3S4S5AlwaysEn
+ */
+ u8 PmConfigDeepSxPol;
+ /*
+ * SLP_S3 Minimum Assertion Width Policy. Values 0: PchSlpS360us,
+ * 1: PchSlpS31ms, 2: PchSlpS350ms, 3: PchSlpS32s.
+ */
+ u8 PmConfigSlpS3MinAssert;
+ /*
+ * SLP_S4 Minimum Assertion Width Policy. Values 0: PchSlpS4PchTime,
+ * 1: PchSlpS41s, 2: PchSlpS42s, 3: PchSlpS43s, 4: PchSlpS44s.
+ */
+ u8 PmConfigSlpS4MinAssert;
+ /*
+ * SLP_SUS Minimum Assertion Width Policy. Values 0: PchSlpSus0ms,
+ * 1: PchSlpSus500ms, 2: PchSlpSus1s, 3: PchSlpSus4s.
+ */
+ u8 PmConfigSlpSusMinAssert;
+ /*
+ * SLP_A Minimum Assertion Width Policy. Values 0: PchSlpA0ms,
+ * 1: PchSlpA4s, 2: PchSlpA98ms, 3: PchSlpA2s.
+ */
+ u8 PmConfigSlpAMinAssert;
+ /*
+ * This member describes whether or not the PCI ClockRun feature of PCH
+ * should be enabled. Values 0: Disabled, 1: Enabled
+ */
+ u8 PmConfigPciClockRun;
+ /*
+ * SLP_X Stretching After SUS Well Power Up. Values 0: Disabled, 1: Enabled
+ */
+ u8 PmConfigSlpStrchSusUp;
+ /*
+ * PCH power button override period.
+ * Values: 0x0 - 4s, 0x1 - 6s, 0x2 - 8s, 0x3 - 10s, 0x4 - 12s, 0x5 - 14s
+ */
+ u8 PmConfigPwrBtnOverridePeriod;
+ /*
+ * Reset Power Cycle Duration could be customized in the unit of second.
+ * PCH HW default is 4 seconds, and range is 1~4 seconds.
+ * Values: 0x0 - 0s, 0x1 - 1s, 0x2 - 2s, 0x3 - 3s, 0x4 - 4s
+ */
+ u8 PmConfigPwrCycDur;
+ /* Determines if enable Serial IRQ. Values 0: Disabled, 1: Enabled.*/
+ u8 SerialIrqConfigSirqEnable;
+ /* Serial IRQ Mode Select. Values: 0: PchQuietMode, 1: PchContinuousMode.*/
+ u8 SerialIrqConfigSirqMode;
+ /*
+ * Start Frame Pulse Width.
+ * Values: 0: PchSfpw4Clk, 1: PchSfpw6Clk, 2; PchSfpw8Clk.
+ */
+ u8 SerialIrqConfigStartFramePulse;
};
typedef struct soc_intel_skylake_config config_t;
diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c
index a382702ba0..e2577aadeb 100644
--- a/src/soc/intel/skylake/finalize.c
+++ b/src/soc/intel/skylake/finalize.c
@@ -16,12 +16,14 @@
#include <arch/io.h>
#include <bootstate.h>
+#include <chip.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 <soc/lpc.h>
#include <soc/pci_devs.h>
#include <soc/pcr.h>
#include <soc/pm.h>
@@ -35,7 +37,6 @@ static void pch_finalize_script(void)
device_t dev;
uint32_t reg32, hsfs;
void *spibar = get_spi_bar();
- u8 reg8;
u16 tcobase;
u16 tcocnt;
uint8_t *pmcbase;
@@ -51,19 +52,14 @@ static void pch_finalize_script(void)
hsfs |= SPIBAR_HSFS_FLOCKDN;
write32(spibar + SPIBAR_HSFS, hsfs);
- /*TCO Lock down*/
+ /*TCO Lock down */
tcobase = pmc_tco_regs();
tcocnt = inw(tcobase + TCO1_CNT);
tcocnt |= TCO_LOCK;
outw(tcocnt, tcobase + TCO1_CNT);
- /* Global SMI Lock */
- dev = PCH_DEV_PMC;
- reg8 = pci_read_config8(dev, GEN_PMCON_A);
- reg8 |= SMI_LOCK;
- pci_write_config8(dev, GEN_PMCON_A, reg8);
-
/* Lock down ABASE and sleep stretching policy */
+ dev = PCH_DEV_PMC;
reg32 = pci_read_config32(dev, GEN_PMCON_B);
reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);
pci_write_config32(dev, GEN_PMCON_B, reg32);
@@ -75,11 +71,69 @@ static void pch_finalize_script(void)
write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);
}
+static void soc_lockdown(void)
+{
+ u8 reg8;
+ device_t dev;
+ const struct device *dev1 = dev_find_slot(0, PCH_DEVFN_LPC);
+ const struct soc_intel_skylake_config *config = dev1->chip_info;
+
+ /* Global SMI Lock */
+ if (config->LockDownConfigGlobalSmi == 0) {
+ dev = PCH_DEV_PMC;
+ reg8 = pci_read_config8(dev, GEN_PMCON_A);
+ reg8 |= SMI_LOCK;
+ pci_write_config8(dev, GEN_PMCON_A, reg8);
+ }
+
+ /* Bios Interface Lock */
+ if (config->LockDownConfigBiosInterface == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_BILD);
+ /* Reads back for posted write to take effect */
+ pci_read_config8(PCH_DEV_LPC, BIOS_CNTL);
+ pci_write_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL,
+ pci_read_config32(PCH_DEV_SPI,
+ SPIBAR_BIOS_CNTL) |
+ SPIBAR_BC_BILD);
+ /* Reads back for posted write to take effect */
+ pci_read_config32(PCH_DEV_SPI, SPIBAR_BIOS_CNTL);
+ /* GCS reg of DMI */
+ pcr_andthenor8(PID_DMI, R_PCH_PCR_DMI_GCS, 0xFF,
+ B_PCH_PCR_DMI_GCS_BILD);
+ }
+
+ /* Bios Lock */
+ if (config->LockDownConfigBiosLock == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_LE);
+ pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_SPI,
+ BIOS_CNTL) | SPIBAR_BC_LE);
+ }
+
+ /* SPIEiss */
+ if (config->LockDownConfigSpiEiss == 0) {
+ pci_write_config8(PCH_DEV_LPC, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_LPC,
+ BIOS_CNTL) | LPC_BC_EISS);
+ pci_write_config8(PCH_DEV_SPI, BIOS_CNTL,
+ pci_read_config8(PCH_DEV_SPI,
+ SPIBAR_BIOS_CNTL) |
+ SPIBAR_BC_EISS);
+ }
+}
+
static void soc_finalize(void *unused)
{
printk(BIOS_DEBUG, "Finalizing chipset.\n");
+
pch_finalize_script();
+ soc_lockdown();
+
/* Indicate finalize step with post code */
post_code(POST_OS_BOOT);
}
diff --git a/src/soc/intel/skylake/include/soc/lpc.h b/src/soc/intel/skylake/include/soc/lpc.h
index 58b78b0b72..b46b8ca5ca 100644
--- a/src/soc/intel/skylake/include/soc/lpc.h
+++ b/src/soc/intel/skylake/include/soc/lpc.h
@@ -50,6 +50,9 @@
#define LPC_GEN4_DEC 0x90 /* LPC IF Generic Decode Range 4 */
#define LGMR 0x98 /* LPC Generic Memory Range */
#define BIOS_CNTL 0xdc
+#define LPC_BC_BILD (1 << 7) /* BILD */
+#define LPC_BC_LE (1 << 2) /* LE */
+#define LPC_BC_EISS (1 << 5) /* EISS */
#define PCCTL 0xE0 /* PCI Clock Control */
#define CLKRUN_EN (1 << 0)
#endif
diff --git a/src/soc/intel/skylake/include/soc/pcr.h b/src/soc/intel/skylake/include/soc/pcr.h
index bf3161b9ac..cb64af6578 100644
--- a/src/soc/intel/skylake/include/soc/pcr.h
+++ b/src/soc/intel/skylake/include/soc/pcr.h
@@ -31,11 +31,16 @@
#define R_PCH_PCR_DMI_LPCLGIR2 0x2734
#define R_PCH_PCR_DMI_LPCLGIR3 0x2738
#define R_PCH_PCR_DMI_LPCLGIR4 0x273c
+#define R_PCH_PCR_DMI_GCS 0x274C
+#define B_PCH_PCR_DMI_GCS_BILD (1 << 0)
#define R_PCH_PCR_DMI_LPCIOD 0x2770
#define R_PCH_PCR_DMI_LPCIOE 0x2774
/* RTC configuration */
#define R_PCH_PCR_RTC_CONF 0x3400
+#define B_PCH_PCR_RTC_CONF_UCMOS_LOCK (1 << 4)
+#define B_PCH_PCR_RTC_CONF_LCMOS_LOCK (1 << 3)
+#define B_PCH_PCR_RTC_CONF_RESERVED (1 << 31)
#define B_PCH_PCR_RTC_CONF_UCMOS_EN 0x4
/* ITSS PCRs*/
diff --git a/src/soc/intel/skylake/include/soc/spi.h b/src/soc/intel/skylake/include/soc/spi.h
index a24197b3ec..7991c1632a 100644
--- a/src/soc/intel/skylake/include/soc/spi.h
+++ b/src/soc/intel/skylake/include/soc/spi.h
@@ -114,8 +114,11 @@
#define FLCOMP_C0DEN_32MB 6
#define SPIBAR_BIOS_CNTL 0xDC
-#define SPIBAR_BC_WPD (1 << 0)
+#define SPIBAR_BC_BILD (1 << 7)
#define SPIBAR_BC_EISS (1 << 5)
+#define SPIBAR_BC_LE (1 << 2)
+#define SPIBAR_BC_WPD (1 << 0)
+
void *get_spi_bar(void);
#endif