summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mainboard/google/dedede/Kconfig1
-rw-r--r--src/mainboard/google/dedede/smihandler.c56
-rw-r--r--src/mainboard/google/dedede/variants/baseboard/gpio.c8
3 files changed, 64 insertions, 1 deletions
diff --git a/src/mainboard/google/dedede/Kconfig b/src/mainboard/google/dedede/Kconfig
index d8961a37df..758143a370 100644
--- a/src/mainboard/google/dedede/Kconfig
+++ b/src/mainboard/google/dedede/Kconfig
@@ -29,6 +29,7 @@ config BOARD_GOOGLE_BASEBOARD_DEDEDE
select DRIVERS_INTEL_MIPI_CAMERA
select SOC_INTEL_COMMON_BLOCK_IPU
select DRIVERS_GENERIC_ALC1015
+ select SPI_FLASH_SMM
config BOARD_GOOGLE_BASEBOARD_DEDEDE_CR50
def_bool n
diff --git a/src/mainboard/google/dedede/smihandler.c b/src/mainboard/google/dedede/smihandler.c
index c50578da70..33c6b2ef53 100644
--- a/src/mainboard/google/dedede/smihandler.c
+++ b/src/mainboard/google/dedede/smihandler.c
@@ -1,11 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <baseboard/gpio.h>
#include <baseboard/variants.h>
+#include <console/console.h>
#include <cpu/x86/smm.h>
#include <ec/google/chromeec/ec.h>
#include <ec/google/chromeec/smm.h>
#include <elog.h>
+#include <gpio.h>
+#include <intelblocks/gpio.h>
#include <intelblocks/smihandler.h>
+#include <spi_flash.h>
#include <variant/ec.h>
void mainboard_smi_gpi_handler(const struct gpi_status *sts)
@@ -47,3 +52,54 @@ void mainboard_smi_espi_handler(void)
void __weak variant_smi_sleep(u8 slp_typ)
{
}
+
+static void mainboard_config_cbi_wp(void)
+{
+ int hw_wp = gpio_get(GPIO_PCH_WP);
+ const struct spi_flash *spi_flash_dev = boot_device_spi_flash();
+ uint8_t sr1;
+ int rv;
+
+ /*
+ * The CBI EEPROM WP should mirror our software write protect status if
+ * hardware write protect is set. If software write protect status is
+ * set at all via status register 1, that should be a sufficient signal.
+ * If the hardware WP is not set, or software write protect is not set
+ * while hardware write protect is set, deassert the CBI EEPROM WP.
+ *
+ * HW WP | SW WP | CBI WP
+ * ------|-------|-------
+ * 0 | X | 0
+ * 1 | 0 | 0
+ * 1 | 1 | 1
+ */
+ if (spi_flash_status(spi_flash_dev, &sr1) < 0) {
+ printk(BIOS_ERR, "MB: Failed to read SPI status register 1\n");
+ printk(BIOS_ERR, "MB: CBI EEPROM WP cannot change!");
+ return;
+ }
+
+ /*
+ * Note that we are assuming that the Status Register protect bits are
+ * are located at this index and that 1 means hardware protected. This
+ * should be the case for these boards.
+ */
+ const bool is_wp = !!(sr1 & 0x80) && hw_wp;
+ printk(BIOS_INFO, "MB: SPI flash is %swrite protected\n",
+ is_wp ? "" : "not ");
+
+ /* Inverted because the signal is active low. */
+ gpio_set(GPP_B16, !is_wp);
+
+ /* Lock the configuration down. */
+ rv = gpio_lock_pad(GPP_B16, GPIO_LOCK_FULL);
+ if (rv)
+ printk(BIOS_ERR, "MB: Failed to lock CBI WP (rv=%d)\n",
+ rv);
+}
+
+void mainboard_smi_finalize(void)
+{
+ if (CONFIG(BOARD_GOOGLE_BASEBOARD_DEDEDE_TPM2))
+ mainboard_config_cbi_wp();
+}
diff --git a/src/mainboard/google/dedede/variants/baseboard/gpio.c b/src/mainboard/google/dedede/variants/baseboard/gpio.c
index 79bae96476..9b3bd7062d 100644
--- a/src/mainboard/google/dedede/variants/baseboard/gpio.c
+++ b/src/mainboard/google/dedede/variants/baseboard/gpio.c
@@ -84,7 +84,13 @@ static const struct pad_config gpio_table[] = {
#else /* BOARD_GOOGLE_BASEBOARD_DEDEDE_TPM2 */
/* Nothing connected on GSPI1 */
PAD_NC(GPP_B15, NONE),
- PAD_NC(GPP_B16, NONE),
+ /*
+ * B16: AP_CBI_EEPROM_WP_L
+ *
+ * We default to 0 to keep the EEPROM protected until we know it is safe to
+ * deassert the write protect signal.
+ */
+ PAD_CFG_GPO(GPP_B16, 0, DEEP),
PAD_NC(GPP_B17, NONE),
PAD_NC(GPP_B18, NONE),
#endif