diff options
author | Tomas Vanek <vanekt@fbl.cz> | 2021-11-16 19:04:05 +0100 |
---|---|---|
committer | Tomas Vanek <vanekt@fbl.cz> | 2022-04-13 16:52:41 +0000 |
commit | e3f4ea0b574d952672d57792895a91065aa7a569 (patch) | |
tree | e0abfb75b5e401a2c431a6d82614c84d5e04fe96 | |
parent | 10f933915d3234cda56f55752a14ec6c4734a6fd (diff) | |
download | riscv-openocd-e3f4ea0b574d952672d57792895a91065aa7a569.zip riscv-openocd-e3f4ea0b574d952672d57792895a91065aa7a569.tar.gz riscv-openocd-e3f4ea0b574d952672d57792895a91065aa7a569.tar.bz2 |
flash/nor/stm32f1x: tidy up async algo supporting code
Use target_get_working_area_avail() instead of try-fail iteration.
Call destroy_reg_param() in a for cycle.
Change-Id: I1891d1ffdea99010c6ab66b9578400b9d7922e20
Signed-off-by: Tomas Vanek <vanekt@fbl.cz>
Reviewed-on: https://review.openocd.org/c/openocd/+/6708
Tested-by: jenkins
Reviewed-by: Tarek BOCHKATI <tarek.bouchkati@gmail.com>
-rw-r--r-- | src/flash/nor/stm32f1x.c | 47 |
1 files changed, 26 insertions, 21 deletions
diff --git a/src/flash/nor/stm32f1x.c b/src/flash/nor/stm32f1x.c index 664524b..f4b1daa 100644 --- a/src/flash/nor/stm32f1x.c +++ b/src/flash/nor/stm32f1x.c @@ -452,12 +452,11 @@ static int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buff { struct stm32x_flash_bank *stm32x_info = bank->driver_priv; struct target *target = bank->target; - uint32_t buffer_size = 16384; + uint32_t buffer_size; struct working_area *write_algorithm; struct working_area *source; - struct reg_param reg_params[5]; struct armv7m_algorithm armv7m_info; - int retval = ERROR_OK; + int retval; static const uint8_t stm32x_flash_write_code[] = { #include "../../../contrib/loaders/flash/stm32/stm32f1x.inc" @@ -478,19 +477,28 @@ static int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buff } /* memory buffer */ - while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { - buffer_size /= 2; - buffer_size &= ~3UL; /* Make sure it's 4 byte aligned */ - if (buffer_size <= 256) { - /* we already allocated the writing code, but failed to get a - * buffer, free the algorithm */ - target_free_working_area(target, write_algorithm); - - LOG_WARNING("no large enough working area available, can't do block memory writes"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } + buffer_size = target_get_working_area_avail(target); + buffer_size = MIN(hwords_count * 2, MAX(buffer_size, 256)); + /* Normally we allocate all available working area. + * MIN shrinks buffer_size if the size of the written block is smaller. + * MAX prevents using async algo if the available working area is smaller + * than 256, the following allocation fails with + * ERROR_TARGET_RESOURCE_NOT_AVAILABLE and slow flashing takes place. + */ + + retval = target_alloc_working_area(target, buffer_size, &source); + /* Allocated size is always 32-bit word aligned */ + if (retval != ERROR_OK) { + target_free_working_area(target, write_algorithm); + LOG_WARNING("no large enough working area available, can't do block memory writes"); + /* target_alloc_working_area() may return ERROR_FAIL if area backup fails: + * convert any error to ERROR_TARGET_RESOURCE_NOT_AVAILABLE + */ + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; } + struct reg_param reg_params[5]; + init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */ init_reg_param(®_params[1], "r1", 32, PARAM_OUT); /* count (halfword-16bit) */ init_reg_param(®_params[2], "r2", 32, PARAM_OUT); /* buffer start */ @@ -508,7 +516,7 @@ static int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buff retval = target_run_flash_async_algorithm(target, buffer, hwords_count, 2, 0, NULL, - 5, reg_params, + ARRAY_SIZE(reg_params), reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info); @@ -530,15 +538,12 @@ static int stm32x_write_block_async(struct flash_bank *bank, const uint8_t *buff } } + for (unsigned int i = 0; i < ARRAY_SIZE(reg_params); i++) + destroy_reg_param(®_params[i]); + target_free_working_area(target, source); target_free_working_area(target, write_algorithm); - destroy_reg_param(®_params[0]); - destroy_reg_param(®_params[1]); - destroy_reg_param(®_params[2]); - destroy_reg_param(®_params[3]); - destroy_reg_param(®_params[4]); - return retval; } |