[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openocd-development
Subject:    [PATCH]: 7da084523a target: add alternative work area config
From:       gerrit () openocd ! org
Date:       2022-05-24 18:43:14
Message-ID: 20220524184314.AB0FD125 () openocd ! org
[Download RAW message or body]

This is an automated email from Gerrit.

"Erhan Kurubas <erhan.kurubas@espressif.com>" just uploaded a new patch set to \
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/6991

-- gerrit

commit 7da084523a0839bf1b382f1b9f66cb7a97d66e8a
Author: Erhan Kurubas <erhan.kurubas@espressif.com>
Date:   Thu Apr 21 07:53:54 2022 +0200

    target: add alternative work area config
    
    During stub flasher operations Espressif targets use 2 different
    working area in sram (for code and data)
    Currently OpenOCD support single work-area system which is not
    suitable for Harward architecture CPU.
    
    In this patch, we added another command set to specify working area
    for the data space. (-alt-work-area-xxx)
    
    Signed-off-by: Erhan Kurubas <erhan.kurubas@espressif.com>
    Change-Id: I50aab41a6405a353ac8ce6fdf70ca6f1198169f6

diff --git a/src/flash/nand/lpc3180.c b/src/flash/nand/lpc3180.c
index bda7b87c32..b15065e818 100644
--- a/src/flash/nand/lpc3180.c
+++ b/src/flash/nand/lpc3180.c
@@ -593,22 +593,22 @@ static int lpc3180_write_page(struct nand_device *nand,
 				return retval;
 
 			/* allocate a working area */
-			if (target->working_area_size < (uint32_t) nand->page_size + 0x200) {
+			if (target->working_area_cfg.size < (uint32_t) nand->page_size + 0x200) {
 				LOG_ERROR("Reserve at least 0x%x physical target working area",
 					nand->page_size + 0x200);
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			if (target->working_area_phys%4) {
+			if (target->working_area_cfg.phys % 4) {
 				LOG_ERROR(
 					"Reserve the physical target working area at word boundary");
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			if (target_alloc_working_area(target, target->working_area_size,
+			if (target_alloc_working_area(target, target->working_area_cfg.size,
 				    &pworking_area) != ERROR_OK) {
 				LOG_ERROR("no working area specified, can't read LPC internal flash");
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			target_mem_base = target->working_area_phys;
+			target_mem_base = target->working_area_cfg.phys;
 
 			if (nand->page_size == 2048)
 				page_buffer = malloc(2048);
@@ -974,22 +974,22 @@ static int lpc3180_read_page(struct nand_device *nand,
 				return retval;
 
 			/* allocate a working area */
-			if (target->working_area_size < (uint32_t) nand->page_size + 0x200) {
+			if (target->working_area_cfg.size < (uint32_t) nand->page_size + 0x200) {
 				LOG_ERROR("Reserve at least 0x%x physical target working area",
 					nand->page_size + 0x200);
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			if (target->working_area_phys%4) {
+			if (target->working_area_cfg.phys % 4) {
 				LOG_ERROR(
 					"Reserve the physical target working area at word boundary");
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			if (target_alloc_working_area(target, target->working_area_size,
+			if (target_alloc_working_area(target, target->working_area_cfg.size,
 				    &pworking_area) != ERROR_OK) {
 				LOG_ERROR("no working area specified, can't read LPC internal flash");
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
-			target_mem_base = target->working_area_phys;
+			target_mem_base = target->working_area_cfg.phys;
 
 			if (nand->page_size == 2048)
 				page_buffer = malloc(2048);
diff --git a/src/flash/nor/fm3.c b/src/flash/nor/fm3.c
index 831f342571..d5c1d011f7 100644
--- a/src/flash/nor/fm3.c
+++ b/src/flash/nor/fm3.c
@@ -362,8 +362,8 @@ static int fm3_write_block(struct flash_bank *bank, const uint8_t \
*buffer,  uint32_t u32_flash_seq_address2;
 
 	/* Increase buffer_size if needed */
-	if (buffer_size < (target->working_area_size / 2))
-		buffer_size = (target->working_area_size / 2);
+	if (buffer_size < target->working_area_cfg.size / 2)
+		buffer_size = target->working_area_cfg.size / 2;
 
 	u32_flash_type = (uint32_t) fm3_info->flashtype;
 
diff --git a/src/flash/nor/numicro.c b/src/flash/nor/numicro.c
index cb7c1df836..58b85bbdfb 100644
--- a/src/flash/nor/numicro.c
+++ b/src/flash/nor/numicro.c
@@ -1345,8 +1345,8 @@ static int numicro_writeblock(struct flash_bank *bank, const \
                uint8_t *buffer,
 	 */
 
 	/* Increase buffer_size if needed */
-	if (buffer_size < (target->working_area_size/2))
-		buffer_size = (target->working_area_size/2);
+	if (buffer_size < target->working_area_cfg.size / 2)
+		buffer_size = target->working_area_cfg.size / 2;
 
 	/* check code alignment */
 	if (offset & 0x1) {
diff --git a/src/flash/nor/psoc5lp.c b/src/flash/nor/psoc5lp.c
index f383213ba6..80a9db49a7 100644
--- a/src/flash/nor/psoc5lp.c
+++ b/src/flash/nor/psoc5lp.c
@@ -1195,7 +1195,7 @@ static int psoc5lp_write(struct flash_bank *bank, const uint8_t \
*buffer,  LOG_DEBUG("Get_Temp: sign 0x%02" PRIx8 ", magnitude 0x%02" PRIx8,
 		temp[0], temp[1]);
 
-	assert(target_get_working_area_avail(target) == target->working_area_size);
+	assert(target_get_working_area_avail(target) == target->working_area_cfg.size);
 	retval = target_alloc_working_area(target,
 			target_get_working_area_avail(target) / 2, &code_area);
 	if (retval != ERROR_OK) {
diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index da047c3d02..45daa1474b 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -2717,7 +2717,7 @@ int arm7_9_check_reset(struct target *target)
 		LOG_WARNING(
 			"NOTE! DCC downloads have not been enabled, defaulting to slow memory writes. \
Type 'help dcc'.");  
-	if (get_target_reset_nag() && (target->working_area_size == 0))
+	if (get_target_reset_nag() && (target->working_area_cfg.size == 0))
 		LOG_WARNING("NOTE! Severe performance degradation without working memory \
enabled.");  
 	if (get_target_reset_nag() && !arm7_9->fast_memory_access)
diff --git a/src/target/target.c b/src/target/target.c
index 25e58f11dc..3c90c04a7a 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -1968,9 +1968,9 @@ int64_t target_timer_next_event(void)
 }
 
 /* Prints the working area layout for debug purposes */
-static void print_wa_layout(struct target *target)
+static void print_wa_layout(struct working_area_config *wa_cfg)
 {
-	struct working_area *c = target->working_areas;
+	struct working_area *c = wa_cfg->areas;
 
 	while (c) {
 		LOG_DEBUG("%c%c " TARGET_ADDR_FMT "-" TARGET_ADDR_FMT " (%" PRIu32 " bytes)",
@@ -2011,9 +2011,9 @@ static void target_split_working_area(struct working_area \
*area, uint32_t size)  }
 
 /* Merge all adjacent free areas into one */
-static void target_merge_working_areas(struct target *target)
+static void target_merge_working_areas(struct working_area_config *wa_cfg)
 {
-	struct working_area *c = target->working_areas;
+	struct working_area *c = wa_cfg->areas;
 
 	while (c && c->next) {
 		assert(c->next->address == c->address + c->size); /* This is an invariant */
@@ -2039,10 +2039,14 @@ static void target_merge_working_areas(struct target *target)
 	}
 }
 
-int target_alloc_working_area_try(struct target *target, uint32_t size, struct \
working_area **area) +static int alloc_working_area_try_do(
+		struct target *target,
+		struct working_area_config *wa_cfg,
+		uint32_t size,
+		struct working_area **area)
 {
 	/* Reevaluate working area address based on MMU state*/
-	if (!target->working_areas) {
+	if (!wa_cfg->areas) {
 		int retval;
 		int enabled;
 
@@ -2051,22 +2055,22 @@ int target_alloc_working_area_try(struct target *target, \
uint32_t size, struct w  return retval;
 
 		if (!enabled) {
-			if (target->working_area_phys_spec) {
+			if (wa_cfg->phys_spec) {
 				LOG_DEBUG("MMU disabled, using physical "
-					"address for working memory " TARGET_ADDR_FMT,
-					target->working_area_phys);
-				target->working_area = target->working_area_phys;
+					"address for working memory "TARGET_ADDR_FMT,
+					wa_cfg->phys);
+				wa_cfg->area = wa_cfg->phys;
 			} else {
 				LOG_ERROR("No working memory available. "
 					"Specify -work-area-phys to target.");
 				return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 			}
 		} else {
-			if (target->working_area_virt_spec) {
+			if (wa_cfg->virt_spec) {
 				LOG_DEBUG("MMU enabled, using virtual "
-					"address for working memory " TARGET_ADDR_FMT,
-					target->working_area_virt);
-				target->working_area = target->working_area_virt;
+					"address for working memory "TARGET_ADDR_FMT,
+					wa_cfg->virt);
+				wa_cfg->area = wa_cfg->virt;
 			} else {
 				LOG_ERROR("No working memory available. "
 					"Specify -work-area-virt to target.");
@@ -2078,21 +2082,21 @@ int target_alloc_working_area_try(struct target *target, \
uint32_t size, struct w  struct working_area *new_wa = malloc(sizeof(*new_wa));
 		if (new_wa) {
 			new_wa->next = NULL;
-			new_wa->size = target->working_area_size & ~3UL; /* 4-byte align */
-			new_wa->address = target->working_area;
+			new_wa->size = ALIGN_DOWN(wa_cfg->size, 4);
+			new_wa->address = wa_cfg->area;
 			new_wa->backup = NULL;
 			new_wa->user = NULL;
 			new_wa->free = true;
 		}
 
-		target->working_areas = new_wa;
+		wa_cfg->areas = new_wa;
 	}
 
 	/* only allocate multiples of 4 byte */
 	if (size % 4)
 		size = (size + 3) & (~3UL);
 
-	struct working_area *c = target->working_areas;
+	struct working_area *c = wa_cfg->areas;
 
 	/* Find the first large enough working area */
 	while (c) {
@@ -2110,7 +2114,7 @@ int target_alloc_working_area_try(struct target *target, \
uint32_t size, struct w  LOG_DEBUG("allocated new working area of %" PRIu32 " bytes \
at address " TARGET_ADDR_FMT,  size, c->address);
 
-	if (target->backup_working_area) {
+	if (wa_cfg->backup) {
 		if (!c->backup) {
 			c->backup = malloc(c->size);
 			if (!c->backup)
@@ -2129,27 +2133,49 @@ int target_alloc_working_area_try(struct target *target, \
uint32_t size, struct w  /* user pointer */
 	c->user = area;
 
-	print_wa_layout(target);
+	print_wa_layout(wa_cfg);
 
 	return ERROR_OK;
 }
 
+int target_alloc_working_area_try(struct target *target, uint32_t size, struct \
working_area **area) +{
+	return alloc_working_area_try_do(target, &target->working_area_cfg, size, area);
+}
+
+int target_alloc_alt_working_area_try(struct target *target, uint32_t size, struct \
working_area **area) +{
+	return alloc_working_area_try_do(target, &target->alt_working_area_cfg, size, \
area); +}
+
 int target_alloc_working_area(struct target *target, uint32_t size, struct \
working_area **area)  {
 	int retval;
 
 	retval = target_alloc_working_area_try(target, size, area);
 	if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
-		LOG_WARNING("not enough working area available(requested %"PRIu32")", size);
+		LOG_WARNING("not enough working area available(requested %" PRIu32 ")", size);
 	return retval;
+}
+
+int target_alloc_alt_working_area(struct target *target, uint32_t size, struct \
working_area **area) +{
+	int retval;
 
+	retval = target_alloc_alt_working_area_try(target, size, area);
+	if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
+		LOG_WARNING("not enough working area available(requested %" PRIu32 ")", size);
+	return retval;
 }
 
-static int target_restore_working_area(struct target *target, struct working_area \
*area) +static int target_restore_working_area(
+		struct target *target,
+		struct working_area_config *wa_cfg,
+		struct working_area *area)
 {
 	int retval = ERROR_OK;
 
-	if (target->backup_working_area && area->backup) {
+	if (wa_cfg->backup && area->backup) {
 		retval = target_write_memory(target, area->address, 4, area->size / 4, \
area->backup);  if (retval != ERROR_OK)
 			LOG_ERROR("failed to restore %" PRIu32 " bytes of working area at address " \
TARGET_ADDR_FMT, @@ -2160,14 +2186,18 @@ static int \
target_restore_working_area(struct target *target, struct working_are  }
 
 /* Restore the area's backup memory, if any, and return the area to the allocation \
                pool */
-static int target_free_working_area_restore(struct target *target, struct \
working_area *area, int restore) +static int target_free_working_area_restore(
+		struct target *target,
+		struct working_area_config *wa_cfg,
+		struct working_area *area,
+		int restore)
 {
 	if (!area || area->free)
 		return ERROR_OK;
 
 	int retval = ERROR_OK;
 	if (restore) {
-		retval = target_restore_working_area(target, area);
+		retval = target_restore_working_area(target, wa_cfg, area);
 		/* REVISIT: Perhaps the area should be freed even if restoring fails. */
 		if (retval != ERROR_OK)
 			return retval;
@@ -2185,24 +2215,32 @@ static int target_free_working_area_restore(struct target \
                *target, struct workin
 	*area->user = NULL;
 	area->user = NULL;
 
-	target_merge_working_areas(target);
+	target_merge_working_areas(wa_cfg);
 
-	print_wa_layout(target);
+	print_wa_layout(wa_cfg);
 
 	return retval;
 }
 
 int target_free_working_area(struct target *target, struct working_area *area)
 {
-	return target_free_working_area_restore(target, area, 1);
+	return target_free_working_area_restore(target, &target->working_area_cfg, area, \
1); +}
+
+int target_free_alt_working_area(struct target *target, struct working_area *area)
+{
+	return target_free_working_area_restore(target, &target->alt_working_area_cfg, \
area, 1);  }
 
 /* free resources and restore memory, if restoring memory fails,
  * free up resources anyway
  */
-static void target_free_all_working_areas_restore(struct target *target, int \
restore) +static void target_free_all_working_areas_restore(
+		struct target *target,
+		struct working_area_config *wa_cfg,
+		int restore)
 {
-	struct working_area *c = target->working_areas;
+	struct working_area *c = wa_cfg->areas;
 
 	LOG_DEBUG("freeing all working areas");
 
@@ -2210,7 +2248,7 @@ static void target_free_all_working_areas_restore(struct target \
*target, int res  while (c) {
 		if (!c->free) {
 			if (restore)
-				target_restore_working_area(target, c);
+				target_restore_working_area(target, wa_cfg, c);
 			c->free = true;
 			*c->user = NULL; /* Same as above */
 			c->user = NULL;
@@ -2219,32 +2257,41 @@ static void target_free_all_working_areas_restore(struct \
target *target, int res  }
 
 	/* Run a merge pass to combine all areas into one */
-	target_merge_working_areas(target);
+	target_merge_working_areas(wa_cfg);
 
-	print_wa_layout(target);
+	print_wa_layout(wa_cfg);
 }
 
-void target_free_all_working_areas(struct target *target)
+static void target_free_all_working_areas_do(struct target *target, struct \
working_area_config *wa_cfg)  {
-	target_free_all_working_areas_restore(target, 1);
-
+	target_free_all_working_areas_restore(target, wa_cfg, 1);
 	/* Now we have none or only one working area marked as free */
-	if (target->working_areas) {
+	if (wa_cfg->areas) {
 		/* Free the last one to allow on-the-fly moving and resizing */
-		free(target->working_areas->backup);
-		free(target->working_areas);
-		target->working_areas = NULL;
+		free(wa_cfg->areas->backup);
+		free(wa_cfg->areas);
+		wa_cfg->areas = NULL;
 	}
 }
 
+void target_free_all_working_areas(struct target *target)
+{
+	target_free_all_working_areas_do(target, &target->working_area_cfg);
+}
+
+void target_free_all_alt_working_areas(struct target *target)
+{
+	target_free_all_working_areas_do(target, &target->alt_working_area_cfg);
+}
+
 /* Find the largest number of bytes that can be allocated */
-uint32_t target_get_working_area_avail(struct target *target)
+static uint32_t get_working_area_avail_do(struct target *target, struct \
working_area_config *wa_cfg)  {
-	struct working_area *c = target->working_areas;
+	struct working_area *c = wa_cfg->areas;
 	uint32_t max_size = 0;
 
 	if (!c)
-		return target->working_area_size;
+		return wa_cfg->size;
 
 	while (c) {
 		if (c->free && max_size < c->size)
@@ -2256,6 +2303,16 @@ uint32_t target_get_working_area_avail(struct target *target)
 	return max_size;
 }
 
+uint32_t target_get_working_area_avail(struct target *target)
+{
+	return get_working_area_avail_do(target, &target->working_area_cfg);
+}
+
+uint32_t target_get_alt_working_area_avail(struct target *target)
+{
+	return get_working_area_avail_do(target, &target->alt_working_area_cfg);
+}
+
 static void target_destroy(struct target *target)
 {
 	if (target->type->deinit_target)
@@ -5303,6 +5360,10 @@ enum target_cfg_param {
 	TCFG_CHAIN_POSITION,
 	TCFG_DBGBASE,
 	TCFG_RTOS,
+	TCFG_ALT_WORK_AREA_VIRT,
+	TCFG_ALT_WORK_AREA_PHYS,
+	TCFG_ALT_WORK_AREA_SIZE,
+	TCFG_ALT_WORK_AREA_BACKUP,
 	TCFG_DEFER_EXAMINE,
 	TCFG_GDB_PORT,
 	TCFG_GDB_MAX_CONNECTIONS,
@@ -5320,6 +5381,10 @@ static struct jim_nvp nvp_config_opts[] = {
 	{ .name = "-chain-position",   .value = TCFG_CHAIN_POSITION },
 	{ .name = "-dbgbase",          .value = TCFG_DBGBASE },
 	{ .name = "-rtos",             .value = TCFG_RTOS },
+	{ .name = "-alt-work-area-virt",   .value = TCFG_ALT_WORK_AREA_VIRT },
+	{ .name = "-alt-work-area-phys",   .value = TCFG_ALT_WORK_AREA_PHYS },
+	{ .name = "-alt-work-area-size",   .value = TCFG_ALT_WORK_AREA_SIZE },
+	{ .name = "-alt-work-area-backup", .value = TCFG_ALT_WORK_AREA_BACKUP },
 	{ .name = "-defer-examine",    .value = TCFG_DEFER_EXAMINE },
 	{ .name = "-gdb-port",         .value = TCFG_GDB_PORT },
 	{ .name = "-gdb-max-connections",   .value = TCFG_GDB_MAX_CONNECTIONS },
@@ -5460,65 +5525,107 @@ no_params:
 			break;
 
 		case TCFG_WORK_AREA_VIRT:
+		case TCFG_ALT_WORK_AREA_VIRT:
 			if (goi->isconfigure) {
-				target_free_all_working_areas(target);
+				target_free_all_working_areas_restore(target, n->value == \
TCFG_ALT_WORK_AREA_VIRT ? +					&target->alt_working_area_cfg : \
&target->working_area_cfg, 1);  e = jim_getopt_wide(goi, &w);
 				if (e != JIM_OK)
 					return e;
-				target->working_area_virt = w;
-				target->working_area_virt_spec = true;
+				if (n->value == TCFG_ALT_WORK_AREA_VIRT) {
+					target->alt_working_area_cfg.virt = w;
+					target->alt_working_area_cfg.virt_spec = true;
+				} else {
+					target->working_area_cfg.virt = w;
+					target->working_area_cfg.virt_spec = true;
+				}
 			} else {
 				if (goi->argc != 0)
 					goto no_params;
 			}
-			Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_virt)); +			if (n->value == TCFG_ALT_WORK_AREA_VIRT)
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->alt_working_area_cfg.virt)); +			else
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_cfg.virt)); +
 			/* loop for more */
 			break;
 
 		case TCFG_WORK_AREA_PHYS:
+		case TCFG_ALT_WORK_AREA_PHYS:
 			if (goi->isconfigure) {
-				target_free_all_working_areas(target);
+				target_free_all_working_areas_restore(target, n->value == \
TCFG_ALT_WORK_AREA_VIRT ? +					&target->alt_working_area_cfg : \
&target->working_area_cfg, 1);  e = jim_getopt_wide(goi, &w);
 				if (e != JIM_OK)
 					return e;
-				target->working_area_phys = w;
-				target->working_area_phys_spec = true;
+				if (n->value == TCFG_ALT_WORK_AREA_PHYS) {
+					target->alt_working_area_cfg.phys = w;
+					target->alt_working_area_cfg.phys_spec = true;
+				} else {
+					target->working_area_cfg.phys = w;
+					target->working_area_cfg.phys_spec = true;
+				}
 			} else {
 				if (goi->argc != 0)
 					goto no_params;
 			}
-			Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_phys)); +			if (n->value == TCFG_ALT_WORK_AREA_PHYS)
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->alt_working_area_cfg.phys)); +			else
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_cfg.phys)); +
 			/* loop for more */
 			break;
 
 		case TCFG_WORK_AREA_SIZE:
+		case TCFG_ALT_WORK_AREA_SIZE:
 			if (goi->isconfigure) {
-				target_free_all_working_areas(target);
+				target_free_all_working_areas_restore(target, n->value == \
TCFG_ALT_WORK_AREA_VIRT ? +					&target->alt_working_area_cfg : \
&target->working_area_cfg, 1);  e = jim_getopt_wide(goi, &w);
 				if (e != JIM_OK)
 					return e;
-				target->working_area_size = w;
+				if (n->value == TCFG_ALT_WORK_AREA_SIZE)
+					target->alt_working_area_cfg.size = w;
+				else
+					target->working_area_cfg.size = w;
+
 			} else {
 				if (goi->argc != 0)
 					goto no_params;
 			}
-			Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_size)); +			if (n->value == TCFG_ALT_WORK_AREA_SIZE)
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->alt_working_area_cfg.size)); +			else
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_cfg.size)); +
 			/* loop for more */
 			break;
 
 		case TCFG_WORK_AREA_BACKUP:
+		case TCFG_ALT_WORK_AREA_BACKUP:
 			if (goi->isconfigure) {
-				target_free_all_working_areas(target);
+				target_free_all_working_areas_restore(target, n->value == \
TCFG_ALT_WORK_AREA_VIRT ? +					&target->alt_working_area_cfg : \
&target->working_area_cfg, 1);  e = jim_getopt_wide(goi, &w);
 				if (e != JIM_OK)
 					return e;
 				/* make this exactly 1 or 0 */
-				target->backup_working_area = (!!w);
+				if (n->value == TCFG_ALT_WORK_AREA_BACKUP)
+					target->alt_working_area_cfg.backup = (!!w);
+				else
+					target->working_area_cfg.backup = (!!w);
+
 			} else {
 				if (goi->argc != 0)
 					goto no_params;
 			}
-			Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->backup_working_area)); +			if (n->value == TCFG_ALT_WORK_AREA_BACKUP)
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->alt_working_area_cfg.backup)); +			else
+				Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, \
target->working_area_cfg.backup)); +
 			/* loop for more e*/
 			break;
 
@@ -5570,6 +5677,7 @@ no_params:
 				}
 
 				target_free_all_working_areas(target);
+				target_free_all_alt_working_areas(target);
 				e = jim_getopt_obj(goi, &o_t);
 				if (e != JIM_OK)
 					return e;
@@ -5850,7 +5958,8 @@ static int jim_target_reset(Jim_Interp *interp, int argc, \
Jim_Obj *const *argv)  /* determine if we should halt or not. */
 	target->reset_halt = (a != 0);
 	/* When this happens - all workareas are invalid. */
-	target_free_all_working_areas_restore(target, 0);
+	target_free_all_working_areas_restore(target, &target->working_area_cfg, 0);
+	target_free_all_working_areas_restore(target, &target->alt_working_area_cfg, 0);
 
 	/* do the assert */
 	if (n->value == NVP_ASSERT)
@@ -6251,10 +6360,14 @@ static int target_create(struct jim_getopt_info *goi)
 	/* default to first core, override with -coreid */
 	target->coreid = 0;
 
-	target->working_area        = 0x0;
-	target->working_area_size   = 0x0;
-	target->working_areas       = NULL;
-	target->backup_working_area = 0;
+	target->working_area_cfg.area       = 0x0;
+	target->working_area_cfg.size       = 0x0;
+	target->working_area_cfg.areas      = NULL;
+	target->working_area_cfg.backup     = 0;
+	target->alt_working_area_cfg.area   = 0x0;
+	target->alt_working_area_cfg.size   = 0x0;
+	target->alt_working_area_cfg.areas  = NULL;
+	target->alt_working_area_cfg.backup = 0;
 
 	target->state               = TARGET_UNKNOWN;
 	target->debug_reason        = DBG_REASON_UNDEFINED;
diff --git a/src/target/target.h b/src/target/target.h
index 1f1a354207..110ada50cc 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -127,6 +127,18 @@ enum target_register_class {
 	REG_CLASS_GENERAL,
 };
 
+struct working_area_config {
+	target_addr_t area;			/* working area (initialised RAM). Evaluated
+										 * upon first allocation from virtual/physical address. */
+	bool virt_spec;				/* virtual address specified? */
+	target_addr_t virt;			/* virtual address */
+	bool phys_spec;				/* physical address specified? */
+	target_addr_t phys;			/* physical address */
+	uint32_t size;				/* size in bytes */
+	uint32_t backup;			/* whether the content of the working area has to be preserved \
*/ +	struct working_area *areas;	/* list of allocated working areas */
+};
+
 /* target_type.h contains the full definition of struct target_type */
 struct target {
 	struct target_type *type;			/* target type definition (name, access functions) */
@@ -158,15 +170,10 @@ struct target {
 	struct target_event_action *event_action;
 
 	bool reset_halt;						/* attempt resetting the CPU into the halted mode? */
-	target_addr_t working_area;				/* working area (initialised RAM). Evaluated
-										 * upon first allocation from virtual/physical address. */
-	bool working_area_virt_spec;		/* virtual address specified? */
-	target_addr_t working_area_virt;			/* virtual address */
-	bool working_area_phys_spec;		/* physical address specified? */
-	target_addr_t working_area_phys;			/* physical address */
-	uint32_t working_area_size;			/* size in bytes */
-	uint32_t backup_working_area;		/* whether the content of the working area has to be \
                preserved */
-	struct working_area *working_areas;/* list of allocated working areas */
+
+	struct working_area_config working_area_cfg;
+	struct working_area_config alt_working_area_cfg;
+
 	enum target_debug_reason debug_reason;/* reason why the target entered debug state \
*/  enum target_endianness endianness;	/* target endianness */
 	/* also see: target_state_name() */
@@ -729,6 +736,8 @@ const char *target_reset_mode_name(enum target_reset_mode \
                reset_mode);
  */
 int target_alloc_working_area(struct target *target,
 		uint32_t size, struct working_area **area);
+int target_alloc_alt_working_area(struct target *target,
+		uint32_t size, struct working_area **area);
 /* Same as target_alloc_working_area, except that no error is logged
  * when ERROR_TARGET_RESOURCE_NOT_AVAILABLE is returned.
  *
@@ -737,6 +746,8 @@ int target_alloc_working_area(struct target *target,
  */
 int target_alloc_working_area_try(struct target *target,
 		uint32_t size, struct working_area **area);
+int target_alloc_alt_working_area_try(struct target *target,
+		uint32_t size, struct working_area **area);
 /**
  * Free a working area.
  * Restore target data if area backup is configured.
@@ -745,8 +756,10 @@ int target_alloc_working_area_try(struct target *target,
  * @returns ERROR_OK if successful; error code if restore failed
  */
 int target_free_working_area(struct target *target, struct working_area *area);
+int target_free_alt_working_area(struct target *target, struct working_area *area);
 void target_free_all_working_areas(struct target *target);
 uint32_t target_get_working_area_avail(struct target *target);
+uint32_t target_get_alt_working_area_avail(struct target *target);
 
 /**
  * Free all the resources allocated by targets and the target layer

-- 


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic