diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-09-12 14:39:39 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-09-22 08:30:10 -0700 |
commit | c98ea9a60abaa3bf3a4ca96e0c047e7512e6ec2f (patch) | |
tree | 00efc49c62da19b5f1f1f590ee239fb9d6b72855 /chip | |
parent | 078ec24008684e855dc3d62b41623bfbbec893dc (diff) | |
download | chrome-ec-c98ea9a60abaa3bf3a4ca96e0c047e7512e6ec2f.tar.gz |
stm32h7/nocturne_fp: Enable RDP level 1, tie it to flash protection status
Prevent flash readout, using RDP field in option byte.
When RDP is defined, it makes no sense to be able to unlock
RO, as that'd allow flashing arbitrary RO that could read
back the rest of the flash, so we just tie
EC_FLASH_PROTECT_RO_AT_BOOT and RDP protection. This also
means we can't unlock the flash after it has been finalized
(without removing WP and using BOOT0/stm32mon to mass erase
the chip).
Also, in flash_mp_mcu, call stm32mon with -U, to unlock
flash for read-back first (which disables RDP and triggers
a mass erase if RDP was enabled). Finally, load spidev
before putting releasing reset, which makes reflashing
more reliable.
BRANCH=nocturne
BUG=b:111330723
TEST=cp flash_mp_mcu read_mp_mcu, replace stm32mon line with:
"stm32mon -u -p -s ${SPIDEV} -r rb.bin"
dut-control fw_wp_state:force_off
=> Check that read_mp_mcu works
dut-control fw_wp_state:force_on
ectool --name=cros_fp flashprotect enable
ectool --name=cros_fp reboot_ec
=> RDP is now on
dut-control fw_wp_state:force_off
=> Check that read_mp_mcu does not work anymore
TEST=Add -U to stm32mon line above in read_mp_mcu, check that
readback only gets blank data.
TEST=In EC console, check that RDP bits are indeed not 0xaa:
Before: rw 0x5200201c => 0x07d6aaf0
After: rw 0x5200201c => 0x07d600f0
TEST=flash_mp_mcu still works (does a flash erase that removes
RDP protection)
Change-Id: Ifbe37ecafbf23f48d4a3cc17933130b7b104b728
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1222094
Commit-Ready: Nicolas Norvez <norvez@chromium.org>
Tested-by: Nicolas Norvez <norvez@chromium.org>
Reviewed-by: Nicolas Norvez <norvez@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/stm32/flash-stm32h7.c | 33 | ||||
-rw-r--r-- | chip/stm32/registers.h | 5 |
2 files changed, 35 insertions, 3 deletions
diff --git a/chip/stm32/flash-stm32h7.c b/chip/stm32/flash-stm32h7.c index c125e5114e..0f82bf409a 100644 --- a/chip/stm32/flash-stm32h7.c +++ b/chip/stm32/flash-stm32h7.c @@ -150,10 +150,25 @@ static void protect_blocks(uint32_t blocks) commit_optb(); } -/* use the option bytes RSS1 bit as 'Write Protect enabled' flag. */ +/* + * If RDP as PSTATE option is defined, use that as 'Write Protect enabled' flag: + * it makes no sense to be able to unlock RO, as that'd allow flashing + * arbitrary RO that could read back all flash. + * + * crbug.com/888109: Do not copy this code over to other STM32 chips without + * understanding the full implications. + * + * If RDP is not defined, use the option bytes RSS1 bit. + * TODO(crbug.com/888104): Validate that using RSS1 for this purpose is safe. + */ static int is_wp_enabled(void) { +#ifdef CONFIG_FLASH_READOUT_PROTECTION_AS_PSTATE + return (STM32_FLASH_OPTSR_CUR(0) & FLASH_OPTSR_RDP_MASK) + != FLASH_OPTSR_RDP_LEVEL_0; +#else return !!(STM32_FLASH_OPTSR_CUR(0) & FLASH_OPTSR_RSS1); +#endif } static int set_wp(int enabled) @@ -163,10 +178,20 @@ static int set_wp(int enabled) rv = unlock_optb(); if (rv) return rv; + +#ifdef CONFIG_FLASH_READOUT_PROTECTION_AS_PSTATE + if (enabled) { + /* Enable RDP level 1. */ + STM32_FLASH_OPTSR_PRG(0) = + (STM32_FLASH_OPTSR_PRG(0) & ~FLASH_OPTSR_RDP_MASK) | + FLASH_OPTSR_RDP_LEVEL_1; + } +#else if (enabled) STM32_FLASH_OPTSR_PRG(0) |= FLASH_OPTSR_RSS1; else STM32_FLASH_OPTSR_PRG(0) &= ~FLASH_OPTSR_RSS1; +#endif return commit_optb(); } @@ -447,8 +472,10 @@ int flash_pre_init(void) */ if ((prot_flags & EC_FLASH_PROTECT_RO_AT_BOOT) && !(prot_flags & EC_FLASH_PROTECT_RO_NOW)) { - int rv = flash_set_protect(EC_FLASH_PROTECT_RO_NOW, - EC_FLASH_PROTECT_RO_NOW); + int rv; + + rv = flash_set_protect(EC_FLASH_PROTECT_RO_NOW, + EC_FLASH_PROTECT_RO_NOW); if (rv) return rv; diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h index 6e976d5b86..2a4f1171fc 100644 --- a/chip/stm32/registers.h +++ b/chip/stm32/registers.h @@ -2093,6 +2093,11 @@ typedef volatile struct stm32_spi_regs stm32_spi_regs_t; #define STM32_FLASH_OPTSR_CUR(bank) STM32_FLASH_REG(bank, 0x1C) #define STM32_FLASH_OPTSR_PRG(bank) STM32_FLASH_REG(bank, 0x20) #define FLASH_OPTSR_BUSY (1 << 0) /* only in OPTSR_CUR */ +#define FLASH_OPTSR_RDP_MASK (0xFF << 8) +#define FLASH_OPTSR_RDP_LEVEL_0 (0xAA << 8) +/* RDP Level 1: Anything but 0xAA/0xCC */ +#define FLASH_OPTSR_RDP_LEVEL_1 (0x00 << 8) +#define FLASH_OPTSR_RDP_LEVEL_2 (0xCC << 8) #define FLASH_OPTSR_RSS1 (1 << 26) #define FLASH_OPTSR_RSS2 (1 << 27) #define STM32_FLASH_OPTCCR(bank) STM32_FLASH_REG(bank, 0x24) |