From ff22122c229bbe2109de92ded773493428f7ece9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Sun, 20 Oct 2024 13:15:19 +0200 Subject: [PATCH] soc/intel/lockdown: Allow locking down SPI and LPC in SMM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Heads payload uses APM_CNT_FINALIZE SMI to set and lock down the SPI controller with PR0 flash protection. Add new option to skip LPC and FAST SPI lock down in coreboot and move it to APM_CNT_FINALIZE SMI handler. Signed-off-by: Michał Żygowski --- src/soc/intel/alderlake/finalize.c | 4 ++- src/soc/intel/cannonlake/finalize.c | 3 +- src/soc/intel/common/block/lpc/Makefile.inc | 4 +++ src/soc/intel/common/block/smm/smihandler.c | 10 ++++++ .../common/pch/include/intelpch/lockdown.h | 3 ++ src/soc/intel/common/pch/lockdown/Kconfig | 15 ++++++++ .../intel/common/pch/lockdown/Makefile.inc | 5 +++ src/soc/intel/common/pch/lockdown/lockdown.c | 33 +++++------------ .../intel/common/pch/lockdown/lockdown_lpc.c | 23 ++++++++++++ .../intel/common/pch/lockdown/lockdown_spi.c | 35 +++++++++++++++++++ src/soc/intel/denverton_ns/lpc.c | 3 +- src/soc/intel/elkhartlake/finalize.c | 3 +- src/soc/intel/jasperlake/finalize.c | 3 +- src/soc/intel/meteorlake/finalize.c | 3 +- src/soc/intel/skylake/finalize.c | 3 +- src/soc/intel/tigerlake/finalize.c | 3 +- src/soc/intel/xeon_sp/finalize.c | 3 +- 17 files changed, 123 insertions(+), 33 deletions(-) create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_lpc.c create mode 100644 src/soc/intel/common/pch/lockdown/lockdown_spi.c 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..b5f727e97c7 100644 --- a/src/soc/intel/cannonlake/finalize.c +++ b/src/soc/intel/cannonlake/finalize.c @@ -87,7 +87,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); 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.inc b/src/soc/intel/common/block/lpc/Makefile.inc index b510cd0ec35..60792654b5a 100644 --- a/src/soc/intel/common/block/lpc/Makefile.inc +++ b/src/soc/intel/common/block/lpc/Makefile.inc @@ -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 4bfd17bfd07..dcd74764957 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 @@ -343,6 +345,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 8fce5e785c2..fbeb341e9ac 100644 --- a/src/soc/intel/common/pch/lockdown/Kconfig +++ b/src/soc/intel/common/pch/lockdown/Kconfig @@ -1,7 +1,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 + 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. \ No newline at end of file diff --git a/src/soc/intel/common/pch/lockdown/Makefile.inc b/src/soc/intel/common/pch/lockdown/Makefile.inc index 71466f8edd1..64aad562acf 100644 --- a/src/soc/intel/common/pch/lockdown/Makefile.inc +++ b/src/soc/intel/common/pch/lockdown/Makefile.inc @@ -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..7e52fb826fe 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -61,21 +61,24 @@ 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(); + if (CONFIG(SOC_INTEL_COMMON_SPI_LOCKDOWN_SMM)) + return; + + /* 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 */ @@ -95,24 +98,6 @@ static void fast_spi_lockdown_cfg(int chipset_lockdown) } } -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(); - } -} - static void sa_lockdown_config(int chipset_lockdown) { if (!CONFIG(SOC_INTEL_COMMON_BLOCK_SA)) 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..69278ea343f --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_lpc.c @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#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)) { + 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..fa09cec7c2e --- /dev/null +++ b/src/soc/intel/common/pch/lockdown/lockdown_spi.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include +#include +#include + +void fast_spi_lockdown_bios(int chipset_lockdown) +{ + if (!CONFIG(SOC_INTEL_COMMON_BLOCK_FAST_SPI)) + return; + + /* 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)) { + 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 7ebca1eb946..8d8acf05088 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 275413b4efa..802d02cb596 100644 --- a/src/soc/intel/elkhartlake/finalize.c +++ b/src/soc/intel/elkhartlake/finalize.c @@ -43,7 +43,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); 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 a977b0516e5..951153fa812 100644 --- a/src/soc/intel/meteorlake/finalize.c +++ b/src/soc/intel/meteorlake/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); tbt_finalize(); sa_finalize(); if (CONFIG(USE_FSP_NOTIFY_PHASE_READY_TO_BOOT) && 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..06ce243fe72 100644 --- a/src/soc/intel/tigerlake/finalize.c +++ b/src/soc/intel/tigerlake/finalize.c @@ -55,7 +55,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); 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..8e409b8c439 100644 --- a/src/soc/intel/xeon_sp/finalize.c +++ b/src/soc/intel/xeon_sp/finalize.c @@ -59,7 +59,8 @@ 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) {