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 #include +#include #include #include #include #include +#include +#include #include +#include #include 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