* GNU General Public License for more details. *
* *
* 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. *
+ * along with this program. If not, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
/* forward declarations */
static int xscale_resume(struct target *, int current,
- uint32_t address, int handle_breakpoints, int debug_execution);
+ target_addr_t address, int handle_breakpoints, int debug_execution);
static int xscale_debug_entry(struct target *);
static int xscale_restore_banked(struct target *);
static int xscale_get_reg(struct reg *reg);
/* 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 "../../contrib/loaders/debug/xscale/debug_handler.inc"
+};
-static char *const xscale_reg_list[] = {
+static const char *const xscale_reg_list[] = {
"XSCALE_MAINID", /* 0 */
"XSCALE_CACHETYPE",
"XSCALE_CTRL",
}
gettimeofday(&now, NULL);
- if ((now.tv_sec > timeout.tv_sec) ||
- ((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec))) {
+ if (timeval_compare(&now, &timeout) > 0) {
LOG_ERROR("time out reading TX register");
return ERROR_TARGET_TIMEOUT;
}
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;
}
}
static int xscale_resume(struct target *target, int current,
- uint32_t address, int handle_breakpoints, int debug_execution)
+ target_addr_t address, int handle_breakpoints, int debug_execution)
{
struct xscale_common *xscale = target_to_xscale(target);
struct arm *arm = &xscale->arm;
enum trace_mode saved_trace_mode;
/* there's a breakpoint at the current PC, we have to step over it */
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
xscale_unset_breakpoint(target, breakpoint);
/* calculate PC of next instruction */
LOG_DEBUG("disable single-step");
xscale_disable_single_step(target);
- LOG_DEBUG("set breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("set breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
xscale_set_breakpoint(target, breakpoint);
}
}
}
static int xscale_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
struct arm *arm = target_to_arm(target);
struct breakpoint *breakpoint = NULL;
{
struct xscale_common *xscale = target_to_xscale(target);
+ /* TODO: apply hw reset signal in not examined state */
+ if (!(target_was_examined(target))) {
+ LOG_WARNING("Reset is not asserted because the target is not examined.");
+ LOG_WARNING("Use a reset button or power cycle the target.");
+ return ERROR_TARGET_NOT_EXAMINED;
+ }
+
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];
address += buf_cnt;
}
- ;
retval = xscale_load_ic(target, 0x0,
xscale->low_vectors);
}
static int xscale_write_core_reg(struct target *target, struct reg *r,
- int num, enum arm_mode mode, uint32_t value)
+ int num, enum arm_mode mode, uint8_t *value)
{
/** \todo add debug handler support for core register writes */
LOG_ERROR("not implemented");
return ERROR_OK;
}
-static int xscale_read_memory(struct target *target, uint32_t address,
+static int xscale_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
uint32_t i;
int retval;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
address,
size,
count);
/* 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_OK;
}
-static int xscale_read_phys_memory(struct target *target, uint32_t address,
+static int xscale_read_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
return ERROR_FAIL;
}
-static int xscale_write_memory(struct target *target, uint32_t address,
+static int xscale_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32,
address,
size,
count);
return ERROR_OK;
}
-static int xscale_write_phys_memory(struct target *target, uint32_t address,
+static int xscale_write_phys_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct xscale_common *xscale = target_to_xscale(target);
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);
struct xscale_common *xscale = target_to_xscale(target);
struct xscale_trace_data *trace_data = xscale->trace.data;
int i, retval;
- uint32_t breakpoint_pc;
+ uint32_t breakpoint_pc = 0;
struct arm_instruction instruction;
uint32_t current_pc = 0;/* initialized when address determined */
}
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)
}
static int xscale_virt2phys(struct target *target,
- uint32_t virtual, uint32_t *physical)
+ target_addr_t virtual, target_addr_t *physical)
{
struct xscale_common *xscale = target_to_xscale(target);
uint32_t cb;
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;
+ }
+ }
+ buf_set_u32(dcsr_reg->value, 0, 32,
+ (buf_get_u32(dcsr_reg->value, 0, 32) & ~DCSR_TRAP_MASK) | 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");
struct target *target = get_current_target(CMD_CTX);
struct xscale_common *xscale = target_to_xscale(target);
struct xscale_trace_data *trace_data;
- struct fileio file;
+ struct fileio *file;
int retval;
retval = xscale_verify_pointer(CMD_CTX, xscale);
while (trace_data) {
int i;
- fileio_write_u32(&file, trace_data->chkpt0);
- fileio_write_u32(&file, trace_data->chkpt1);
- fileio_write_u32(&file, trace_data->last_instruction);
- fileio_write_u32(&file, trace_data->depth);
+ fileio_write_u32(file, trace_data->chkpt0);
+ fileio_write_u32(file, trace_data->chkpt1);
+ fileio_write_u32(file, trace_data->last_instruction);
+ fileio_write_u32(file, trace_data->depth);
for (i = 0; i < trace_data->depth; i++)
- fileio_write_u32(&file, trace_data->entries[i].data |
+ fileio_write_u32(file, trace_data->entries[i].data |
((trace_data->entries[i].type & 0xffff) << 16));
trace_data = trace_data->next;
}
- fileio_close(&file);
+ fileio_close(file);
return ERROR_OK;
}
.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,