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:
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
|
||||
@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
|
||||
|
||||
|
|
|
@ -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']");
|
||||
|
||||
|
|
Loading…
Reference in New Issue