* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
- * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
/* This XScale "debug handler" is loaded into the processor's
* mini-ICache, which is 2K of code writable only via JTAG.
- *
- * FIXME the OpenOCD "bin2char" utility currently doesn't handle
- * binary files cleanly. It's string oriented, and terminates them
- * with a NUL character. Better would be to generate the constants
- * and let other code decide names, scoping, and other housekeeping.
*/
-static /* unsigned const char xscale_debug_handler[] = ... */
-#include "xscale_debug.h"
+static const uint8_t xscale_debug_handler[] = {
+#include "xscale_debug.inc"
+};
-static char *const xscale_reg_list[] = {
+static const char *const xscale_reg_list[] = {
"XSCALE_MAINID", /* 0 */
"XSCALE_CACHETYPE",
"XSCALE_CTRL",
static int xscale_send(struct target *target, const uint8_t *buffer, int count, int size)
{
struct xscale_common *xscale = target_to_xscale(target);
- uint32_t t[3];
- int bits[3];
int retval;
int done_count = 0;
XSCALE_DBGRX << xscale->xscale_variant,
TAP_IDLE);
- bits[0] = 3;
- t[0] = 0;
- bits[1] = 32;
- t[2] = 1;
- bits[2] = 1;
+ static const uint8_t t0;
+ uint8_t t1[4];
+ static const uint8_t t2 = 1;
+ struct scan_field fields[3] = {
+ { .num_bits = 3, .out_value = &t0 },
+ { .num_bits = 32, .out_value = t1 },
+ { .num_bits = 1, .out_value = &t2 },
+ };
+
int endianness = target->endianness;
while (done_count++ < count) {
+ uint32_t t;
+
switch (size) {
case 4:
if (endianness == TARGET_LITTLE_ENDIAN)
- t[1] = le_to_h_u32(buffer);
+ t = le_to_h_u32(buffer);
else
- t[1] = be_to_h_u32(buffer);
+ t = be_to_h_u32(buffer);
break;
case 2:
if (endianness == TARGET_LITTLE_ENDIAN)
- t[1] = le_to_h_u16(buffer);
+ t = le_to_h_u16(buffer);
else
- t[1] = be_to_h_u16(buffer);
+ t = be_to_h_u16(buffer);
break;
case 1:
- t[1] = buffer[0];
+ t = buffer[0];
break;
default:
LOG_ERROR("BUG: size neither 4, 2 nor 1");
return ERROR_COMMAND_SYNTAX_ERROR;
}
- jtag_add_dr_out(target->tap,
+
+ buf_set_u32(t1, 0, 32, t);
+
+ jtag_add_dr_scan(target->tap,
3,
- bits,
- t,
+ fields,
TAP_IDLE);
buffer += size;
}
LOG_DEBUG("target->state: %s",
target_state_name(target));
+ /* assert reset */
+ jtag_add_reset(0, 1);
+
+ /* sleep 1ms, to be sure we fulfill any requirements */
+ jtag_add_sleep(1000);
+ jtag_execute_queue();
+
/* select DCSR instruction (set endstate to R-T-I to ensure we don't
* end up in T-L-R, which would reset JTAG
*/
xscale_jtag_set_instr(target->tap, ~0, TAP_IDLE);
jtag_execute_queue();
- /* assert reset */
- jtag_add_reset(0, 1);
-
- /* sleep 1ms, to be sure we fulfill any requirements */
- jtag_add_sleep(1000);
- jtag_execute_queue();
-
target->state = TARGET_RESET;
if (target->reset_halt) {
* coprocessors, trace data, etc.
*/
address = xscale->handler_address;
- for (unsigned binary_size = sizeof xscale_debug_handler - 1;
+ for (unsigned binary_size = sizeof xscale_debug_handler;
binary_size > 0;
binary_size -= buf_cnt, buffer += buf_cnt) {
uint32_t cache_line[8];
/* receive data from target (count times 32-bit words in host endianness) */
buf32 = malloc(4 * count);
retval = xscale_receive(target, buf32, count);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK) {
+ free(buf32);
return retval;
+ }
/* extract data from host-endian buffer into byte stream */
for (i = 0; i < count; i++) {
return ERROR_FAIL;
}
-static int xscale_bulk_write_memory(struct target *target, uint32_t address,
- uint32_t count, const uint8_t *buffer)
-{
- return xscale_write_memory(target, address, 4, count, buffer);
-}
-
static int xscale_get_ttb(struct target *target, uint32_t *result)
{
struct xscale_common *xscale = target_to_xscale(target);
}
static int xscale_init_arch_info(struct target *target,
- struct xscale_common *xscale, struct jtag_tap *tap, const char *variant)
+ struct xscale_common *xscale, struct jtag_tap *tap)
{
struct arm *arm;
uint32_t high_reset_branch, low_reset_branch;
/* store architecture specfic data */
xscale->common_magic = XSCALE_COMMON_MAGIC;
- /* we don't really *need* a variant param ... */
- if (variant) {
- int ir_length = 0;
-
- if (strcmp(variant, "pxa250") == 0
- || strcmp(variant, "pxa255") == 0
- || strcmp(variant, "pxa26x") == 0)
- ir_length = 5;
- else if (strcmp(variant, "pxa27x") == 0
- || strcmp(variant, "ixp42x") == 0
- || strcmp(variant, "ixp45x") == 0
- || strcmp(variant, "ixp46x") == 0)
- ir_length = 7;
- else if (strcmp(variant, "pxa3xx") == 0)
- ir_length = 11;
- else
- LOG_WARNING("%s: unrecognized variant %s",
- tap->dotted_name, variant);
-
- if (ir_length && ir_length != tap->ir_length) {
- LOG_WARNING("%s: IR length for %s is %d; fixing",
- tap->dotted_name, variant, ir_length);
- tap->ir_length = ir_length;
- }
- }
-
- /* PXA3xx shifts the JTAG instructions */
+ /* PXA3xx with 11 bit IR shifts the JTAG instructions */
if (tap->ir_length == 11)
xscale->xscale_variant = XSCALE_PXA3XX;
else
/* prepare ARMv4/5 specific information */
arm->arch_info = xscale;
+ arm->core_type = ARM_MODE_ANY;
arm->read_core_reg = xscale_read_core_reg;
arm->write_core_reg = xscale_write_core_reg;
arm->full_context = xscale_full_context;
{
struct xscale_common *xscale;
- if (sizeof xscale_debug_handler - 1 > 0x800) {
+ if (sizeof xscale_debug_handler > 0x800) {
LOG_ERROR("debug_handler.bin: larger than 2kb");
return ERROR_FAIL;
}
if (!xscale)
return ERROR_FAIL;
- return xscale_init_arch_info(target, xscale, target->tap,
- target->variant);
+ return xscale_init_arch_info(target, xscale, target->tap);
}
COMMAND_HANDLER(xscale_handle_debug_handler_command)
return ERROR_OK;
}
+static const struct {
+ char name[15];
+ unsigned mask;
+} vec_ids[] = {
+ { "fiq", DCSR_TF, },
+ { "irq", DCSR_TI, },
+ { "dabt", DCSR_TD, },
+ { "pabt", DCSR_TA, },
+ { "swi", DCSR_TS, },
+ { "undef", DCSR_TU, },
+ { "reset", DCSR_TR, },
+};
+
COMMAND_HANDLER(xscale_handle_vector_catch_command)
{
struct target *target = get_current_target(CMD_CTX);
struct xscale_common *xscale = target_to_xscale(target);
int retval;
+ uint32_t dcsr_value;
+ uint32_t catch = 0;
+ struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR];
retval = xscale_verify_pointer(CMD_CTX, xscale);
if (retval != ERROR_OK)
return retval;
- if (CMD_ARGC < 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
- else {
- COMMAND_PARSE_NUMBER(u8, CMD_ARGV[0], xscale->vector_catch);
- buf_set_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value,
- 16,
- 8,
- xscale->vector_catch);
+ dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32);
+ if (CMD_ARGC > 0) {
+ if (CMD_ARGC == 1) {
+ if (strcmp(CMD_ARGV[0], "all") == 0) {
+ catch = DCSR_TRAP_MASK;
+ CMD_ARGC--;
+ } else if (strcmp(CMD_ARGV[0], "none") == 0) {
+ catch = 0;
+ CMD_ARGC--;
+ }
+ }
+ while (CMD_ARGC-- > 0) {
+ unsigned i;
+ for (i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+ if (strcmp(CMD_ARGV[CMD_ARGC], vec_ids[i].name))
+ continue;
+ catch |= vec_ids[i].mask;
+ break;
+ }
+ if (i == ARRAY_SIZE(vec_ids)) {
+ LOG_ERROR("No vector '%s'", CMD_ARGV[CMD_ARGC]);
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ }
+ *(uint32_t *)(dcsr_reg->value) &= ~DCSR_TRAP_MASK;
+ *(uint32_t *)(dcsr_reg->value) |= catch;
xscale_write_dcsr(target, -1, -1);
}
- command_print(CMD_CTX, "vector catch mask: 0x%2.2x", xscale->vector_catch);
+ dcsr_value = buf_get_u32(dcsr_reg->value, 0, 32);
+ for (unsigned i = 0; i < ARRAY_SIZE(vec_ids); i++) {
+ command_print(CMD_CTX, "%15s: %s", vec_ids[i].name,
+ (dcsr_value & vec_ids[i].mask) ? "catch" : "ignore");
+ }
return ERROR_OK;
}
if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
char fill_string[12];
- sprintf(fill_string, "fill %" PRId32, xscale->trace.buffer_fill);
+ sprintf(fill_string, "fill %d", xscale->trace.buffer_fill);
command_print(CMD_CTX, "trace buffer enabled (%s)",
(xscale->trace.mode == XSCALE_TRACE_FILL)
? fill_string : "wrap");
.name = "vector_catch",
.handler = xscale_handle_vector_catch_command,
.mode = COMMAND_EXEC,
- .help = "set or display 8-bit mask of vectors "
+ .help = "set or display mask of vectors "
"that should trigger debug entry",
- .usage = "[mask]",
+ .usage = "['all'|'none'|'fiq'|'irq'|'dabt'|'pabt'|'swi'|'undef'|'reset']",
},
{
.name = "vector_table",
.poll = xscale_poll,
.arch_state = xscale_arch_state,
- .target_request_data = NULL,
-
.halt = xscale_halt,
.resume = xscale_resume,
.step = xscale_step,
.assert_reset = xscale_assert_reset,
.deassert_reset = xscale_deassert_reset,
- .soft_reset_halt = NULL,
/* REVISIT on some cores, allow exporting iwmmxt registers ... */
.get_gdb_reg_list = arm_get_gdb_reg_list,
.read_phys_memory = xscale_read_phys_memory,
.write_memory = xscale_write_memory,
.write_phys_memory = xscale_write_phys_memory,
- .bulk_write_memory = xscale_bulk_write_memory,
.checksum_memory = arm_checksum_memory,
.blank_check_memory = arm_blank_check_memory,