Re: [Openocd-development] PATCH: XScale vector table handling / Linux kernel debugging
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
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
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
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