summaryrefslogtreecommitdiff
path: root/src/southbridge/intel
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2021-02-10 17:12:05 +0100
committerPatrick Rudolph <siro@das-labor.org>2021-06-21 08:11:11 +0000
commitd21b463fb058deccef3a2c2ad80d771b5aba9f19 (patch)
treefdb4d134ffe185f67500f3419960996f0cbb8679 /src/southbridge/intel
parent44a4c0a58dd4ef725c7ff24f9889b12d42a4c5f2 (diff)
downloadcoreboot-d21b463fb058deccef3a2c2ad80d771b5aba9f19.tar.gz
security/intel: Add option to enable SMM flash access only
On platforms where the boot media can be updated externally, e.g. using a BMC, add the possibility to enable writes in SMM only. This allows to protect the BIOS region even without the use of vboot, but keeps SMMSTORE working for use in payloads. Note that this breaks flashconsole, since the flash becomes read-only. Tested on Asrock B85M Pro4 and HP 280 G2, SMM BIOS write protection works as expected, and SMMSTORE can still be used. Change-Id: I157db885b5f1d0f74009ede6fb2342b20d9429fa Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/40830 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Diffstat (limited to 'src/southbridge/intel')
-rw-r--r--src/southbridge/intel/common/finalize.c3
-rw-r--r--src/southbridge/intel/common/spi.c39
2 files changed, 34 insertions, 8 deletions
diff --git a/src/southbridge/intel/common/finalize.c b/src/southbridge/intel/common/finalize.c
index 975d839e67..6fb27bbb4b 100644
--- a/src/southbridge/intel/common/finalize.c
+++ b/src/southbridge/intel/common/finalize.c
@@ -45,6 +45,9 @@ void intel_pch_finalize_smm(void)
pci_write_config32(PCI_DEV(0, 27, 0), 0x74,
pci_read_config32(PCI_DEV(0, 27, 0), 0x74));
+ if (CONFIG(BOOTMEDIA_SMM_BWP))
+ write_pmbase16(SMI_EN, read_pmbase16(SMI_EN) | TCO_EN);
+
write_pmbase16(TCO1_CNT, read_pmbase16(TCO1_CNT) | TCO_LOCK);
post_code(POST_OS_BOOT);
diff --git a/src/southbridge/intel/common/spi.c b/src/southbridge/intel/common/spi.c
index 828f3d3e3d..30f7657948 100644
--- a/src/southbridge/intel/common/spi.c
+++ b/src/southbridge/intel/common/spi.c
@@ -27,6 +27,8 @@
static int spi_is_multichip(void);
+static void spi_set_smm_only_flashing(bool enable);
+
struct ich7_spi_regs {
uint16_t spis;
uint16_t spic;
@@ -282,7 +284,6 @@ static void *get_spi_bar(pci_devfn_t dev)
void spi_init(void)
{
- uint8_t bios_cntl;
struct ich9_spi_regs *ich9_spi;
struct ich7_spi_regs *ich7_spi;
uint16_t hsfs;
@@ -332,13 +333,8 @@ void spi_init(void)
ich_set_bbar(0);
- if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) {
- /* Disable the BIOS write protect so write commands are allowed. */
- bios_cntl = pci_read_config8(dev, 0xdc);
- /* Deassert SMM BIOS Write Protect Disable. */
- bios_cntl &= ~(1 << 5);
- pci_write_config8(dev, 0xdc, bios_cntl | 0x1);
- }
+ /* Disable the BIOS write protect so write commands are allowed. */
+ spi_set_smm_only_flashing(false);
}
static int spi_locked(void)
@@ -1096,12 +1092,39 @@ void spi_finalize_ops(void)
writeb_(spi_config->ops[i].op, &cntlr.opmenu[i]);
}
writew_(optype, cntlr.optype);
+
+ spi_set_smm_only_flashing(CONFIG(BOOTMEDIA_SMM_BWP));
}
__weak void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config)
{
}
+#define BIOS_CNTL 0xdc
+#define BIOS_CNTL_BIOSWE (1 << 0)
+#define BIOS_CNTL_BLE (1 << 1)
+#define BIOS_CNTL_SMM_BWP (1 << 5)
+
+static void spi_set_smm_only_flashing(bool enable)
+{
+ if (!(CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)))
+ return;
+
+ const pci_devfn_t dev = PCI_DEV(0, 31, 0);
+
+ uint8_t bios_cntl = pci_read_config8(dev, BIOS_CNTL);
+
+ if (enable) {
+ bios_cntl &= ~BIOS_CNTL_BIOSWE;
+ bios_cntl |= BIOS_CNTL_BLE | BIOS_CNTL_SMM_BWP;
+ } else {
+ bios_cntl &= ~(BIOS_CNTL_BLE | BIOS_CNTL_SMM_BWP);
+ bios_cntl |= BIOS_CNTL_BIOSWE;
+ }
+
+ pci_write_config8(dev, BIOS_CNTL, bios_cntl);
+}
+
static const struct spi_ctrlr spi_ctrlr = {
.xfer_vector = xfer_vectors,
.max_xfer_size = member_size(struct ich9_spi_regs, fdata),