Marc Jones has uploaded this change for review.

View Change

WIP stoneyridge: Lock PSP region

This is a work in progress.

The call to lock the PSP is currently in romstage for debugging via serial.
The call should move to bootblock. Also, WP and SPI flash WP needs to be
checked prior to locking the PSP region.

Write Protect the SI_ALL FMAP area, which includes the AMD PSP, with the
ROM_PROTECT in the SPI flash controller.

SI_ALL@0x0 0xCB000 {
UNUSED@0x00000 0x20000
AMD_FW@0x20000 0xAB000
}

Change-Id: Ic375033d9942045389a528182daca2cd5288b672
Signed-off-by: Marc Jones <marcj303@gmail.com>
---
M src/mainboard/google/kahlee/ec.c
M src/soc/amd/stoneyridge/early_setup.c
M src/soc/amd/stoneyridge/include/soc/southbridge.h
3 files changed, 82 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/08/21308/1
diff --git a/src/mainboard/google/kahlee/ec.c b/src/mainboard/google/kahlee/ec.c
index 75ed1fa..6fe7226 100644
--- a/src/mainboard/google/kahlee/ec.c
+++ b/src/mainboard/google/kahlee/ec.c
@@ -72,4 +72,16 @@
ramstage_ec_init();
else
early_ec_init();
+
+/*
+ * Located here for testing. Move to bootblock_fch_early_init or other
+ * correct location before commiting.
+ */
+#ifdef __PRE_RAM__
+ if (IS_ENABLED(CONFIG_CHROMEOS)) {
+ /* TODO: Check SPI WP setting before locking */
+ if (sb_lock_psp())
+ die("ERROR: Could Not WP PSP Region!\n");
+ }
+#endif
}
diff --git a/src/soc/amd/stoneyridge/early_setup.c b/src/soc/amd/stoneyridge/early_setup.c
index 5166a7f..3618ba5 100644
--- a/src/soc/amd/stoneyridge/early_setup.c
+++ b/src/soc/amd/stoneyridge/early_setup.c
@@ -24,6 +24,7 @@
#include <soc/southbridge.h>
#include <soc/pci_devs.h>
#include <Fch/Fch.h>
+#include <fmap.h>
#include <cpu/x86/msr.h>
#include <delay.h>

@@ -342,6 +343,63 @@
pci_io_write_config16(dev, 0x6e, 0xffff);
}

+/*
+ * Set the write once SPI ROM Protect registers to protect the PSP.
+ *
+ * PCU_DEV, LPC_FUNC[5C,58,54,50] ROM Protect 3, 2, 1, 0
+ * {RomBase, 000_0000_0000b} <= address[31:0] <= (({RomBase, 000_0000_0000b} +
+ * ((Range+1) << (RangeUnit ? 16 : 12) ) ) - 1).
+ */
+int sb_lock_psp(void)
+{
+ pci_devfn_t dev;
+ struct region r;
+ size_t r_offset, r_size;
+ u32 reg;
+
+ dev = PCI_DEV(0, PCU_DEV, LPC_FUNC);
+
+ /* Locate PSP area in the FMAP */
+ if (fmap_locate_area("SI_ALL", &r) != 0 ) {
+ assert(0);
+ return -1;
+ }
+
+ /* The offset from the bottom of the FLASH ROM. (4GB - ROMSIZE) */
+ r_offset = 0xFFFFFFFF - CONFIG_ROM_SIZE + 1 + region_offset(&r);
+ r_size = region_sz(&r);
+ printk(BIOS_DEBUG, "r_offset: 0x%x r_size:0x%x\n", (u32)r_offset, (u32)r_size);
+
+ reg = pci_io_read_config32(dev, LPC_ROM_PROTECT0);
+
+ if (reg != 0) {
+ assert(0);
+ return -1;
+ }
+
+ /*
+ * Determine the 4KB or 64 Region Unit size.
+ * The region MUST align with the unit size or it could write
+ * protect the next region.
+ */
+ if (r_size <= (0x100 * 0x1000) && !(r_size % 0x1000)) {
+ reg |= (r_size / 0x1000);
+ reg |= LPC_ROM_PROTECT_UNIT_4KB;
+ } else if (r_size <= (0x100 * 0x10000) && !(r_size % 0x10000)) {
+ reg |= (r_size / 0x1000);
+ reg |= LPC_ROM_PROTECT_UNIT_64KB;
+ } else {
+ assert(0); /* region isn't aligned */
+ return -1;
+ }
+
+ reg |= r_offset & LPC_ROM_PROTECT_BASE_MASK;
+ reg |= LPC_ROM_PROTECT_WP;
+ pci_io_write_config32(dev, LPC_ROM_PROTECT0, reg);
+ printk(BIOS_DEBUG, "ROM PROTECT0: 0x%x\n", reg); //debug, remove
+ return 0;
+}
+
void bootblock_fch_early_init(void)
{
sb_enable_rom();
diff --git a/src/soc/amd/stoneyridge/include/soc/southbridge.h b/src/soc/amd/stoneyridge/include/soc/southbridge.h
index de481f0..ee71d14 100644
--- a/src/soc/amd/stoneyridge/include/soc/southbridge.h
+++ b/src/soc/amd/stoneyridge/include/soc/southbridge.h
@@ -120,6 +120,17 @@
#define LPC_WIDEIO1_ENABLE BIT(24)
#define LPC_WIDEIO0_ENABLE BIT(2)

+#define LPC_ROM_PROTECT0 0x50
+#define LPC_ROM_PROTECT1 0x54
+#define LPC_ROM_PROTECT2 0x58
+#define LPC_ROM_PROTECT3 0x5c
+#define LPC_ROM_PROTECT_BASE_MASK 0xffffffff << 12
+#define LPC_ROM_PROTECT_WP BIT(10)
+#define LPC_ROM_PROTECT_RP BIT(9)
+#define LPC_ROM_PROTECT_UNIT_4KB 0
+#define LPC_ROM_PROTECT_UNIT_64KB BIT(8)
+#define LPC_ROM_PROTECT_RANGE_MASK 0xff
+
#define LPC_WIDEIO_GENERIC_PORT 0x64

#define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74
@@ -186,6 +197,7 @@
void sb_enable(device_t dev);
void southbridge_final(void *chip_info);
void southbridge_init(void *chip_info);
+int sb_lock_psp(void);
void sb_lpc_port80(void);
void sb_lpc_decode(void);
void sb_pci_port80(void);

To view, visit change 21308. To unsubscribe, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ic375033d9942045389a528182daca2cd5288b672
Gerrit-Change-Number: 21308
Gerrit-PatchSet: 1
Gerrit-Owner: Marc Jones <marc@marcjonesconsulting.com>