From 8529e7c21e9976425a335693b19494783e1945e0 Mon Sep 17 00:00:00 2001
From: oharboe <oharboe@b42882b7-edfa-0310-969c-e2dbd0fdcd60>
Date: Sun, 24 Feb 2008 21:54:09 +0000
Subject: - added "xscale fast_memory_access" which speeds up memory  access by
 disabling "unecessary" checks. - arm926ejs. Added missing type->mmu and
 type->virt2phys fn's.  for now these are used by working_area when specifying
  mmu enabled and mmu not enabled address

git-svn-id: svn://svn.berlios.de/openocd/trunk@335 b42882b7-edfa-0310-969c-e2dbd0fdcd60
---
 src/target/arm926ejs.c | 45 ++++++++++++++++++++++++++-
 src/target/xscale.c    | 84 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/target/xscale.h    |  2 ++
 3 files changed, 122 insertions(+), 9 deletions(-)

(limited to 'src/target')

diff --git a/src/target/arm926ejs.c b/src/target/arm926ejs.c
index 10061530..75d43fd8 100644
--- a/src/target/arm926ejs.c
+++ b/src/target/arm926ejs.c
@@ -53,6 +53,8 @@ int arm926ejs_arch_state(struct target_s *target);
 int arm926ejs_read_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int arm926ejs_write_memory(struct target_s *target, u32 address, u32 size, u32 count, u8 *buffer);
 int arm926ejs_soft_reset_halt(struct target_s *target);
+static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical);
+static int arm926ejs_mmu(struct target_s *target, int *enabled);
 
 target_type_t arm926ejs_target =
 {
@@ -89,7 +91,9 @@ target_type_t arm926ejs_target =
 	.register_commands = arm926ejs_register_commands,
 	.target_command = arm926ejs_target_command,
 	.init_target = arm926ejs_init_target,
-	.quit = arm926ejs_quit
+	.quit = arm926ejs_quit,
+	.virt2phys = arm926ejs_virt2phys,
+	.mmu = arm926ejs_mmu
 };
 
 
@@ -899,3 +903,42 @@ int arm926ejs_handle_mw_phys_command(command_context_t *cmd_ctx, char *cmd, char
 	
 	return armv4_5_mmu_handle_mw_phys_command(cmd_ctx, cmd, args, argc, target, &arm926ejs->armv4_5_mmu);
 }
+static int arm926ejs_virt2phys(struct target_s *target, u32 virtual, u32 *physical)
+{
+	int retval;
+	int type;
+	u32 cb;
+	int domain;
+	u32 ap;
+	
+	armv4_5_common_t *armv4_5;
+	arm7_9_common_t *arm7_9;
+	arm9tdmi_common_t *arm9tdmi;
+	arm926ejs_common_t *arm926ejs;
+	retval= arm926ejs_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm926ejs);
+	if (retval != ERROR_OK)
+	{
+		return retval;
+	}
+	u32 ret = armv4_5_mmu_translate_va(target, &arm926ejs->armv4_5_mmu, virtual, &type, &cb, &domain, &ap);
+	if (type == -1)
+	{
+		return ret;
+	}
+	*physical = ret;
+	return ERROR_OK;
+}
+
+static int arm926ejs_mmu(struct target_s *target, int *enabled)
+{
+	armv4_5_common_t *armv4_5 = target->arch_info;
+	arm926ejs_common_t *arm926ejs = armv4_5->arch_info;
+	
+	if (target->state != TARGET_HALTED)
+	{
+		ERROR("Target not halted");
+		return ERROR_TARGET_INVALID;
+	}
+	*enabled = arm926ejs->armv4_5_mmu.mmu_enabled;
+	return ERROR_OK;
+}
diff --git a/src/target/xscale.c b/src/target/xscale.c
index 4e111521..bfa0f9f9 100644
--- a/src/target/xscale.c
+++ b/src/target/xscale.c
@@ -631,7 +631,6 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
 
 	scan_field_t fields[3];
 	u8 field0_out = 0x0;
-	u8 field0_in = 0x0;
 	u8 field0_check_value = 0x2;
 	u8 field0_check_mask = 0x6;
 	u8 field2 = 0x1;
@@ -646,8 +645,11 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
 	fields[0].num_bits = 3;
 	fields[0].out_value = &field0_out;
 	fields[0].out_mask = NULL;
-	fields[0].in_value = &field0_in;
-	jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
+	fields[0].in_handler = NULL;
+	if (!xscale->fast_memory_access)
+	{
+		jtag_set_check_value(fields+0, &field0_check_value, &field0_check_mask, NULL);
+	}
 
 	fields[1].device = xscale->jtag_info.chain_pos;
 	fields[1].num_bits = 32;
@@ -666,18 +668,43 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
 	fields[2].out_value = &field2;
 	fields[2].out_mask = NULL;
 	fields[2].in_value = NULL;
-	jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
+	fields[2].in_handler = NULL;
+	if (!xscale->fast_memory_access)
+	{
+		jtag_set_check_value(fields+2, &field2_check_value, &field2_check_mask, NULL);
+	}
 
-	while (done_count++ < count)
+	if (size==4)
 	{
+		int endianness = target->endianness;
+		while (done_count++ < count)
+		{
+			if (endianness == TARGET_LITTLE_ENDIAN)
+			{
+				output[0]=buffer[0];
+				output[1]=buffer[1];
+				output[2]=buffer[2];
+				output[3]=buffer[3];
+			} else
+			{
+				output[0]=buffer[3];
+				output[1]=buffer[2];
+				output[2]=buffer[1];
+				output[3]=buffer[0];
+			}
+			jtag_add_dr_scan(3, fields, TAP_RTI, NULL);
+			buffer += size;
+		}
+		
+	} else
+	{
+		while (done_count++ < count)
+		{
 		/* extract sized element from target-endian buffer, and put it
 		 * into little-endian output buffer
 		 */
 		switch (size)
 		{
-			case 4:
-				buf_set_u32(output, 0, 32, target_buffer_get_u32(target, buffer));
-				break;
 			case 2:
 				buf_set_u32(output, 0, 32, target_buffer_get_u16(target, buffer));
 				break;
@@ -693,6 +720,8 @@ int xscale_send(target_t *target, u8 *buffer, int count, int size)
 		buffer += size;
 	}
 
+	}
+
 	if ((retval = jtag_execute_queue()) != ERROR_OK)
 	{
 		ERROR("JTAG error while sending data to debug handler");
@@ -3101,6 +3130,8 @@ int xscale_init_arch_info(target_t *target, xscale_common_t *xscale, int chain_p
 	xscale->armv4_5_mmu.has_tiny_pages = 1;
 	xscale->armv4_5_mmu.mmu_enabled = 0;
 
+	xscale->fast_memory_access = 0;
+
 	return ERROR_OK;
 }
 
@@ -3700,6 +3731,41 @@ int xscale_handle_cp15(command_context_t *cmd_ctx, char *cmd, char **args, int a
 	return ERROR_OK;
 }
 
+int handle_xscale_fast_memory_access_command(struct command_context_s *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)
+	{
+		return ERROR_OK;
+	}
+	
+	if (argc == 1)
+	{
+		if (strcmp("enable", args[0]) == 0)
+		{
+			xscale->fast_memory_access = 1;
+		}
+		else if (strcmp("disable", args[0]) == 0)
+		{
+			xscale->fast_memory_access = 0;
+		}
+		else
+		{
+			return ERROR_COMMAND_SYNTAX_ERROR;
+		}
+	} else if (argc!=0)
+	{
+		return ERROR_COMMAND_SYNTAX_ERROR;
+	}
+		
+	command_print(cmd_ctx, "fast memory access is %s", (xscale->fast_memory_access) ? "enabled" : "disabled");
+
+	return ERROR_OK;
+}
+
 int xscale_register_commands(struct command_context_s *cmd_ctx)
 {
 	command_t *xscale_cmd;
@@ -3724,6 +3790,8 @@ int xscale_register_commands(struct command_context_s *cmd_ctx)
 		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]");
+	register_command(cmd_ctx, xscale_cmd, "fast_memory_access", handle_xscale_fast_memory_access_command,
+		 COMMAND_ANY, "use fast memory accesses instead of slower but potentially unsafe slow accesses <enable|disable>");
 	
 	armv4_5_register_commands(cmd_ctx);
 
diff --git a/src/target/xscale.h b/src/target/xscale.h
index 8d1c25cc..62285abb 100644
--- a/src/target/xscale.h
+++ b/src/target/xscale.h
@@ -143,6 +143,8 @@ typedef struct xscale_common_s
 	
 	/* possible future enhancements that go beyond XScale common stuff */
 	void *arch_info;
+	
+	int fast_memory_access;
 } xscale_common_t;
 
 typedef struct xscale_reg_s
-- 
cgit v1.2.3