From b404b9ab57f17d84eb8dbfb42e6ac49c32913eee Mon Sep 17 00:00:00 2001
From: David Brownell <dbrownell@users.sourceforge.net>
Date: Sun, 22 Nov 2009 10:21:48 -0800
Subject: ARM: use arm_reg_current()

Start using the arm_reg_current() call.  This shrinks and speeds
the affected code.  It can also prevent some coredumps coming from
invalid CPSR values ... the ARMV4_5_CORE_REG_MODE() macro returns
bogus registers if e.g. "Secure Monitor" mode isn't supported by
the current CPU.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
---
 src/target/arm7_9_common.c | 45 ++++++++++++++++++-------------
 src/target/arm920t.c       | 66 ++++++++++++++++++++++++++++------------------
 src/target/cortex_a8.c     | 24 ++++++-----------
 3 files changed, 74 insertions(+), 61 deletions(-)

(limited to 'src')

diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c
index a58bd3bd..4c5e286c 100644
--- a/src/target/arm7_9_common.c
+++ b/src/target/arm7_9_common.c
@@ -1245,9 +1245,11 @@ int arm7_9_soft_reset_halt(struct target *target)
 	/* reset registers */
 	for (i = 0; i <= 14; i++)
 	{
-		buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, 0xffffffff);
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 1;
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
+		struct reg *r = arm_reg_current(armv4_5, i);
+
+		buf_set_u32(r->value, 0, 32, 0xffffffff);
+		r->dirty = 1;
+		r->valid = 1;
 	}
 
 	if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK)
@@ -1443,32 +1445,31 @@ static int arm7_9_debug_entry(struct target *target)
 
 	for (i = 0; i <= 15; i++)
 	{
+		struct reg *r = arm_reg_current(armv4_5, i);
+
 		LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, context[i]);
-		buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).value, 0, 32, context[i]);
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = 0;
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid = 1;
+
+		buf_set_u32(r->value, 0, 32, context[i]);
+		/* r0 and r15 (pc) have to be restored later */
+		r->dirty = (i == 0) || (i == 15);
+		r->valid = 1;
 	}
 
 	LOG_DEBUG("entered debug state at PC 0x%" PRIx32 "", context[15]);
 
 	/* exceptions other than USR & SYS have a saved program status register */
-	if ((armv4_5->core_mode != ARMV4_5_MODE_USR) && (armv4_5->core_mode != ARMV4_5_MODE_SYS))
-	{
+	if (armv4_5->spsr) {
 		uint32_t spsr;
 		arm7_9->read_xpsr(target, &spsr, 1);
 		if ((retval = jtag_execute_queue()) != ERROR_OK)
 		{
 			return retval;
 		}
-		buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).value, 0, 32, spsr);
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).dirty = 0;
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 16).valid = 1;
+		buf_set_u32(armv4_5->spsr->value, 0, 32, spsr);
+		armv4_5->spsr->dirty = 0;
+		armv4_5->spsr->valid = 1;
 	}
 
-	/* r0 and r15 (pc) have to be restored later */
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15).valid;
-
 	if ((retval = jtag_execute_queue()) != ERROR_OK)
 		return retval;
 
@@ -2377,8 +2378,11 @@ int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, u
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	for (i = 0; i <= last_reg; i++)
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
+	for (i = 0; i <= last_reg; i++) {
+		struct reg *r = arm_reg_current(armv4_5, i);
+
+		r->dirty = r->valid;
+	}
 
 	arm7_9->read_xpsr(target, &cpsr, 0);
 	if ((retval = jtag_execute_queue()) != ERROR_OK)
@@ -2562,8 +2566,11 @@ int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size,
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	for (i = 0; i <= last_reg; i++)
-		ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, i).valid;
+	for (i = 0; i <= last_reg; i++) {
+		struct reg *r = arm_reg_current(armv4_5, i);
+
+		r->dirty = r->valid;
+	}
 
 	arm7_9->read_xpsr(target, &cpsr, 0);
 	if ((retval = jtag_execute_queue()) != ERROR_OK)
diff --git a/src/target/arm920t.c b/src/target/arm920t.c
index a1fb7f31..0610c93c 100644
--- a/src/target/arm920t.c
+++ b/src/target/arm920t.c
@@ -216,6 +216,7 @@ static int arm920t_read_cp15_interpreted(struct target *target,
 	uint32_t* regs_p[1];
 	uint32_t regs[2];
 	uint32_t cp15c15 = 0x0;
+	struct reg *r = armv4_5->core_cache->reg_list;
 
 	/* load address into R1 */
 	regs[1] = address;
@@ -247,8 +248,8 @@ static int arm920t_read_cp15_interpreted(struct target *target,
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
+	r[0].dirty = 1;
+	r[1].dirty = 1;
 
 	return ERROR_OK;
 }
@@ -260,6 +261,7 @@ int arm920t_write_cp15_interpreted(struct target *target,
 	uint32_t cp15c15 = 0x0;
 	struct arm *armv4_5 = target_to_armv4_5(target);
 	uint32_t regs[2];
+	struct reg *r = armv4_5->core_cache->reg_list;
 
 	/* load value, address into R0, R1 */
 	regs[0] = value;
@@ -287,8 +289,8 @@ int arm920t_write_cp15_interpreted(struct target *target,
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = 1;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = 1;
+	r[0].dirty = 1;
+	r[1].dirty = 1;
 
 	return ERROR_OK;
 }
@@ -678,6 +680,7 @@ COMMAND_HANDLER(arm920t_handle_read_cache_command)
 	FILE *output;
 	struct arm920t_cache_line d_cache[8][64], i_cache[8][64];
 	int segment, index;
+	struct reg *r;
 
 	retval = arm920t_verify_pointer(CMD_CTX, arm920t);
 	if (retval != ERROR_OK)
@@ -893,17 +896,22 @@ COMMAND_HANDLER(arm920t_handle_read_cache_command)
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	/* mark registers dirty. */
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
+	/* force writeback of the valid data */
+	r = armv4_5->core_cache->reg_list;
+	r[0].dirty = r[0].valid;
+	r[1].dirty = r[1].valid;
+	r[2].dirty = r[2].valid;
+	r[3].dirty = r[3].valid;
+	r[4].dirty = r[4].valid;
+	r[5].dirty = r[5].valid;
+	r[6].dirty = r[6].valid;
+	r[7].dirty = r[7].valid;
+
+	r = arm_reg_current(armv4_5, 8);
+	r->dirty = r->valid;
+
+	r = arm_reg_current(armv4_5, 9);
+	r->dirty = r->valid;
 
 	return ERROR_OK;
 }
@@ -924,6 +932,7 @@ COMMAND_HANDLER(arm920t_handle_read_mmu_command)
 	uint32_t Dlockdown, Ilockdown;
 	struct arm920t_tlb_entry d_tlb[64], i_tlb[64];
 	int victim;
+	struct reg *r;
 
 	retval = arm920t_verify_pointer(CMD_CTX, arm920t);
 	if (retval != ERROR_OK)
@@ -1176,17 +1185,22 @@ COMMAND_HANDLER(arm920t_handle_read_mmu_command)
 	if (!is_arm_mode(armv4_5->core_mode))
 		return ERROR_FAIL;
 
-	/* mark registers dirty */
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 1).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 2).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 3).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 4).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 5).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 6).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 7).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 8).valid;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 9).valid;
+	/* force writeback of the valid data */
+	r = armv4_5->core_cache->reg_list;
+	r[0].dirty = r[0].valid;
+	r[1].dirty = r[1].valid;
+	r[2].dirty = r[2].valid;
+	r[3].dirty = r[3].valid;
+	r[4].dirty = r[4].valid;
+	r[5].dirty = r[5].valid;
+	r[6].dirty = r[6].valid;
+	r[7].dirty = r[7].valid;
+
+	r = arm_reg_current(armv4_5, 8);
+	r->dirty = r->valid;
+
+	r = arm_reg_current(armv4_5, 9);
+	r->dirty = r->valid;
 
 	return ERROR_OK;
 }
diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c
index de579feb..b006e81a 100644
--- a/src/target/cortex_a8.c
+++ b/src/target/cortex_a8.c
@@ -496,8 +496,7 @@ static int cortex_a8_resume(struct target *target, int current,
 
 	/* current = 1: continue on current pc, otherwise continue at <address> */
 	resume_pc = buf_get_u32(
-			ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-				armv4_5->core_mode, 15).value,
+			armv4_5->core_cache->reg_list[15].value,
 			0, 32);
 	if (!current)
 		resume_pc = address;
@@ -522,13 +521,10 @@ static int cortex_a8_resume(struct target *target, int current,
 		return ERROR_FAIL;
 	}
 	LOG_DEBUG("resume pc = 0x%08" PRIx32, resume_pc);
-	buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-				armv4_5->core_mode, 15).value,
+	buf_set_u32(armv4_5->core_cache->reg_list[15].value,
 			0, 32, resume_pc);
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-			armv4_5->core_mode, 15).dirty = 1;
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-			armv4_5->core_mode, 15).valid = 1;
+	armv4_5->core_cache->reg_list[15].dirty = 1;
+	armv4_5->core_cache->reg_list[15].valid = 1;
 
 	cortex_a8_restore_context(target);
 
@@ -653,8 +649,7 @@ static int cortex_a8_debug_entry(struct target *target)
 	/* update cache */
 	for (i = 0; i <= ARM_PC; i++)
 	{
-		reg = &ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-					armv4_5->core_mode, i);
+		reg = arm_reg_current(armv4_5, i);
 
 		buf_set_u32(reg->value, 0, 32, regfile[i]);
 		reg->valid = 1;
@@ -672,13 +667,10 @@ static int cortex_a8_debug_entry(struct target *target)
 		// ARM state
 		regfile[ARM_PC] -= 8;
 	}
-	buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-				armv4_5->core_mode, ARM_PC).value,
-			0, 32, regfile[ARM_PC]);
 
-	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 0)
-		.dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
-				armv4_5->core_mode, 0).valid;
+	reg = armv4_5->core_cache->reg_list + 15;
+	buf_set_u32(reg->value, 0, 32, regfile[ARM_PC]);
+	reg->dirty = reg->valid;
 	ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5->core_mode, 15)
 		.dirty = ARMV4_5_CORE_REG_MODE(armv4_5->core_cache,
 				armv4_5->core_mode, 15).valid;
-- 
cgit v1.2.3