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__archive__
parent
ae4c224459
commit
fd4c0f33b1
|
@ -4877,6 +4877,52 @@ else if a @var{value} is provided, that value is written to that register.
|
||||||
@subsection XScale specific commands
|
@subsection XScale specific commands
|
||||||
@cindex XScale
|
@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,
|
These commands are available to XScale based CPUs,
|
||||||
which are implementations of the ARMv5TE architecture.
|
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.
|
If the optional parameter is provided, first set the bitmask to that value.
|
||||||
@end deffn
|
@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
|
@section ARMv6 Architecture
|
||||||
@cindex ARMv6
|
@cindex ARMv6
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
* Copyright (C) 2007,2008 Øyvind Harboe *
|
* Copyright (C) 2007,2008 Øyvind Harboe *
|
||||||
* oyvind.harboe@zylin.com *
|
* oyvind.harboe@zylin.com *
|
||||||
* *
|
* *
|
||||||
|
* Copyright (C) 2009 Michael Schwingen *
|
||||||
|
* michael@schwingen.org *
|
||||||
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* 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)
|
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);
|
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, "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_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']");
|
register_command(cmd_ctx, xscale_cmd, "trace_buffer", xscale_handle_trace_buffer_command, COMMAND_EXEC, "<enable | disable> ['fill' [n]|'wrap']");
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue