<p>Lijian Zhao has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/21943">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">soc/intel/cannonlake: Add finalized function<br><br>Before OS boot up, the following action need to be taken.<br>1.Lockdown PMC/SPI/DMI/TCO register.<br>2.Disable Sideband Access.<br>3.Disable Heci interface.<br>4.Disable PMtimer base on config settings.<br><br>TEST=Boot up into OS properly.<br><br>Change-Id: Icfa05b50fd76fbaeb856d398918990aedac4c5e6<br>Signed-off-by: Lijian Zhao <lijian.zhao@intel.com><br>---<br>M src/soc/intel/cannonlake/Makefile.inc<br>M src/soc/intel/cannonlake/chip.h<br>A src/soc/intel/cannonlake/finalize.c<br>M src/soc/intel/cannonlake/include/soc/pmc.h<br>A src/soc/intel/cannonlake/lockdown.c<br>5 files changed, 283 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/43/21943/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/src/soc/intel/cannonlake/Makefile.inc b/src/soc/intel/cannonlake/Makefile.inc<br>index 6fcee31..1076e10 100644<br>--- a/src/soc/intel/cannonlake/Makefile.inc<br>+++ b/src/soc/intel/cannonlake/Makefile.inc<br>@@ -30,6 +30,7 @@<br> ramstage-y += acpi.c<br> ramstage-y += chip.c<br> ramstage-y += cpu.c<br>+ramstage-y += finalize.c<br> ramstage-y += gpio.c<br> ramstage-y += gspi.c<br> ramstage-y += gpio.c<br>diff --git a/src/soc/intel/cannonlake/chip.h b/src/soc/intel/cannonlake/chip.h<br>index ee908f0..a5c4c6b 100644<br>--- a/src/soc/intel/cannonlake/chip.h<br>+++ b/src/soc/intel/cannonlake/chip.h<br>@@ -167,7 +167,8 @@<br> /* TCO IRQ Select. The valid value is 9, 10, 11, 20, 21, 22, 23 */<br> uint8_t TcoIrqSelect;<br> uint8_t TcoIrqEnable;<br>-<br>+ /* Enable SMI_LOCK bit to prevent writes to the Global SMI Enable bit.*/<br>+ uint8_t LockDownConfigGlobalSmi;<br> enum {<br> CHIPSET_LOCKDOWN_FSP = 0, /* FSP handles locking per UPDs */<br> CHIPSET_LOCKDOWN_COREBOOT, /* coreboot handles locking */<br>diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c<br>new file mode 100644<br>index 0000000..fccb056<br>--- /dev/null<br>+++ b/src/soc/intel/cannonlake/finalize.c<br>@@ -0,0 +1,171 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2014 Google Inc.<br>+ * Copyright (C) 2017 Intel Corporation.<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#include <arch/io.h><br>+#include <bootstate.h><br>+#include <chip.h><br>+#include <console/console.h><br>+#include <console/post_codes.h><br>+#include <cpu/x86/smm.h><br>+#include <device/pci.h><br>+#include <intelblocks/lpc_lib.h><br>+#include <intelblocks/pcr.h><br>+#include <reg_script.h><br>+#include <spi-generic.h><br>+#include <soc/p2sb.h><br>+#include <soc/pci_devs.h><br>+#include <soc/pcr_ids.h><br>+#include <soc/pm.h><br>+#include <soc/smbus.h><br>+#include <soc/systemagent.h><br>+#include <stdlib.h><br>+<br>+#define PSF_BASE_ADDRESS 0x300<br>+#define PCR_PSFX_T0_SHDW_PCIEN 0x1C<br>+#define PCR_PSFX_T0_SHDW_PCIEN_FUNDIS (1 << 8)<br>+<br>+static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask)<br>+{<br>+ uint32_t reg32;<br>+<br>+ reg32 = pci_read_config32(dev, PCH_P2SB_EPMASK(epmask_id));<br>+ pci_write_config32(dev, PCH_P2SB_EPMASK(epmask_id), reg32 | mask);<br>+}<br>+<br>+static void disable_sideband_access(void)<br>+{<br>+ device_t dev;<br>+ u8 reg8;<br>+ uint32_t mask;<br>+<br>+ dev = PCH_DEV_P2SB;<br>+<br>+ /* Remove the host accessing right to PSF register range. */<br>+ /* Set p2sb PCI offset EPMASK5 C4h [29, 28, 27, 26] to [1, 1, 1, 1] */<br>+ mask = (1 << 29) | (1 << 28) | (1 << 27) | (1 << 26);<br>+ pch_configure_endpoints(dev, 5, mask);<br>+<br>+ /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */<br>+ reg8 = pci_read_config8(dev, PCH_P2SB_E0 + 2);<br>+ pci_write_config8(dev, PCH_P2SB_E0 + 2, reg8 | (1 << 1));<br>+<br>+ /* hide p2sb device */<br>+ pci_write_config8(dev, PCH_P2SB_E0 + 1, 1);<br>+}<br>+<br>+static void pch_disable_heci(void)<br>+{<br>+ device_t dev = PCH_DEV_P2SB;<br>+<br>+ /*<br>+ * if p2sb device 1f.1 is not present or hidden in devicetree<br>+ * p2sb device becomes NULL<br>+ */<br>+ if (!dev)<br>+ return;<br>+<br>+ /* unhide p2sb device */<br>+ pci_write_config8(dev, PCH_P2SB_E0 + 1, 0);<br>+<br>+ /* disable heci */<br>+ pcr_or32(PID_PSF1, PSF_BASE_ADDRESS + PCR_PSFX_T0_SHDW_PCIEN,<br>+ PCR_PSFX_T0_SHDW_PCIEN_FUNDIS);<br>+<br>+ disable_sideband_access();<br>+}<br>+<br>+static void pch_finalize_script(void)<br>+{<br>+ device_t dev;<br>+ uint32_t reg32;<br>+ uint16_t tcobase, tcocnt;<br>+ uint8_t *pmcbase;<br>+ config_t *config;<br>+ uint8_t reg8;<br>+<br>+ /*TCO Lock down */<br>+ tcobase = smbus_tco_regs();<br>+ tcocnt = inw(tcobase + TCO1_CNT);<br>+ tcocnt |= TCO_LOCK;<br>+ outw(tcocnt, tcobase + TCO1_CNT);<br>+<br>+ /*<br>+ * Disable ACPI PM timer based on dt policy<br>+ *<br>+ * Disabling ACPI PM timer is necessary for XTAL OSC shutdown.<br>+ * Disabling ACPI PM timer also switches off TCO<br>+ */<br>+ dev = PCH_DEV_PMC;<br>+ config = dev->chip_info;<br>+ pmcbase = pmc_mmio_regs();<br>+ if (config->PmTimerDisabled) {<br>+ reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL);<br>+ reg8 |= (1 << 1);<br>+ write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8);<br>+ }<br>+<br>+ /* Disable XTAL shutdown qualification for low power idle. */<br>+ if (config->s0ix_enable) {<br>+ reg32 = read32(pmcbase + CPPMVRIC);<br>+ reg32 |= XTALSDQDIS;<br>+ write32(pmcbase + CPPMVRIC, reg32);<br>+ }<br>+<br>+ /* we should disable Heci1 based on the devicetree policy */<br>+ if (config->HeciEnabled == 0)<br>+ pch_disable_heci();<br>+}<br>+<br>+static void soc_lockdown(void)<br>+{<br>+ const struct device *dev;<br>+ const struct soc_intel_cannonlake_config *config;<br>+ uint8_t reg8, *pmc;<br>+<br>+ dev = PCH_DEV_PMC;<br>+<br>+ /* Check if PMC is enabled, else return */<br>+ if (dev == NULL || dev->chip_info == NULL)<br>+ return;<br>+<br>+ config = dev->chip_info;<br>+<br>+ /* Global SMI Lock */<br>+ if (config->LockDownConfigGlobalSmi == 0) {<br>+ pmc = pmc_mmio_regs();<br>+ reg8 = read8(pmc + GEN_PMCON_B);<br>+ reg8 |= SMI_LOCK;<br>+ write8(pmc + GEN_PMCON_B, reg8);<br>+ }<br>+}<br>+<br>+static void soc_finalize(void *unused)<br>+{<br>+ printk(BIOS_DEBUG, "Finalizing chipset.\n");<br>+<br>+ pch_finalize_script();<br>+<br>+ soc_lockdown();<br>+<br>+ printk(BIOS_DEBUG, "Finalizing SMM.\n");<br>+ outb(APM_CNT_FINALIZE, APM_CNT);<br>+<br>+ /* Indicate finalize step with post code */<br>+ post_code(POST_OS_BOOT);<br>+}<br>+<br>+BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL);<br>+BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT, soc_finalize, NULL);<br>diff --git a/src/soc/intel/cannonlake/include/soc/pmc.h b/src/soc/intel/cannonlake/include/soc/pmc.h<br>index a98b4ba..fd28859 100644<br>--- a/src/soc/intel/cannonlake/include/soc/pmc.h<br>+++ b/src/soc/intel/cannonlake/include/soc/pmc.h<br>@@ -120,6 +120,9 @@<br> #define GBLRST_CAUSE0_THERMTRIP (1 << 5)<br> #define GBLRST_CAUSE1 0x1928<br> <br>+#define CPPMVRIC 0x1B1C<br>+#define XTALSDQDIS (1 << 22)<br>+<br> #define IRQ_REG ACTL<br> #define SCI_IRQ_ADJUST 0<br> #define ACTL 0x1BD8<br>diff --git a/src/soc/intel/cannonlake/lockdown.c b/src/soc/intel/cannonlake/lockdown.c<br>new file mode 100644<br>index 0000000..0158bff<br>--- /dev/null<br>+++ b/src/soc/intel/cannonlake/lockdown.c<br>@@ -0,0 +1,106 @@<br>+/*<br>+ * This file is part of the coreboot project.<br>+ *<br>+ * Copyright (C) 2017 Intel Corporation.<br>+ *<br>+ * This program is free software; you can redistribute it and/or modify<br>+ * it under the terms of the GNU General Public License as published by<br>+ * the Free Software Foundation; version 2 of the License.<br>+ *<br>+ * This program is distributed in the hope that it will be useful,<br>+ * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>+ * GNU General Public License for more details.<br>+ */<br>+<br>+#include <arch/io.h><br>+#include <bootstate.h><br>+#include <chip.h><br>+#include <intelblocks/fast_spi.h><br>+#include <intelblocks/lpc_lib.h><br>+#include <intelblocks/pcr.h><br>+#include <soc/pci_devs.h><br>+#include <soc/pcr_ids.h><br>+#include <soc/pm.h><br>+#include <string.h><br>+<br>+#define PCR_DMI_GCS 0x274C<br>+#define PCR_DMI_GCS_BILD (1 << 0)<br>+<br>+static void pmc_lockdown_cfg(void)<br>+{<br>+ uint8_t *pmcbase;<br>+ uint32_t reg32, pmsyncreg;<br>+<br>+ /* PMSYNC */<br>+ pmcbase = pmc_mmio_regs();<br>+ pmsyncreg = read32(pmcbase + PMSYNC_TPR_CFG);<br>+ pmsyncreg |= PMSYNC_LOCK;<br>+ write32(pmcbase + PMSYNC_TPR_CFG, pmsyncreg);<br>+<br>+ /* Lock down ABASE and sleep stretching policy */<br>+ reg32 = read32(pmcbase + GEN_PMCON_B);<br>+ reg32 |= (SLP_STR_POL_LOCK | ACPI_BASE_LOCK);<br>+ write32(pmcbase + GEN_PMCON_B, reg32);<br>+}<br>+<br>+static void dmi_lockdown_cfg(void)<br>+{<br>+ /*<br>+ * GCS reg of DMI<br>+ *<br>+ * When set, prevents GCS.BBS from being changed<br>+ * GCS.BBS: (Boot BIOS Strap) This field determines the destination<br>+ * of accesses to the BIOS memory range.<br>+ * Bits Description<br>+ * “0b”: SPI<br>+ * “1b”: LPC/eSPI<br>+ */<br>+ pcr_or8(PID_DMI, PCR_DMI_GCS, PCR_DMI_GCS_BILD);<br>+}<br>+<br>+static void spi_lockdown_cfg(const struct soc_intel_cannonlake_config *config)<br>+{<br>+ /* Set FAST_SPI opcode menu */<br>+ fast_spi_set_opcode_menu();<br>+<br>+ /* Discrete Lock Flash PR registers */<br>+ fast_spi_pr_dlock();<br>+<br>+ /* Lock FAST_SPIBAR */<br>+ fast_spi_lock_bar();<br>+<br>+ /* Set Bios Interface Lock, Bios Lock */<br>+ if (config->chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) {<br>+ /* Bios Interface Lock */<br>+ fast_spi_set_bios_interface_lock_down();<br>+<br>+ /* Bios Lock */<br>+ fast_spi_set_lock_enable();<br>+ }<br>+}<br>+<br>+static void platform_lockdown_config(void *unused)<br>+{<br>+ struct soc_intel_cannonlake_config *config;<br>+ struct device *dev;<br>+<br>+ dev = PCH_DEV_SPI;<br>+ /* Check if device is valid, else return */<br>+ if (dev == NULL || dev->chip_info == NULL)<br>+ return;<br>+<br>+ config = dev->chip_info;<br>+<br>+ /* SPI lock down configuration */<br>+ spi_lockdown_cfg(config);<br>+<br>+ /* DMI lock down configuration */<br>+ dmi_lockdown_cfg();<br>+<br>+ /* PMC lock down configuration */<br>+ pmc_lockdown_cfg();<br>+}<br>+<br>+BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT, platform_lockdown_config,<br>+ NULL);<br></pre><p>To view, visit <a href="https://review.coreboot.org/21943">change 21943</a>. To unsubscribe, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/21943"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Icfa05b50fd76fbaeb856d398918990aedac4c5e6 </div>
<div style="display:none"> Gerrit-Change-Number: 21943 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Lijian Zhao <lijian.zhao@intel.com> </div>