Michael Schwingen <rincewind@discworld.dascon.de> 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
This commit is contained in:
oharboe 2009-08-25 07:09:48 +00:00
parent ae4c224459
commit fd4c0f33b1
2 changed files with 136 additions and 0 deletions

View File

@ -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} [<low|high> <index> <value>]
@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

View File

@ -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<<idx);
xscale->static_low_vectors[idx] = vec;
}
else if (!err && (strcmp(args[0], "high") == 0))
{
xscale->static_high_vectors_set |= (1<<idx);
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 @@ 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, "<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']");