aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2021-11-16 19:04:05 +0100
committerTomas Vanek <vanekt@fbl.cz>2022-04-13 16:52:41 +0000
commite3f4ea0b574d952672d57792895a91065aa7a569 (patch)
treee0abfb75b5e401a2c431a6d82614c84d5e04fe96
parent10f933915d3234cda56f55752a14ec6c4734a6fd (diff)
downloadriscv-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.c47
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(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* flash base (in), status (out) */
init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (halfword-16bit) */
init_reg_param(&reg_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(&reg_params[i]);
+
target_free_working_area(target, source);
target_free_working_area(target, write_algorithm);
- destroy_reg_param(&reg_params[0]);
- destroy_reg_param(&reg_params[1]);
- destroy_reg_param(&reg_params[2]);
- destroy_reg_param(&reg_params[3]);
- destroy_reg_param(&reg_params[4]);
-
return retval;
}