From dafa5aacbe96629a57d63795ab9acdd618f45306 Mon Sep 17 00:00:00 2001
From: mifi <mifi@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Wed, 6 Feb 2008 19:59:55 +0000
Subject: [PATCH] - added patch to access cp15 register (XScale) (thanks to
 Edgar Grimberg for the patch)

git-svn-id: svn://svn.berlios.de/openocd/trunk@283 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/target/xscale.c | 92 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/src/target/xscale.c b/src/target/xscale.c
index 37f9b641e..ec49a8c6b 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -3579,6 +3579,96 @@ int xscale_handle_analyze_trace_buffer_command(struct command_context_s *cmd_ctx
 	return ERROR_OK;
 }
 
+int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int argc)
+{
+	target_t *target = get_current_target(cmd_ctx);
+	armv4_5_common_t *armv4_5;
+	xscale_common_t *xscale;
+	
+	if (xscale_get_arch_pointers(target, &armv4_5, &xscale) != ERROR_OK)
+	{
+		command_print(cmd_ctx, "target isn't an XScale target");
+		return ERROR_OK;
+	}
+	
+	if (target->state != TARGET_HALTED)
+	{
+		command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd);
+		return ERROR_OK;
+	}
+	u32 reg_no = 0;
+	reg_t *reg = NULL;
+	if(argc > 0)
+	{
+		reg_no = strtoul(args[0], NULL, 0);
+		/*translate from xscale cp15 register no to openocd register*/
+		switch(reg_no)
+		{
+		case 0:
+			reg_no = XSCALE_MAINID;
+			break;
+		case 1:
+			reg_no = XSCALE_CTRL;
+			break;
+		case 2:
+			reg_no = XSCALE_TTB;
+			break; 
+		case 3:
+			reg_no = XSCALE_DAC;
+			break;
+		case 5:
+			reg_no = XSCALE_FSR;
+			break;
+		case 6:
+			reg_no = XSCALE_FAR;
+			break;
+		case 13:
+			reg_no = XSCALE_PID;
+			break;
+		case 15:
+			reg_no = XSCALE_CPACCESS;
+			break;
+		default:
+			command_print(cmd_ctx, "invalid register number");
+			return ERROR_INVALID_ARGUMENTS;
+		}
+		reg = &xscale->reg_cache->reg_list[reg_no];
+		
+	}
+	if(argc == 1)
+	{
+		u32 value;
+		
+		/* read cp15 control register */
+		xscale_get_reg(reg);
+		value = buf_get_u32(reg->value, 0, 32);
+		command_print(cmd_ctx, "%s (/%i): 0x%x", reg->name, reg->size, value);
+	}
+	else if(argc == 2)
+	{   
+
+		u32 value = strtoul(args[1], NULL, 0);
+		
+		/* send CP write request (command 0x41) */
+		xscale_send_u32(target, 0x41);
+		
+		/* send CP register number */
+		xscale_send_u32(target, reg_no);
+		
+		/* send CP register value */
+		xscale_send_u32(target, value);
+		
+		/* execute cpwait to ensure outstanding operations complete */
+		xscale_send_u32(target, 0x53);
+	}
+	else
+	{
+		command_print(cmd_ctx, "usage: cp15 [register]<, [value]>");	
+	}
+	
+	return ERROR_OK;
+}
+
 int xscale_register_commands(struct command_context_s *cmd_ctx)
 {
 	command_t *xscale_cmd;
@@ -3603,6 +3693,8 @@ int xscale_register_commands(struct command_context_s *cmd_ctx)
 	register_command(cmd_ctx, xscale_cmd, "trace_image", xscale_handle_trace_image_command,
 		COMMAND_EXEC, "load image from <file> [base address]");
 
+	register_command(cmd_ctx, xscale_cmd, "cp15", xscale_handle_cp15, COMMAND_EXEC, "access coproc 15 <register> [value]");
+	
 	armv4_5_register_commands(cmd_ctx);
 
 	return ERROR_OK;
-- 
GitLab