From: OpenOCD-Gerrit <ope...@us...> - 2021-08-26 06:27:53
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 1247eee4e6e55889b14bec8d81c4748767bb67b8 (commit) from e609d5a5de84b3daf8b9524143e41a6c0713fd8f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1247eee4e6e55889b14bec8d81c4748767bb67b8 Author: Tarek BOCHKATI <tar...@gm...> Date: Tue May 25 11:54:50 2021 +0100 flash/stm32l4x: introduce flash programming without loader this capability permits to program the flash if we cannot reserve a workarea. the introduction the command 'stm32l4x flashloader <bank_id> [enable|disable]' helps to automatically skip using the flashloader if needed. Change-Id: Id29213c85ee5c7c487cfee21554f5a7ea50db6c9 Signed-off-by: Tarek BOCHKATI <tar...@gm...> Reviewed-on: https://review.openocd.org/c/openocd/+/6273 Reviewed-by: Oleksij Rempel <li...@re...> Tested-by: jenkins diff --git a/doc/openocd.texi b/doc/openocd.texi index 33812499a..4404807a6 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -7344,6 +7344,13 @@ Unlocks the entire stm32 device. The @var{num} parameter is a value shown by @command{flash banks}. @end deffn +@deffn Command {stm32l4x flashloader} num [@option{enable} | @option{disable}] +Enables or disables the flashloader usage (enabled by default), +when disabled it will fall back to direct memory access to program the Flash or OTP memories. +if neither @option{enabled} nor @option{disable} are specified, the command will display +the current configuration. +@end deffn + @deffn {Command} {stm32l4x mass_erase} num Mass erases the entire stm32l4x device. The @var{num} parameter is a value shown by @command{flash banks}. diff --git a/src/flash/nor/stm32l4x.c b/src/flash/nor/stm32l4x.c index de36d56c7..5bc23090f 100644 --- a/src/flash/nor/stm32l4x.c +++ b/src/flash/nor/stm32l4x.c @@ -116,6 +116,7 @@ /* Erase time can be as high as 25ms, 10x this and assume it's toast... */ #define FLASH_ERASE_TIMEOUT 250 +#define FLASH_WRITE_TIMEOUT 50 /* relevant STM32L4 flags ****************************************************/ @@ -223,6 +224,7 @@ struct stm32l4_flash_bank { uint32_t flash_regs_base; const uint32_t *flash_regs; bool otp_enabled; + bool use_flashloader; enum stm32l4_rdp rdp; bool tzen; uint32_t optr; @@ -545,6 +547,7 @@ FLASH_BANK_COMMAND_HANDLER(stm32l4_flash_bank_command) stm32l4_info->probed = false; stm32l4_info->otp_enabled = false; stm32l4_info->user_bank_size = bank->size; + stm32l4_info->use_flashloader = true; return ERROR_OK; } @@ -1362,6 +1365,49 @@ static int stm32l4_write_block(struct flash_bank *bank, const uint8_t *buffer, return retval; } +/* Count is in double-words */ +static int stm32l4_write_block_without_loader(struct flash_bank *bank, const uint8_t *buffer, + uint32_t offset, uint32_t count) +{ + struct target *target = bank->target; + uint32_t address = bank->base + offset; + int retval = ERROR_OK; + + /* wait for BSY bit */ + retval = stm32l4_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); + if (retval != ERROR_OK) + return retval; + + /* set PG in FLASH_CR */ + retval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_PG); + if (retval != ERROR_OK) + return retval; + + + /* write directly to flash memory */ + const uint8_t *src = buffer; + while (count--) { + retval = target_write_memory(target, address, 4, 2, src); + if (retval != ERROR_OK) + return retval; + + /* wait for BSY bit */ + retval = stm32l4_wait_status_busy(bank, FLASH_WRITE_TIMEOUT); + if (retval != ERROR_OK) + return retval; + + src += 8; + address += 8; + } + + /* reset PG in FLASH_CR */ + retval = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, 0); + if (retval != ERROR_OK) + return retval; + + return retval; +} + static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count) { @@ -1434,14 +1480,22 @@ static int stm32l4_write(struct flash_bank *bank, const uint8_t *buffer, if (retval != ERROR_OK) goto err_lock; - /* For TrustZone enabled devices, when TZEN is set and RDP level is 0.5, - * the debug is possible only in non-secure state. - * Thus means the flashloader will run in non-secure mode, - * and the workarea need to be in non-secure RAM */ - if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0_5)) - LOG_INFO("RDP level is 0.5, the work-area should reside in non-secure RAM"); + if (stm32l4_info->use_flashloader) { + /* For TrustZone enabled devices, when TZEN is set and RDP level is 0.5, + * the debug is possible only in non-secure state. + * Thus means the flashloader will run in non-secure mode, + * and the workarea need to be in non-secure RAM */ + if (stm32l4_info->tzen && (stm32l4_info->rdp == RDP_LEVEL_0_5)) + LOG_INFO("RDP level is 0.5, the work-area should reside in non-secure RAM"); + + retval = stm32l4_write_block(bank, buffer, offset, count / 8); + } + + if (!stm32l4_info->use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) { + LOG_INFO("falling back to single memory accesses"); + retval = stm32l4_write_block_without_loader(bank, buffer, offset, count / 8); + } - retval = stm32l4_write_block(bank, buffer, offset, count / 8); err_lock: retval2 = stm32l4_write_flash_reg_by_index(bank, STM32_FLASH_CR_INDEX, FLASH_LOCK); @@ -2017,6 +2071,26 @@ COMMAND_HANDLER(stm32l4_handle_trustzone_command) return stm32l4_perform_obl_launch(bank); } +COMMAND_HANDLER(stm32l4_handle_flashloader_command) +{ + if (CMD_ARGC < 1 || CMD_ARGC > 2) + return ERROR_COMMAND_SYNTAX_ERROR; + + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (retval != ERROR_OK) + return retval; + + struct stm32l4_flash_bank *stm32l4_info = bank->driver_priv; + + if (CMD_ARGC == 2) + COMMAND_PARSE_ENABLE(CMD_ARGV[1], stm32l4_info->use_flashloader); + + command_print(CMD, "FlashLoader usage is %s", stm32l4_info->use_flashloader ? "enabled" : "disabled"); + + return ERROR_OK; +} + COMMAND_HANDLER(stm32l4_handle_option_load_command) { if (CMD_ARGC != 1) @@ -2222,6 +2296,13 @@ static const struct command_registration stm32l4_exec_command_handlers[] = { .usage = "bank_id", .help = "Unlock entire protected flash device.", }, + { + .name = "flashloader", + .handler = stm32l4_handle_flashloader_command, + .mode = COMMAND_EXEC, + .usage = "<bank_id> [enable|disable]", + .help = "Configure the flashloader usage", + }, { .name = "mass_erase", .handler = stm32l4_handle_mass_erase_command, ----------------------------------------------------------------------- Summary of changes: doc/openocd.texi | 7 ++++ src/flash/nor/stm32l4x.c | 95 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 7 deletions(-) hooks/post-receive -- Main OpenOCD repository |