#include "imp.h"
#include <helper/align.h>
#include <helper/binarybuffer.h>
+#include <helper/bits.h>
#include <target/algorithm.h>
+#include <target/arm_adi_v5.h>
#include <target/cortex_m.h>
-#include "bits.h"
#include "stm32l4x.h"
/* STM32L4xxx series for reference.
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;
stm32l4_info->probed = false;
stm32l4_info->otp_enabled = false;
stm32l4_info->user_bank_size = bank->size;
- stm32l4_info->use_flashloader = true;
return ERROR_OK;
}
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARM_MODE_THREAD;
- init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* buffer start, status (out) */
+ /* contrib/loaders/flash/stm32/stm32l4x.c:write() arguments */
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* stm32l4_work_area ptr , status (out) */
init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* buffer end */
init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* target address */
init_reg_param(®_params[3], "r3", 32, PARAM_OUT); /* count (of stm32l4_info->data_width) */
- init_reg_param(®_params[4], "sp", 32, PARAM_OUT); /* write algo stack pointer */
buf_set_u32(reg_params[0].value, 0, 32, source->address);
buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
buf_set_u32(reg_params[2].value, 0, 32, address);
buf_set_u32(reg_params[3].value, 0, 32, count);
+
+ /* write algo stack pointer */
+ init_reg_param(®_params[4], "sp", 32, PARAM_OUT);
buf_set_u32(reg_params[4].value, 0, 32, source->address +
offsetof(struct stm32l4_work_area, stack) + LDR_STACK_SIZE);
if (retval != ERROR_OK)
goto err_lock;
- 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 / stm32l4_info->data_width);
- }
+ /* 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_WARNING("RDP = 0x55, the work-area should be in non-secure RAM (check SAU partitioning)");
+
+ /* first try to write using the loader, for better performance */
+ retval = stm32l4_write_block(bank, buffer, offset,
+ count / stm32l4_info->data_width);
- if (!stm32l4_info->use_flashloader || retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
- LOG_INFO("falling back to single memory accesses");
+ /* if resources are not available write without a loader */
+ if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
+ LOG_WARNING("falling back to programming without a flash loader (slower)");
retval = stm32l4_write_block_without_loader(bank, buffer, offset,
count / stm32l4_info->data_width);
}
/* STM32L55/L56xx can be single/dual bank:
* if size = 512K check DBANK bit
* if size = 256K check DB256K bit
+ *
+ * default page size is 4kb, if DBANK = 1, the page size is 2kb.
*/
- page_size_kb = 4;
+
+ page_size_kb = (stm32l4_info->optr & FLASH_L5_DBANK) ? 2 : 4;
num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages;
+
if ((is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DBANK)) ||
(!is_max_flash_size && (stm32l4_info->optr & FLASH_L5_DB256))) {
stm32l4_info->dual_bank_mode = true;
- page_size_kb = 2;
- num_pages = flash_size_kb / page_size_kb;
stm32l4_info->bank1_sectors = num_pages / 2;
}
break;
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)
.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,