* Copyright (C) 2006, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007,2008 Øyvind Harboe *
+ * 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 *
#include "time_support.h"
#include "image.h"
+
+/*
+ * Important XScale documents available as of October 2009 include:
+ *
+ * Intel XScale® Core Developer’s Manual, January 2004
+ * Order Number: 273473-002
+ * This has a chapter detailing debug facilities, and punts some
+ * details to chip-specific microarchitecture documentats.
+ *
+ * Hot-Debug for Intel XScale® Core Debug White Paper, May 2005
+ * Document Number: 273539-005
+ * Less detailed than the developer's manual, but summarizes those
+ * missing details (for most XScales) and gives LOTS of notes about
+ * debugger/handler interaction issues. Presents a simpler reset
+ * and load-handler sequence than the arch doc. (Note, OpenOCD
+ * doesn't currently support "Hot-Debug" as defined there.)
+ *
+ * Chip-specific microarchitecture documents may also be useful.
+ */
+
/* cli handling */
int xscale_register_commands(struct command_context_s *cmd_ctx);
int xscale_assert_reset(target_t *target);
int xscale_deassert_reset(target_t *target);
-int xscale_soft_reset_halt(struct target_s *target);
int xscale_set_reg_u32(reg_t *reg, uint32_t value);
.assert_reset = xscale_assert_reset,
.deassert_reset = xscale_deassert_reset,
- .soft_reset_halt = xscale_soft_reset_halt,
+ .soft_reset_halt = NULL,
.get_gdb_reg_list = armv4_5_get_gdb_reg_list,
.mmu = xscale_mmu
};
-char* xscale_reg_list[] =
+static char *const xscale_reg_list[] =
{
"XSCALE_MAINID", /* 0 */
"XSCALE_CACHETYPE",
"XSCALE_TXRXCTRL",
};
-xscale_reg_t xscale_reg_arch_info[] =
+static const xscale_reg_t xscale_reg_arch_info[] =
{
{XSCALE_MAINID, NULL},
{XSCALE_CACHETYPE, NULL},
{-1, NULL}, /* TXRXCTRL implicit access via JTAG */
};
-int xscale_reg_arch_type = -1;
+static int xscale_reg_arch_type = -1;
int xscale_get_reg(reg_t *reg);
int xscale_set_reg(reg_t *reg, uint8_t *buf);
fields[1].out_value = NULL;
fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
-
fields[2].tap = xscale->jtag_info.tap;
fields[2].num_bits = 1;
fields[2].out_value = &field2;
static void xscale_getbuf(jtag_callback_data_t arg)
{
- uint8_t *in = (uint8_t *)arg;
+ uint8_t *in = (uint8_t *)arg;
*((uint32_t *)in) = buf_get_u32(in, 0, 32);
}
fields[1].out_value = NULL;
fields[1].in_value = xscale->reg_cache->reg_list[XSCALE_TX].value;
-
fields[2].tap = xscale->jtag_info.tap;
fields[2].num_bits = 1;
fields[2].out_value = NULL;
fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_RX].value;
fields[1].in_value = NULL;
-
fields[2].tap = xscale->jtag_info.tap;
fields[2].num_bits = 1;
fields[2].out_value = &field2;
fields[1].out_value = xscale->reg_cache->reg_list[XSCALE_DCSR].value;
fields[1].in_value = NULL;
-
fields[2].tap = xscale->jtag_info.tap;
fields[2].num_bits = 1;
fields[2].out_value = &field2;
fields[0].tap = xscale->jtag_info.tap;
fields[0].num_bits = 6;
fields[0].out_value = &cmd;
-
fields[0].in_value = NULL;
-
-
-
-
fields[1].tap = xscale->jtag_info.tap;
fields[1].num_bits = 27;
fields[1].out_value = packet;
-
fields[1].in_value = NULL;
-
-
-
-
jtag_add_dr_scan(2, fields, jtag_get_end_state());
fields[0].num_bits = 32;
jtag_add_dr_scan(2, fields, jtag_get_end_state());
}
- jtag_execute_queue();
-
- return ERROR_OK;
+ return jtag_execute_queue();
}
int xscale_invalidate_ic_line(target_t *target, uint32_t va)
fields[0].tap = xscale->jtag_info.tap;
fields[0].num_bits = 6;
fields[0].out_value = &cmd;
-
fields[0].in_value = NULL;
-
-
-
-
fields[1].tap = xscale->jtag_info.tap;
fields[1].num_bits = 27;
fields[1].out_value = packet;
-
fields[1].in_value = NULL;
-
-
-
-
jtag_add_dr_scan(2, fields, jtag_get_end_state());
return ERROR_OK;
armv4_5_common_t *armv4_5 = target->arch_info;
xscale_common_t *xscale = armv4_5->arch_info;
- char *state[] =
+ static const char *state[] =
{
"disabled", "enabled"
};
- char *arch_dbg_reason[] =
+ static const char *arch_dbg_reason[] =
{
"", "\n(processor reset)", "\n(trace buffer full)"
};
/* move r0 from buffer to register cache */
buf_set_u32(armv4_5->core_cache->reg_list[0].value, 0, 32, buffer[0]);
- armv4_5->core_cache->reg_list[15].dirty = 1;
- armv4_5->core_cache->reg_list[15].valid = 1;
+ armv4_5->core_cache->reg_list[0].dirty = 1;
+ armv4_5->core_cache->reg_list[0].valid = 1;
LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
/* move pc from buffer to register cache */
xscale->arch_debug_reason = XSCALE_DBG_REASON_TB_FULL;
pc -= 4;
break;
- case 0x7: /* Reserved */
+ case 0x7: /* Reserved (may flag Hot-Debug support) */
default:
LOG_ERROR("Method of Entry is 'Reserved'");
exit(-1);
return ERROR_OK;
}
-int xscale_soft_reset_halt(struct target_s *target)
-{
- return ERROR_OK;
-}
-
int xscale_read_core_reg(struct target_s *target, int num, enum armv4_5_mode mode)
{
return ERROR_OK;
}
+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%" PRIx32, 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%" PRIx32, 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);
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']");