aboutsummaryrefslogtreecommitdiff
path: root/src/flash/nor
diff options
context:
space:
mode:
authorTarek BOCHKATI <tarek.bouchkati@gmail.com>2020-11-03 01:22:53 +0100
committerTomas Vanek <vanekt@fbl.cz>2021-03-24 17:18:29 +0000
commit6405d35f324f767c2ab88da12a600cb8e6c25f0e (patch)
tree3513a1863cb06ba36996a1ae0019d80b72bf6786 /src/flash/nor
parent88fa831839cf7e45f66064c9c74cfcf59b8d8c7e (diff)
downloadriscv-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.c65
-rw-r--r--src/flash/nor/stm32l4x.h6
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