Skip to content

Commit

Permalink
soc/intel/lockdown: Allow locking down SPI and LPC in SMM
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
miczyg1 committed Oct 20, 2024
1 parent 9129754 commit ff22122
Show file tree
Hide file tree
Showing 17 changed files with 123 additions and 33 deletions.
4 changes: 3 additions & 1 deletion src/soc/intel/alderlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/cannonlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 4 additions & 0 deletions src/soc/intel/common/block/lpc/Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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
10 changes: 10 additions & 0 deletions src/soc/intel/common/block/smm/smihandler.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <elog.h>
#include <intelblocks/cfg.h>
#include <intelblocks/fast_spi.h>
#include <intelblocks/oc_wdt.h>
#include <intelblocks/pmclib.h>
#include <intelblocks/smihandler.h>
#include <intelblocks/tco.h>
#include <intelblocks/uart.h>
#include <intelpch/lockdown.h>
#include <smmstore.h>
#include <soc/nvs.h>
#include <soc/pci_devs.h>
Expand Down Expand Up @@ -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();
Expand Down
3 changes: 3 additions & 0 deletions src/soc/intel/common/pch/include/intelpch/lockdown.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
15 changes: 15 additions & 0 deletions src/soc/intel/common/pch/lockdown/Kconfig
Original file line number Diff line number Diff line change
@@ -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.
5 changes: 5 additions & 0 deletions src/soc/intel/common/pch/lockdown/Makefile.inc
Original file line number Diff line number Diff line change
@@ -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
33 changes: 9 additions & 24 deletions src/soc/intel/common/pch/lockdown/lockdown.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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))
Expand Down
23 changes: 23 additions & 0 deletions src/soc/intel/common/pch/lockdown/lockdown_lpc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <intelblocks/cfg.h>
#include <intelblocks/lpc_lib.h>
#include <intelpch/lockdown.h>

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();
}
}
35 changes: 35 additions & 0 deletions src/soc/intel/common/pch/lockdown/lockdown_spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */

#include <intelblocks/cfg.h>
#include <intelblocks/fast_spi.h>
#include <intelpch/lockdown.h>

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();
}
}
3 changes: 2 additions & 1 deletion src/soc/intel/denverton_ns/lpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/elkhartlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/jasperlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/meteorlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/skylake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/tigerlake/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion src/soc/intel/xeon_sp/finalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down

0 comments on commit ff22122

Please sign in to comment.