diff options
author | Tarek BOCHKATI <tarek.bouchkati@gmail.com> | 2020-11-03 01:22:53 +0100 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2021-03-24 17:18:29 +0000 |
commit | 6405d35f324f767c2ab88da12a600cb8e6c25f0e (patch) | |
tree | 3513a1863cb06ba36996a1ae0019d80b72bf6786 /src/flash/nor | |
parent | 88fa831839cf7e45f66064c9c74cfcf59b8d8c7e (diff) | |
download | riscv-openocd-6405d35f324f767c2ab88da12a600cb8e6c25f0e.zip riscv-openocd-6405d35f324f767c2ab88da12a600cb8e6c25f0e.tar.gz riscv-openocd-6405d35f324f767c2ab88da12a600cb8e6c25f0e.tar.bz2 |
flash/stm32l4x: probe tzen and rdp values
introduction of 'enum stm32l4_rdp' enumerating possible RDP levels for
devices with and without TrustZone.
also in 'stm32l4_flash_bank' structure we added and rdp and tzen members
to store read values by the helper 'stm32l4_sync_rdp_tzen'
these new members are used to display security and protection status
while probing the flash.
Change-Id: Icf883189715278a3323fe210d295047678b16592
Signed-off-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
Reviewed-on: http://openocd.zylin.com/5541
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
Diffstat (limited to 'src/flash/nor')
-rw-r--r-- | src/flash/nor/stm32l4x.c | 65 | ||||
-rw-r--r-- | src/flash/nor/stm32l4x.h | 6 |
2 files changed, 60 insertions, 11 deletions
diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index bfedc8d..594bce0 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -143,6 +143,13 @@ enum stm32l4_flash_reg_index { STM32_FLASH_REG_INDEX_NUM, }; +enum stm32l4_rdp { + RDP_LEVEL_0 = 0xAA, + RDP_LEVEL_0_5 = 0x55, /* for devices with TrustZone enabled */ + RDP_LEVEL_1 = 0x00, + RDP_LEVEL_2 = 0xCC +}; + static const uint32_t stm32l4_flash_regs[STM32_FLASH_REG_INDEX_NUM] = { [STM32_FLASH_ACR_INDEX] = 0x000, [STM32_FLASH_KEYR_INDEX] = 0x008, @@ -199,6 +206,8 @@ struct stm32l4_flash_bank { const struct stm32l4_part_info *part_info; const uint32_t *flash_regs; bool otp_enabled; + enum stm32l4_rdp rdp; + bool tzen; }; enum stm32_bank_id { @@ -610,6 +619,35 @@ static inline bool stm32l4_otp_is_enabled(struct flash_bank *bank) return stm32l4_info->otp_enabled; } +static void stm32l4_sync_rdp_tzen(struct flash_bank *bank, uint32_t optr_value) +{ + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + + bool tzen = false; + + if (stm32l4_info->part_info->flags & F_HAS_TZ) + tzen = (optr_value & FLASH_TZEN) != 0; + + uint32_t rdp = optr_value & FLASH_RDP_MASK; + + /* for devices without TrustZone: + * RDP level 0 and 2 values are to 0xAA and 0xCC + * Any other value corresponds to RDP level 1 + * for devices with TrusZone: + * RDP level 0 and 2 values are 0xAA and 0xCC + * RDP level 0.5 value is 0x55 only if TZEN = 1 + * Any other value corresponds to RDP level 1, including 0x55 if TZEN = 0 + */ + + if (rdp != RDP_LEVEL_0 && rdp != RDP_LEVEL_2) { + if (!tzen || (tzen && rdp != RDP_LEVEL_0_5)) + rdp = RDP_LEVEL_1; + } + + stm32l4_info->tzen = tzen; + stm32l4_info->rdp = rdp; +} + static inline uint32_t stm32l4_get_flash_reg(struct flash_bank *bank, uint32_t reg_offset) { struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; @@ -1332,6 +1370,22 @@ static int stm32l4_probe(struct flash_bank *bank) LOG_INFO("device idcode = 0x%08" PRIx32 " (%s)", stm32l4_info->idcode, device_info); + /* read flash option register */ + retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &options); + if (retval != ERROR_OK) + return retval; + + stm32l4_sync_rdp_tzen(bank, options); + + if (part_info->flags & F_HAS_TZ) + LOG_INFO("TZEN = %d : TrustZone %s by option bytes", + stm32l4_info->tzen, + stm32l4_info->tzen ? "enabled" : "disabled"); + + LOG_INFO("RDP level %s (0x%02X)", + stm32l4_info->rdp == RDP_LEVEL_0 ? "0" : stm32l4_info->rdp == RDP_LEVEL_0_5 ? "0.5" : "1", + stm32l4_info->rdp); + if (stm32l4_is_otp(bank)) { bank->size = part_info->otp_size; @@ -1347,7 +1401,6 @@ static int stm32l4_probe(struct flash_bank *bank) return ERROR_FAIL; } - stm32l4_info->probed = true; return ERROR_OK; } else if (bank->base != STM32_FLASH_BANK_BASE) { @@ -1379,11 +1432,6 @@ static int stm32l4_probe(struct flash_bank *bank) /* did we assign a flash size? */ assert((flash_size_kb != 0xffff) && flash_size_kb); - /* read flash option register */ - retval = stm32l4_read_flash_reg_by_index(bank, STM32_FLASH_OPTR_INDEX, &options); - if (retval != ERROR_OK) - return retval; - stm32l4_info->bank1_sectors = 0; stm32l4_info->hole_sectors = 0; @@ -1783,7 +1831,8 @@ COMMAND_HANDLER(stm32l4_handle_lock_command) /* set readout protection level 1 by erasing the RDP option byte */ struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; - if (stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX], 0, 0x000000FF) != ERROR_OK) { + if (stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX], + RDP_LEVEL_1, FLASH_RDP_MASK) != ERROR_OK) { command_print(CMD, "%s failed to lock device", bank->driver->name); return ERROR_OK; } @@ -1817,7 +1866,7 @@ COMMAND_HANDLER(stm32l4_handle_unlock_command) struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; if (stm32l4_write_option(bank, stm32l4_info->flash_regs[STM32_FLASH_OPTR_INDEX], - RDP_LEVEL_0, 0x000000FF) != ERROR_OK) { + RDP_LEVEL_0, FLASH_RDP_MASK) != ERROR_OK) { command_print(CMD, "%s failed to unlock device", bank->driver->name); return ERROR_OK; } diff --git a/src/flash/nor/stm32l4x.h b/src/flash/nor/stm32l4x.h index 3e810a0..41b5ff8 100644 --- a/src/flash/nor/stm32l4x.h +++ b/src/flash/nor/stm32l4x.h @@ -56,9 +56,9 @@ #define OPTKEY1 0x08192A3B #define OPTKEY2 0x4C5D6E7F -#define RDP_LEVEL_0 0xAA -#define RDP_LEVEL_1 0xBB -#define RDP_LEVEL_2 0xCC +/* FLASH_OPTR register bits */ +#define FLASH_RDP_MASK 0xFF +#define FLASH_TZEN (1 << 31) /* other registers */ #define DBGMCU_IDCODE_G0 0x40015800 |