diff --git a/src/soc/intel/alderlake/finalize.c b/src/soc/intel/alderlake/finalize.c index 460c8af174e..9cd9351d96a 100644 --- a/src/soc/intel/alderlake/finalize.c +++ b/src/soc/intel/alderlake/finalize.c @@ -84,7 +84,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) diff --git a/src/soc/intel/cannonlake/finalize.c b/src/soc/intel/cannonlake/finalize.c index ba7fc69b552..825dd0aadf1 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -87,7 +87,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT) && CONFIG(SOC_INTEL_COMMON_BLOCK_HECI1_DISABLE_USING_PMC_IPC)) heci1_disable(); diff --git a/src/soc/intel/common/block/lpc/Makefile.mk b/src/soc/intel/common/block/lpc/Makefile.mk index b510cd0ec35..60792654b5a 100644 --- a/src/soc/intel/common/block/lpc/Makefile.mk +++ b/src/soc/intel/common/block/lpc/Makefile.mk @@ -5,3 +5,7 @@ romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc.c + +ifeq ($(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM),y) +smm-$(CONFIG_SOC_INTEL_COMMON_BLOCK_LPC) += lpc_lib.c +endif diff --git a/src/soc/intel/common/block/smm/smihandler.c b/src/soc/intel/common/block/smm/smihandler.c index c1f895fbd2a..65a15b09649 100644 --- a/src/soc/intel/common/block/smm/smihandler.c +++ b/src/soc/intel/common/block/smm/smihandler.c @@ -15,12 +15,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -347,6 +349,14 @@ static void finalize(void) } finalize_done = 1; + if (CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) { + /* SPI lock down configuration */ + fast_spi_lockdown_bios(CHIPSET_LOCKDOWN_COREBOOT); + + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(CHIPSET_LOCKDOWN_COREBOOT); + } + if (CONFIG(SPI_FLASH_SMM)) /* Re-init SPI driver to handle locked BAR */ fast_spi_init(); diff --git a/src/soc/intel/common/pch/include/intelpch/lockdown.h b/src/soc/intel/common/pch/include/intelpch/lockdown.h index b5aba06fe0e..1b96f41a2a4 100644 --- a/src/soc/intel/common/pch/include/intelpch/lockdown.h +++ b/src/soc/intel/common/pch/include/intelpch/lockdown.h @@ -22,4 +22,7 @@ int get_lockdown_config(void); */ void soc_lockdown_config(int chipset_lockdown); +void fast_spi_lockdown_bios(int chipset_lockdown); +void lpc_lockdown_config(int chipset_lockdown); + #endif /* SOC_INTEL_COMMON_PCH_LOCKDOWN_H */ diff --git a/src/soc/intel/common/pch/lockdown/Kconfig b/src/soc/intel/common/pch/lockdown/Kconfig index 38f60d20569..545185c52f2 100644 --- a/src/soc/intel/common/pch/lockdown/Kconfig +++ b/src/soc/intel/common/pch/lockdown/Kconfig @@ -3,7 +3,22 @@ config SOC_INTEL_COMMON_PCH_LOCKDOWN bool default n + select HAVE_INTEL_CHIPSET_LOCKDOWN help This option allows to have chipset lockdown for DMI, FAST_SPI and soc_lockdown_config() to implement any additional lockdown as PMC, LPC for supported PCH. + +config SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM + bool "Lock down SPI controller in SMM" + default n + depends on HAVE_SMI_HANDLER && !INTEL_CHIPSET_LOCKDOWN + select SPI_FLASH_SMM + help + This option allows to have chipset lockdown for FAST_SPI and LPC for + supported PCH. If selected, coreboot will skip locking down the SPI + and LPC controller. The payload or OS is responsible for locking it + using APM_CNT_FINALIZE SMI. Used by heads to set and lock PR0 flash + protection. + + If unsure, say N. diff --git a/src/soc/intel/common/pch/lockdown/Makefile.mk b/src/soc/intel/common/pch/lockdown/Makefile.mk index 71466f8edd1..64aad562acf 100644 --- a/src/soc/intel/common/pch/lockdown/Makefile.mk +++ b/src/soc/intel/common/pch/lockdown/Makefile.mk @@ -1,2 +1,7 @@ ## SPDX-License-Identifier: GPL-2.0-only ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_lpc.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_PCH_LOCKDOWN) += lockdown_spi.c + +smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_lpc.c +smm-$(CONFIG_SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM) += lockdown_spi.c diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c index 1b1d99cc0c9..2d229e1a90a 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include #include #include #include @@ -61,56 +60,17 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) /* Set FAST_SPI opcode menu */ fast_spi_set_opcode_menu(); - /* Discrete Lock Flash PR registers */ - fast_spi_pr_dlock(); - /* Check if SPI transaction is pending */ fast_spi_cycle_in_progress(); /* Clear any outstanding status bits like AEL, FCERR, FDONE, SAF etc. */ fast_spi_clear_outstanding_status(); - /* Lock FAST_SPIBAR */ - fast_spi_lock_bar(); - /* Set Vendor Component Lock (VCL) */ fast_spi_vscc0_lock(); - /* Set BIOS Interface Lock, BIOS Lock */ - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { - /* BIOS Interface Lock */ - fast_spi_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { - fast_spi_set_eiss(); - fast_spi_enable_wp(); - } - - /* BIOS Lock */ - fast_spi_set_lock_enable(); - - /* EXT BIOS Lock */ - fast_spi_set_ext_bios_lock_enable(); - } -} - -static void lpc_lockdown_config(int chipset_lockdown) -{ - /* Set BIOS Interface Lock, BIOS Lock */ - if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { - /* BIOS Interface Lock */ - lpc_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { - lpc_set_eiss(); - lpc_enable_wp(); - } - - /* BIOS Lock */ - lpc_set_lock_enable(); - } + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + fast_spi_lockdown_bios(chipset_lockdown); } static void sa_lockdown_config(int chipset_lockdown) @@ -136,8 +96,9 @@ static void platform_lockdown_config(void *unused) /* SPI lock down configuration */ fast_spi_lockdown_cfg(chipset_lockdown); - /* LPC/eSPI lock down configuration */ - lpc_lockdown_config(chipset_lockdown); + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(chipset_lockdown); /* GPMR lock down configuration */ gpmr_lockdown_cfg(); diff --git a/src/soc/intel/common/pch/lockdown/lockdown_lpc.c b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c new file mode 100644 index 00000000000..79a27d520f3 --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void lpc_lockdown_config(int chipset_lockdown) +{ + /* Set BIOS Interface Lock, BIOS Lock */ + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { + /* BIOS Interface Lock */ + lpc_set_bios_interface_lock_down(); + + /* Only allow writes in SMM */ + if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { + lpc_set_eiss(); + lpc_enable_wp(); + } + + /* BIOS Lock */ + lpc_set_lock_enable(); + } +} diff --git a/src/soc/intel/common/pch/lockdown/lockdown_spi.c b/src/soc/intel/common/pch/lockdown/lockdown_spi.c new file mode 100644 index 00000000000..0815a370bf0 --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_spi.c @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include + +void fast_spi_lockdown_bios(int chipset_lockdown) +{ + /* Discrete Lock Flash PR registers */ + fast_spi_pr_dlock(); + + /* Lock FAST_SPIBAR */ + fast_spi_lock_bar(); + + /* Set BIOS Interface Lock, BIOS Lock */ + if (chipset_lockdown == CHIPSET_LOCKDOWN_COREBOOT) { + /* BIOS Interface Lock */ + fast_spi_set_bios_interface_lock_down(); + + /* Only allow writes in SMM */ + if (CONFIG(BOOTMEDIA_SMM_BWP) && is_smm_bwp_permitted()) { + fast_spi_set_eiss(); + fast_spi_enable_wp(); + } + + /* BIOS Lock */ + fast_spi_set_lock_enable(); + + /* EXT BIOS Lock */ + fast_spi_set_ext_bios_lock_enable(); + } +} diff --git a/src/soc/intel/denverton_ns/lpc.c b/src/soc/intel/denverton_ns/lpc.c index ae923d7c0ed..b04e928bfa8 100644 --- a/src/soc/intel/denverton_ns/lpc.c +++ b/src/soc/intel/denverton_ns/lpc.c @@ -536,7 +536,8 @@ static const struct pci_driver lpc_driver __pci_driver = { static void finalize_chipset(void *unused) { - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); } BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, finalize_chipset, NULL); diff --git a/src/soc/intel/elkhartlake/finalize.c b/src/soc/intel/elkhartlake/finalize.c index 712a6c037f5..3fcc29e2a13 100644 --- a/src/soc/intel/elkhartlake/finalize.c +++ b/src/soc/intel/elkhartlake/finalize.c @@ -51,7 +51,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) heci_finalize(); diff --git a/src/soc/intel/jasperlake/finalize.c b/src/soc/intel/jasperlake/finalize.c index 6cff7a80f30..1b68cc51786 100644 --- a/src/soc/intel/jasperlake/finalize.c +++ b/src/soc/intel/jasperlake/finalize.c @@ -75,7 +75,8 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); /* Indicate finalize step with post code */ post_code(POSTCODE_OS_BOOT); diff --git a/src/soc/intel/meteorlake/finalize.c b/src/soc/intel/meteorlake/finalize.c index 38e3c7d3f9f..0118f5d79aa 100644 --- a/src/soc/intel/meteorlake/finalize.c +++ b/src/soc/intel/meteorlake/finalize.c @@ -83,7 +83,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); sa_finalize(); if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && diff --git a/src/soc/intel/pantherlake/finalize.c b/src/soc/intel/pantherlake/finalize.c new file mode 100644 index 00000000000..1d47dd7a0b6 --- /dev/null +++ b/src/soc/intel/pantherlake/finalize.c @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void pch_finalize(void) +{ + /* TCO Lock down */ + tco_lockdown(); + + pmc_clear_pmcon_sts(); +} + +static void tbt_finalize(void) +{ + int i; + const struct device *dev; + + /* Disable Thunderbolt PCIe root ports bus master */ + for (i = 0; i < NUM_TBT_FUNCTIONS; i++) { + dev = pcidev_path_on_root(PCI_DEVFN_TBT(i)); + if (dev) + pci_dev_disable_bus_master(dev); + } +} + +static void sa_finalize(void) +{ + if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT) + sa_lock_pam(); +} + +static void heci_finalize(void) +{ + heci_set_to_d0i3(); + if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) + heci1_disable(); +} + +static void soc_finalize(void *unused) +{ + printk(BIOS_DEBUG, "Finalizing chipset.\n"); + + pch_finalize(); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + + tbt_finalize(); + sa_finalize(); + if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && + CONFIG(USE_FSP_NOTIFY_PHASE_END_OF_FIRMWARE)) + heci_finalize(); + + /* Indicate finalize step with post code */ + post_code(POSTCODE_OS_BOOT); +} + +BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY, soc_finalize, NULL); +/* + * The purpose of this change is to accommodate more time to push out sending + * CSE EOP messages at post. + */ +BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, soc_finalize, NULL); diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index fd80aeac1a0..a147b62e46f 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -106,7 +106,8 @@ static void soc_finalize(void *unused) pch_finalize_script(dev); soc_lockdown(dev); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); /* Indicate finalize step with post code */ post_code(POSTCODE_OS_BOOT); diff --git a/src/soc/intel/tigerlake/finalize.c b/src/soc/intel/tigerlake/finalize.c index cd02745a9e6..158b2fb6916 100644 --- a/src/soc/intel/tigerlake/finalize.c +++ b/src/soc/intel/tigerlake/finalize.c @@ -55,7 +55,9 @@ static void soc_finalize(void *unused) printk(BIOS_DEBUG, "Finalizing chipset.\n"); pch_finalize(); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + tbt_finalize(); if (CONFIG(DISABLE_HECI1_AT_PRE_BOOT)) heci1_disable(); diff --git a/src/soc/intel/xeon_sp/finalize.c b/src/soc/intel/xeon_sp/finalize.c index af630fe8127..16799fe38e2 100644 --- a/src/soc/intel/xeon_sp/finalize.c +++ b/src/soc/intel/xeon_sp/finalize.c @@ -59,7 +59,9 @@ static void soc_finalize(void *unused) if (!CONFIG(USE_PM_ACPI_TIMER)) setbits8(pmc_mmio_regs() + PCH_PWRM_ACPI_TMR_CTL, ACPI_TIM_DIS); - apm_control(APM_CNT_FINALIZE); + if (CONFIG(INTEL_CHIPSET_LOCKDOWN) || acpi_is_wakeup_s3()) + apm_control(APM_CNT_FINALIZE); + lock_pam0123(); if (CONFIG_MAX_SOCKET > 1) { diff --git a/src/soc/intel/xeon_sp/lockdown.c b/src/soc/intel/xeon_sp/lockdown.c index a3d17b46c33..51a5cf54317 100644 --- a/src/soc/intel/xeon_sp/lockdown.c +++ b/src/soc/intel/xeon_sp/lockdown.c @@ -6,25 +6,15 @@ #include #include -static void lpc_lockdown_config(void) -{ - /* Set BIOS Interface Lock, BIOS Lock */ - lpc_set_bios_interface_lock_down(); - - /* Only allow writes in SMM */ - if (CONFIG(BOOTMEDIA_SMM_BWP)) { - lpc_set_eiss(); - lpc_enable_wp(); - } - lpc_set_lock_enable(); -} - void soc_lockdown_config(int chipset_lockdown) { if (chipset_lockdown == CHIPSET_LOCKDOWN_FSP) return; - lpc_lockdown_config(); + if (!CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + /* LPC/eSPI lock down configuration */ + lpc_lockdown_config(chipset_lockdown); + pmc_lockdown_config(); sata_lockdown_config(chipset_lockdown); spi_lockdown_config(chipset_lockdown);