Re: [Openocd-development] PATCH: XScale vector table handling / Linux kernel debugging

2009-08-25 Thread Øyvind Harboe
Committed.

Thanks!




-- 
Øyvind Harboe
Embedded software and hardware consulting services
http://www.zylin.com
___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


Re: [Openocd-development] PATCH: XScale vector table handling / Linux kernel debugging

2009-08-25 Thread Michael Schwingen
David Brownell wrote:
 That one example shouldn't go *between* the @deffn blocks ...
 it's part of the preceding @deffn, giving the bit semantics,
 not a free-standing chunk of text.
   

I must admit I do know nothing about texinfo.

How about this version?

cu
Michael

Index: src/target/xscale.c
===
--- src/target/xscale.c	(revision 2606)
+++ src/target/xscale.c	(working copy)
@@ -5,6 +5,9 @@
  *   Copyright (C) 2007,2008 Øyvind Harboe *
  *   oyvind.har...@zylin.com   *
  * *
+ *   Copyright (C) 2009 Michael Schwingen  *
+ *   mich...@schwingen.org *
+ * *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or *
@@ -3384,6 +3387,65 @@
 }
 
 
+int xscale_handle_vector_table_command(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;
+	int err = 0;
+
+	if (xscale_get_arch_pointers(target, armv4_5, xscale) != ERROR_OK)
+	{
+		return ERROR_OK;
+	}
+
+	if (argc == 0) /* print current settings */
+	{
+		int idx;
+
+		command_print(cmd_ctx, active user-set static vectors:);
+		for (idx = 1; idx  8; idx++)
+			if (xscale-static_low_vectors_set  (1  idx))
+command_print(cmd_ctx, low  %d: 0x%x, idx, xscale-static_low_vectors[idx]);
+		for (idx = 1; idx  8; idx++)
+			if (xscale-static_high_vectors_set  (1  idx))
+command_print(cmd_ctx, high %d: 0x%x, idx, xscale-static_high_vectors[idx]);
+		return ERROR_OK;
+	}
+
+	if (argc != 3)
+		err = 1;
+	else
+	{
+		int idx;
+		uint32_t vec;
+		idx = strtoul(args[1], NULL, 0);
+		vec = strtoul(args[2], NULL, 0);
+
+		if (idx  1 || idx = 8)
+			err = 1;
+
+		if (!err  strcmp(args[0], low) == 0)
+		{
+			xscale-static_low_vectors_set |= (1idx);
+			xscale-static_low_vectors[idx] = vec;
+		}
+		else if (!err  (strcmp(args[0], high) == 0))
+		{
+			xscale-static_high_vectors_set |= (1idx);
+			xscale-static_high_vectors[idx] = vec;
+		}
+		else
+			err = 1;
+	}
+
+	if (err)
+		command_print(cmd_ctx, usage: xscale vector_table high|low index code);
+
+	return ERROR_OK;
+}
+
+
 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
 	target_t *target = get_current_target(cmd_ctx);
@@ -3692,6 +3754,7 @@
 	register_command(cmd_ctx, xscale_cmd, dcache, xscale_handle_idcache_command, COMMAND_EXEC, ['enable'|'disable'] the DCache);
 
 	register_command(cmd_ctx, xscale_cmd, vector_catch, xscale_handle_vector_catch_command, COMMAND_EXEC, mask of vectors that should be catched);
+	register_command(cmd_ctx, xscale_cmd, vector_table, xscale_handle_vector_table_command, COMMAND_EXEC, high|low index code set static code for exception handler entry);
 
 	register_command(cmd_ctx, xscale_cmd, trace_buffer, xscale_handle_trace_buffer_command, COMMAND_EXEC, enable | disable ['fill' [n]|'wrap']);
 
Index: doc/openocd.texi
===
--- doc/openocd.texi	(revision 2606)
+++ doc/openocd.texi	(working copy)
@@ -4877,6 +4877,52 @@
 @subsection XScale specific commands
 @cindex XScale
 
+Some notes about the debug implementation on the XScale CPUs:
+
+The XScale CPU provides a special debug-only mini-instruction cache
+(mini-IC) in which exception vectors and target-resident debug handler
+code are placed by OpenOCD. In order to get access to the CPU, OpenOCD
+must point vector 0 (the reset vector) to the entry of the debug
+handler. However, this means that the complete first cacheline in the
+mini-IC is marked valid, which makes the CPU fetch all exception
+handlers from the mini-IC, ignoring the code in RAM.
+
+OpenOCD currently does not sync the mini-IC entries with the RAM
+contents (which would fail anyway while the target is running), so
+the user must provide appropriate values using the @code{xscale
+vector_table} command.
+
+It is recommended to place a pc-relative indirect branch in the vector
+table, and put the branch destination somewhere in memory. Doing so
+makes sure the code in the vector table stays constant regardless of
+code layout in memory:
+...@example
+_vectors:
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+ldr pc,[pc,#0x100-8]
+.org 0x100
+.long real_reset_vector
+.long 

Re: [Openocd-development] PATCH: XScale vector table handling / Linux kernel debugging

2009-08-25 Thread David Brownell
On Tuesday 25 August 2009, Michael Schwingen wrote:
  That one example shouldn't go *between* the @deffn blocks ...
  it's part of the preceding @deffn, giving the bit semantics,
  not a free-standing chunk of text.
    
 
 I must admit I do know nothing about texinfo.
 
 How about this version?

OK; thanks!

___
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development


[Openocd-development] PATCH: XScale vector table handling / Linux kernel debugging

2009-08-24 Thread Michael Schwingen
Hi,

it seems the XScale vector table handling code in OpenOCD is only partially
implemented: the code to use user-provided vectors is there, but there is no
way to set these variables, and also no code that syncs the cached vectors
with the RAM contents.

The attached patch adds a xscale vector_table command that allows to set
the values that are written in the mini-IC (plus documentation updates that
describe why this is needed).

Using the correct values, I can now start and debug a Linux kernel on my
IXP425 board from openocd - this would before crash after uncompressing
kernel, because the cached exception vectors were completely off.

This is only tested on big-endian IXP42x, but even if it does not work on
other CPUs, it should not break any existing functionality.

cu
Michael
Index: src/target/xscale.c
===
--- src/target/xscale.c	(revision 2606)
+++ src/target/xscale.c	(working copy)
@@ -5,6 +5,9 @@
  *   Copyright (C) 2007,2008 Øyvind Harboe *
  *   oyvind.har...@zylin.com   *
  * *
+ *   Copyright (C) 2009 Michael Schwingen  *
+ *   mich...@schwingen.org *
+ * *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
  *   the Free Software Foundation; either version 2 of the License, or *
@@ -3384,6 +3387,65 @@
 }
 
 
+int xscale_handle_vector_table_command(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;
+	int err = 0;
+
+	if (xscale_get_arch_pointers(target, armv4_5, xscale) != ERROR_OK)
+	{
+		return ERROR_OK;
+	}
+
+	if (argc == 0) /* print current settings */
+	{
+		int idx;
+
+		command_print(cmd_ctx, active user-set static vectors:);
+		for (idx = 1; idx  8; idx++)
+			if (xscale-static_low_vectors_set  (1  idx))
+command_print(cmd_ctx, low  %d: 0x%x, idx, xscale-static_low_vectors[idx]);
+		for (idx = 1; idx  8; idx++)
+			if (xscale-static_high_vectors_set  (1  idx))
+command_print(cmd_ctx, high %d: 0x%x, idx, xscale-static_high_vectors[idx]);
+		return ERROR_OK;
+	}
+
+	if (argc != 3)
+		err = 1;
+	else
+	{
+		int idx;
+		uint32_t vec;
+		idx = strtoul(args[1], NULL, 0);
+		vec = strtoul(args[2], NULL, 0);
+
+		if (idx  1 || idx = 8)
+			err = 1;
+
+		if (!err  strcmp(args[0], low) == 0)
+		{
+			xscale-static_low_vectors_set |= (1idx);
+			xscale-static_low_vectors[idx] = vec;
+		}
+		else if (!err  (strcmp(args[0], high) == 0))
+		{
+			xscale-static_high_vectors_set |= (1idx);
+			xscale-static_high_vectors[idx] = vec;
+		}
+		else
+			err = 1;
+	}
+
+	if (err)
+		command_print(cmd_ctx, usage: xscale vector_table high|low index code);
+
+	return ERROR_OK;
+}
+
+
 int xscale_handle_trace_buffer_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
 {
 	target_t *target = get_current_target(cmd_ctx);
@@ -3692,6 +3754,7 @@
 	register_command(cmd_ctx, xscale_cmd, dcache, xscale_handle_idcache_command, COMMAND_EXEC, ['enable'|'disable'] the DCache);
 
 	register_command(cmd_ctx, xscale_cmd, vector_catch, xscale_handle_vector_catch_command, COMMAND_EXEC, mask of vectors that should be catched);
+	register_command(cmd_ctx, xscale_cmd, vector_table, xscale_handle_vector_table_command, COMMAND_EXEC, high|low index code set static code for exception handler entry);
 
 	register_command(cmd_ctx, xscale_cmd, trace_buffer, xscale_handle_trace_buffer_command, COMMAND_EXEC, enable | disable ['fill' [n]|'wrap']);
 
Index: doc/openocd.texi
===
--- doc/openocd.texi	(revision 2606)
+++ doc/openocd.texi	(working copy)
@@ -4877,6 +4877,52 @@
 @subsection XScale specific commands
 @cindex XScale
 
+Some notes about the debug implementation on the XScale CPUs:
+
+The XScale CPU provides a special debug-only mini-instruction cache
+(mini-IC) in which exception vectors and target-resident debug handler
+code are placed by OpenOCD. In order to get access to the CPU, OpenOCD
+must point vector 0 (the reset vector) to the entry of the debug
+handler. However, this means that the complete first cacheline in the
+mini-IC is marked valid, which makes the CPU fetch all exception
+handlers from the mini-IC, ignoring the code in RAM.
+
+OpenOCD currently does not sync the mini-IC entries with the RAM
+contents (which would fail anyway while the target is running), so
+the user must provide appropriate values using the @code{xscale
+vector_table} command.
+
+It is recommended to place a pc-relative indirect branch in the vector
+table, and put