From fd4c0f33b119a9242b05c9141237a5fb744ec985 Mon Sep 17 00:00:00 2001 From: oharboe Date: Tue, 25 Aug 2009 07:09:48 +0000 Subject: [PATCH] Michael Schwingen 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). git-svn-id: svn://svn.berlios.de/openocd/trunk@2613 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- doc/openocd.texi | 73 +++++++++++++++++++++++++++++++++++++++++++++ src/target/xscale.c | 63 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) diff --git a/doc/openocd.texi b/doc/openocd.texi index ec4bf8c29..157606e65 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4877,6 +4877,52 @@ else if a @var{value} is provided, that value is written to that register. @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 real_ui_handler + .long real_swi_handler + .long real_pf_abort + .long real_data_abort + .long 0 /* unused */ + .long real_irq_handler + .long real_fiq_handler +@end example + +The debug handler must be placed somewhere in the address space using +the @code{xscale debug_handler} command. The allowed locations for the +debug handler are either (0x800 - 0x1fef800) or (0xfe000800 - +0xfffff800). The default value is 0xfe000800. + + These commands are available to XScale based CPUs, which are implementations of the ARMv5TE architecture. @@ -4938,6 +4984,33 @@ Display a bitmask showing the hardware vectors to catch. If the optional parameter is provided, first set the bitmask to that value. @end deffn +The mask bits correspond with bit 16..23 in the DCSR: +@example +0x01 Trap Reset +0x02 Trap Undefined Instructions +0x04 Trap Software Interrupt +0x08 Trap Prefetch Abort +0x10 Trap Data Abort +0x20 reserved +0x40 Trap IRQ +0x80 Trap FIQ +@end example + + +@anchor{xscale vector_table} +@deffn Command {xscale vector_table} [ ] +@cindex vector_table + +Set an entry in the mini-IC vector table. There are two tables: one for +low vectors (at 0x00000000), and one for high vectors (0xFFFF0000), each +holding the 8 exception vectors. @var{index} can be 1-7, because vector 0 +points to the debug handler entry and can not be overwritten. +@var{value} holds the 32-bit opcode that is placed in the mini-IC. + +Without arguments, the current settings are displayed. + +@end deffn + @section ARMv6 Architecture @cindex ARMv6 diff --git a/src/target/xscale.c b/src/target/xscale.c index 71edee2e3..cc90eb319 100644 --- a/src/target/xscale.c +++ b/src/target/xscale.c @@ -5,6 +5,9 @@ * Copyright (C) 2007,2008 Øyvind Harboe * * oyvind.harboe@zylin.com * * * + * Copyright (C) 2009 Michael Schwingen * + * michael@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_catch_command(command_context_t *cmd_ctx, char *cmd, ch } +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 |= (1<static_low_vectors[idx] = vec; + } + else if (!err && (strcmp(args[0], "high") == 0)) + { + xscale->static_high_vectors_set |= (1<static_high_vectors[idx] = vec; + } + else + err = 1; + } + + if (err) + command_print(cmd_ctx, "usage: xscale vector_table "); + + 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 @@ int xscale_register_commands(struct command_context_s *cmd_ctx) 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, " of vectors that should be catched"); + register_command(cmd_ctx, xscale_cmd, "vector_table", xscale_handle_vector_table_command, COMMAND_EXEC, " set static code for exception handler entry"); register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, " ['fill' [n]|'wrap']");