+ }
+
+ 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);
+
+ return retval;
+}
+
+static int stm32x_write_block_riscv(struct flash_bank *bank, const uint8_t *buffer,
+ uint32_t address, uint32_t hwords_count)
+{
+ struct target *target = bank->target;
+ uint32_t buffer_size;
+ struct working_area *write_algorithm;
+ struct working_area *source;
+ static const uint8_t gd32vf103_flash_write_code[] = {
+#include "../../../contrib/loaders/flash/gd32vf103/gd32vf103.inc"
+ };
+
+ /* flash write code */
+ if (target_alloc_working_area(target, sizeof(gd32vf103_flash_write_code),
+ &write_algorithm) != ERROR_OK) {
+ LOG_WARNING("no working area available, can't do block memory writes");
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ int retval = target_write_buffer(target, write_algorithm->address,
+ sizeof(gd32vf103_flash_write_code), gd32vf103_flash_write_code);
+ if (retval != ERROR_OK) {
+ target_free_working_area(target, write_algorithm);
+ return retval;
+ }
+
+ /* memory buffer */
+ buffer_size = target_get_working_area_avail(target);
+ buffer_size = MIN(hwords_count * 2, MAX(buffer_size, 256));
+
+ retval = target_alloc_working_area(target, buffer_size, &source);
+ /* Allocated size is always 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[4];
+
+ init_reg_param(®_params[0], "a0", 32, PARAM_OUT); /* poiner to FLASH_SR */
+ init_reg_param(®_params[1], "a1", 32, PARAM_OUT); /* count (halfword-16bit) */
+ init_reg_param(®_params[2], "a2", 32, PARAM_OUT); /* buffer start */
+ init_reg_param(®_params[3], "a3", 32, PARAM_IN_OUT); /* target address */
+
+ while (hwords_count > 0) {
+ uint32_t thisrun_hwords = source->size / 2;