+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2006, 2007 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
* 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 *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * 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., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
***************************************************************************/
#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",
/* convenience wrapper to access XScale specific registers */
static int xscale_set_reg_u32(struct reg *reg, uint32_t value)
{
- uint8_t buf[4];
+ uint8_t buf[4] = { 0 };
buf_set_u32(buf, 0, 32, value);
static const char xscale_not[] = "target is not an XScale";
-static int xscale_verify_pointer(struct command_context *cmd_ctx,
+static int xscale_verify_pointer(struct command_invocation *cmd,
struct xscale_common *xscale)
{
if (xscale->common_magic != XSCALE_COMMON_MAGIC) {
- command_print(cmd_ctx, xscale_not);
+ command_print(cmd, xscale_not);
return ERROR_TARGET_INVALID;
}
return ERROR_OK;
static int xscale_jtag_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
{
- assert(tap != NULL);
+ assert(tap);
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
struct scan_field field;
- uint8_t scratch[4];
+ uint8_t scratch[4] = { 0 };
- memset(&field, 0, sizeof field);
+ memset(&field, 0, sizeof(field));
field.num_bits = tap->ir_length;
field.out_value = scratch;
buf_set_u32(scratch, 0, field.num_bits, new_instr);
buf_set_u32(&field0, 1, 1, xscale->hold_rst);
buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 3;
fields[0].out_value = &field0;
return retval;
}
- xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
- xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
+ xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;
+ xscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;
/* write the register with the value we just read
* on this second pass, only the first bit of field0 is guaranteed to be 0)
path[1] = TAP_DRCAPTURE;
path[2] = TAP_DRSHIFT;
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 3;
uint8_t tmp;
noconsume_path[4] = TAP_DREXIT2;
noconsume_path[5] = TAP_DRSHIFT;
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 3;
fields[0].in_value = &field0_in;
}
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;
}
XSCALE_DBGRX << xscale->xscale_variant,
TAP_IDLE);
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 3;
fields[0].out_value = &field0_out;
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] = { 0 };
+ 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;
}
buf_set_u32(&field0, 1, 1, xscale->hold_rst);
buf_set_u32(&field0, 2, 1, xscale->external_debug_break);
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 3;
fields[0].out_value = &field0;
return retval;
}
- xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = 0;
- xscale->reg_cache->reg_list[XSCALE_DCSR].valid = 1;
+ xscale->reg_cache->reg_list[XSCALE_DCSR].dirty = false;
+ xscale->reg_cache->reg_list[XSCALE_DCSR].valid = true;
return ERROR_OK;
}
static int xscale_load_ic(struct target *target, uint32_t va, uint32_t buffer[8])
{
struct xscale_common *xscale = target_to_xscale(target);
- uint8_t packet[4];
- uint8_t cmd;
+ uint8_t packet[4] = { 0 };
+ uint8_t cmd = 0;
int word;
struct scan_field fields[2];
/* virtual address of desired cache line */
buf_set_u32(packet, 0, 27, va >> 5);
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 6;
fields[0].out_value = &cmd;
static int xscale_invalidate_ic_line(struct target *target, uint32_t va)
{
struct xscale_common *xscale = target_to_xscale(target);
- uint8_t packet[4];
- uint8_t cmd;
+ uint8_t packet[4] = { 0 };
+ uint8_t cmd = 0;
struct scan_field fields[2];
xscale_jtag_set_instr(target->tap,
/* virtual address of desired cache line */
buf_set_u32(packet, 0, 27, va >> 5);
- memset(&fields, 0, sizeof fields);
+ memset(&fields, 0, sizeof(fields));
fields[0].num_bits = 6;
fields[0].out_value = &cmd;
retval = xscale_debug_entry(target);
} else if (retval != ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
LOG_USER("error while polling TX register, reset CPU");
- /* here we "lie" so GDB won't get stuck and a reset can be perfomed */
+ /* here we "lie" so GDB won't get stuck and a reset can be performed */
target->state = TARGET_HALTED;
}
/* move r0 from buffer to register cache */
buf_set_u32(arm->core_cache->reg_list[0].value, 0, 32, buffer[0]);
- arm->core_cache->reg_list[0].dirty = 1;
- arm->core_cache->reg_list[0].valid = 1;
+ arm->core_cache->reg_list[0].dirty = true;
+ arm->core_cache->reg_list[0].valid = true;
LOG_DEBUG("r0: 0x%8.8" PRIx32 "", buffer[0]);
/* move pc from buffer to register cache */
buf_set_u32(arm->pc->value, 0, 32, buffer[1]);
- arm->pc->dirty = 1;
- arm->pc->valid = 1;
+ arm->pc->dirty = true;
+ arm->pc->valid = true;
LOG_DEBUG("pc: 0x%8.8" PRIx32 "", buffer[1]);
/* move data from buffer to register cache */
for (i = 1; i <= 7; i++) {
buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, buffer[1 + i]);
- arm->core_cache->reg_list[i].dirty = 1;
- arm->core_cache->reg_list[i].valid = 1;
+ arm->core_cache->reg_list[i].dirty = true;
+ arm->core_cache->reg_list[i].valid = true;
LOG_DEBUG("r%i: 0x%8.8" PRIx32 "", i, buffer[i + 1]);
}
/* mark xscale regs invalid to ensure they are retrieved from the
* debug handler if requested */
for (i = 0; i < xscale->reg_cache->num_regs; i++)
- xscale->reg_cache->reg_list[i].valid = 0;
+ xscale->reg_cache->reg_list[i].valid = false;
/* examine debug reason */
xscale_read_dcsr(target);
xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
pc -= 4;
break;
- case 0x5: /* Vector trap occured */
+ case 0x5: /* Vector trap occurred */
target->debug_reason = DBG_REASON_BREAKPOINT;
xscale->arch_debug_reason = XSCALE_DBG_REASON_GENERIC;
pc -= 4;
struct watchpoint *watchpoint = target->watchpoints;
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
xscale_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
/* set any pending breakpoints */
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
xscale_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
struct xscale_trace_data *td = xscale->trace.data;
while (td) {
struct xscale_trace_data *next_td = td->next;
- if (td->entries)
- free(td->entries);
+ free(td->entries);
free(td);
td = next_td;
}
}
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;
struct breakpoint *breakpoint;
breakpoint = breakpoint_find(target,
buf_get_u32(arm->pc->value, 0, 32));
- if (breakpoint != NULL) {
+ if (breakpoint) {
uint32_t next_pc;
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;
if (handle_breakpoints)
breakpoint = breakpoint_find(target,
buf_get_u32(arm->pc->value, 0, 32));
- if (breakpoint != NULL) {
+ if (breakpoint) {
retval = xscale_unset_breakpoint(target, breakpoint);
if (retval != ERROR_OK)
return retval;
{
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));
/* mark all hardware breakpoints as unset */
while (breakpoint) {
if (breakpoint->type == BKPT_HARD)
- breakpoint->set = 0;
+ breakpoint->is_set = false;
breakpoint = breakpoint->next;
}
* 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_TARGET_NOT_HALTED;
}
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
if (!xscale->ibcr0_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], value);
xscale->ibcr0_used = 1;
- breakpoint->set = 1; /* breakpoint set on first breakpoint register */
+ /* breakpoint set on first breakpoint register */
+ breakpoint_hw_set(breakpoint, 0);
} else if (!xscale->ibcr1_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], value);
xscale->ibcr1_used = 1;
- breakpoint->set = 2; /* breakpoint set on second breakpoint register */
+ /* breakpoint set on second breakpoint register */
+ breakpoint_hw_set(breakpoint, 1);
} else {/* bug: availability previously verified in xscale_add_breakpoint() */
LOG_ERROR("BUG: no hardware comparator available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
if (retval != ERROR_OK)
return retval;
}
- breakpoint->set = 1;
+ breakpoint->is_set = true;
xscale_send_u32(target, 0x50); /* clean dcache */
xscale_send_u32(target, xscale->cache_clean_address);
return ERROR_TARGET_NOT_HALTED;
}
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
- if (breakpoint->set == 1) {
+ if (breakpoint->number == 0) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR0], 0x0);
xscale->ibcr0_used = 0;
- } else if (breakpoint->set == 2) {
+ } else if (breakpoint->number == 1) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_IBCR1], 0x0);
xscale->ibcr1_used = 0;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
} else {
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4) {
if (retval != ERROR_OK)
return retval;
}
- breakpoint->set = 0;
+ breakpoint->is_set = false;
xscale_send_u32(target, 0x50); /* clean dcache */
xscale_send_u32(target, xscale->cache_clean_address);
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set)
+ if (breakpoint->is_set)
xscale_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR0], watchpoint->address);
dbcon_value |= enable;
xscale_set_reg_u32(dbcon, dbcon_value);
- watchpoint->set = 1;
+ watchpoint_set(watchpoint, 0);
xscale->dbr0_used = 1;
} else if (!xscale->dbr1_used) {
xscale_set_reg_u32(&xscale->reg_cache->reg_list[XSCALE_DBR1], watchpoint->address);
dbcon_value |= enable << 2;
xscale_set_reg_u32(dbcon, dbcon_value);
- watchpoint->set = 2;
+ watchpoint_set(watchpoint, 1);
xscale->dbr1_used = 1;
} else {
LOG_ERROR("BUG: no hardware comparator available");
return ERROR_TARGET_NOT_HALTED;
}
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
- if (watchpoint->set == 1) {
+ if (watchpoint->number == 0) {
if (watchpoint->length > 4) {
dbcon_value &= ~0x103; /* clear DBCON[M] as well */
xscale->dbr1_used = 0; /* DBR1 was used for mask */
xscale_set_reg_u32(dbcon, dbcon_value);
xscale->dbr0_used = 0;
- } else if (watchpoint->set == 2) {
+ } else if (watchpoint->number == 1) {
dbcon_value &= ~0xc;
xscale_set_reg_u32(dbcon, dbcon_value);
xscale->dbr1_used = 0;
}
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
xscale_unset_watchpoint(target, watchpoint);
if (watchpoint->length > 4)
} else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) {
/* can't (explicitly) read from TXRXCTRL register */
return ERROR_OK;
- } else {/* Other DBG registers have to be transfered by the debug handler
+ } else {/* Other DBG registers have to be transferred by the debug handler
* send CP read request (command 0x40) */
xscale_send_u32(target, 0x40);
xscale_read_tx(target, 1);
buf_cpy(xscale->reg_cache->reg_list[XSCALE_TX].value, reg->value, 32);
- reg->dirty = 0;
- reg->valid = 1;
+ reg->dirty = false;
+ reg->valid = true;
}
return ERROR_OK;
} else if (strcmp(reg->name, "XSCALE_TXRXCTRL") == 0) {
/* can't (explicitly) write to TXRXCTRL register */
return ERROR_OK;
- } else {/* Other DBG registers have to be transfered by the debug handler
+ } else {/* Other DBG registers have to be transferred by the debug handler
* send CP write request (command 0x41) */
xscale_send_u32(target, 0x41);
struct arm_instruction *instruction)
{
struct xscale_common *const xscale = target_to_xscale(target);
- int i;
int section = -1;
size_t size_read;
uint32_t opcode;
return ERROR_TRACE_IMAGE_UNAVAILABLE;
/* search for the section the current instruction belongs to */
- for (i = 0; i < xscale->trace.image->num_sections; i++) {
+ for (unsigned int i = 0; i < xscale->trace.image->num_sections; i++) {
if ((xscale->trace.image->sections[i].base_address <= pc) &&
(xscale->trace.image->sections[i].base_address +
xscale->trace.image->sections[i].size > pc)) {
static inline void xscale_display_instruction(struct target *target, uint32_t pc,
struct arm_instruction *instruction,
- struct command_context *cmd_ctx)
+ struct command_invocation *cmd)
{
int retval = xscale_read_instruction(target, pc, instruction);
if (retval == ERROR_OK)
- command_print(cmd_ctx, "%s", instruction->text);
+ command_print(cmd, "%s", instruction->text);
else
- command_print(cmd_ctx, "0x%8.8" PRIx32 "\t<not found in image>", pc);
+ command_print(cmd, "0x%8.8" PRIx32 "\t<not found in image>", pc);
}
-static int xscale_analyze_trace(struct target *target, struct command_context *cmd_ctx)
+static int xscale_analyze_trace(struct target *target, struct command_invocation *cmd)
{
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 */
count = trace_data->entries[i].data & 0x0f;
for (j = 0; j < count; j++) {
xscale_display_instruction(target, current_pc, &instruction,
- cmd_ctx);
+ cmd);
current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
}
* rollover and some exceptions: undef, swi, prefetch abort. */
if ((trace_msg_type == 15) || (exception > 0 && exception < 4)) {
xscale_display_instruction(target, current_pc, &instruction,
- cmd_ctx);
+ cmd);
current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
}
continue;
if (exception) {
- command_print(cmd_ctx, "--- exception %i ---", exception);
+ command_print(cmd, "--- exception %i ---", exception);
continue;
}
/* not exception or rollover; next instruction is a branch and is
* not included in the count */
- xscale_display_instruction(target, current_pc, &instruction, cmd_ctx);
+ xscale_display_instruction(target, current_pc, &instruction, cmd);
/* for direct branches, extract branch destination from instruction */
if ((trace_msg_type == 8) || (trace_msg_type == 12)) {
current_pc = chkpt_reg;
else if (current_pc != chkpt_reg) /* sanity check */
LOG_WARNING("trace is suspect: checkpoint register "
- "inconsistent with adddress from image");
+ "inconsistent with address from image");
}
if (current_pc == 0)
- command_print(cmd_ctx, "address unknown");
+ command_print(cmd, "address unknown");
continue;
}
/* display remaining instructions */
for (i = 0; i < gap_count; i++) {
- xscale_display_instruction(target, current_pc, &instruction, cmd_ctx);
+ xscale_display_instruction(target, current_pc, &instruction, cmd);
current_pc += xscale->trace.core_state == ARM_STATE_ARM ? 4 : 2;
}
/* fill in values for the xscale reg cache */
(*cache_p)->name = "XScale registers";
(*cache_p)->next = NULL;
- (*cache_p)->reg_list = malloc(num_regs * sizeof(struct reg));
+ (*cache_p)->reg_list = calloc(num_regs, sizeof(struct reg));
(*cache_p)->num_regs = num_regs;
for (i = 0; i < num_regs; i++) {
(*cache_p)->reg_list[i].name = xscale_reg_list[i];
(*cache_p)->reg_list[i].value = calloc(4, 1);
- (*cache_p)->reg_list[i].dirty = 0;
- (*cache_p)->reg_list[i].valid = 0;
+ (*cache_p)->reg_list[i].dirty = false;
+ (*cache_p)->reg_list[i].valid = false;
(*cache_p)->reg_list[i].size = 32;
(*cache_p)->reg_list[i].arch_info = &arch_info[i];
(*cache_p)->reg_list[i].type = &xscale_reg_type;
+ (*cache_p)->reg_list[i].exist = true;
arch_info[i] = xscale_reg_arch_info[i];
arch_info[i].target = target;
}
xscale->reg_cache = (*cache_p);
}
+static void xscale_free_reg_cache(struct target *target)
+{
+ struct xscale_common *xscale = target_to_xscale(target);
+ struct reg_cache *cache = xscale->reg_cache;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(xscale_reg_arch_info); i++)
+ free(cache->reg_list[i].value);
+
+ free(cache->reg_list[0].arch_info);
+ free(cache->reg_list);
+ free(cache);
+
+ arm_free_reg_cache(&xscale->arm);
+}
+
static int xscale_init_target(struct command_context *cmd_ctx,
struct target *target)
{
return ERROR_OK;
}
+static void xscale_deinit_target(struct target *target)
+{
+ struct xscale_common *xscale = target_to_xscale(target);
+
+ xscale_free_reg_cache(target);
+ free(xscale);
+}
+
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;
arm = &xscale->arm;
- /* store architecture specfic data */
+ /* store architecture specific 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->core_type = ARM_CORE_TYPE_STD;
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_COMMAND_SYNTAX_ERROR;
target = get_target(CMD_ARGV[0]);
- if (target == NULL) {
+ if (!target) {
LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
return ERROR_FAIL;
}
xscale = target_to_xscale(target);
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
return ERROR_COMMAND_SYNTAX_ERROR;
target = get_target(CMD_ARGV[0]);
- if (target == NULL) {
+ if (!target) {
LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
return ERROR_FAIL;
}
xscale = target_to_xscale(target);
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
- return armv4_5_handle_cache_info_command(CMD_CTX, &xscale->armv4_5_mmu.armv4_5_cache);
+ return armv4_5_handle_cache_info_command(CMD, &xscale->armv4_5_mmu.armv4_5_cache);
}
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;
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+ command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK;
}
xscale->armv4_5_mmu.mmu_enabled = enable;
}
- command_print(CMD_CTX, "mmu %s",
+ command_print(CMD, "mmu %s",
(xscale->armv4_5_mmu.mmu_enabled) ? "enabled" : "disabled");
return ERROR_OK;
struct target *target = get_current_target(CMD_CTX);
struct xscale_common *xscale = target_to_xscale(target);
- int retval = xscale_verify_pointer(CMD_CTX, xscale);
+ int retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+ command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK;
}
xscale->armv4_5_mmu.armv4_5_cache.i_cache_enabled :
xscale->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled;
const char *msg = enabled ? "enabled" : "disabled";
- command_print(CMD_CTX, "%s %s", CMD_NAME, msg);
+ command_print(CMD, "%s %s", CMD_NAME, msg);
return ERROR_OK;
}
uint32_t catch = 0;
struct reg *dcsr_reg = &xscale->reg_cache->reg_list[XSCALE_DCSR];
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
- 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) {
return ERROR_COMMAND_SYNTAX_ERROR;
}
}
- *(uint32_t *)(dcsr_reg->value) &= ~DCSR_TRAP_MASK;
- *(uint32_t *)(dcsr_reg->value) |= catch;
+ 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);
}
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,
+ command_print(CMD, "%15s: %s", vec_ids[i].name,
(dcsr_value & vec_ids[i].mask) ? "catch" : "ignore");
}
int err = 0;
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (CMD_ARGC == 0) { /* print current settings */
int idx;
- command_print(CMD_CTX, "active user-set static vectors:");
+ command_print(CMD, "active user-set static vectors:");
for (idx = 1; idx < 8; idx++)
if (xscale->static_low_vectors_set & (1 << idx))
- command_print(CMD_CTX,
+ command_print(CMD,
"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,
+ command_print(CMD,
"high %d: 0x%" PRIx32,
idx,
xscale->static_high_vectors[idx]);
uint32_t dcsr_value;
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+ command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK;
}
if (CMD_ARGC >= 3)
COMMAND_PARSE_NUMBER(int, CMD_ARGV[2], buffcount);
if (buffcount < 1) { /* invalid */
- command_print(CMD_CTX, "fill buffer count must be > 0");
+ command_print(CMD, "fill buffer count must be > 0");
xscale->trace.mode = XSCALE_TRACE_DISABLED;
return ERROR_COMMAND_SYNTAX_ERROR;
}
if (xscale->trace.mode != XSCALE_TRACE_DISABLED) {
char fill_string[12];
- sprintf(fill_string, "fill %" PRId32, xscale->trace.buffer_fill);
- command_print(CMD_CTX, "trace buffer enabled (%s)",
+ sprintf(fill_string, "fill %d", xscale->trace.buffer_fill);
+ command_print(CMD, "trace buffer enabled (%s)",
(xscale->trace.mode == XSCALE_TRACE_FILL)
? fill_string : "wrap");
} else
- command_print(CMD_CTX, "trace buffer disabled");
+ command_print(CMD, "trace buffer disabled");
dcsr_value = buf_get_u32(xscale->reg_cache->reg_list[XSCALE_DCSR].value, 0, 32);
if (xscale->trace.mode == XSCALE_TRACE_FILL)
if (CMD_ARGC < 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (xscale->trace.image) {
image_close(xscale->trace.image);
free(xscale->trace.image);
- command_print(CMD_CTX, "previously loaded image found and closed");
+ command_print(CMD, "previously loaded image found and closed");
}
xscale->trace.image = malloc(sizeof(struct image));
- xscale->trace.image->base_address_set = 0;
- xscale->trace.image->start_address_set = 0;
+ xscale->trace.image->base_address_set = false;
+ xscale->trace.image->start_address_set = false;
/* a base address isn't always necessary, default to 0x0 (i.e. don't relocate) */
if (CMD_ARGC >= 2) {
- xscale->trace.image->base_address_set = 1;
+ xscale->trace.image->base_address_set = true;
COMMAND_PARSE_NUMBER(llong, CMD_ARGV[1], xscale->trace.image->base_address);
} else
- xscale->trace.image->base_address_set = 0;
+ xscale->trace.image->base_address_set = false;
if (image_open(xscale->trace.image, CMD_ARGV[0],
(CMD_ARGC >= 3) ? CMD_ARGV[2] : NULL) != ERROR_OK) {
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);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+ command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK;
}
trace_data = xscale->trace.data;
if (!trace_data) {
- command_print(CMD_CTX, "no trace data collected");
+ command_print(CMD, "no trace data collected");
return ERROR_OK;
}
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;
}
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
- xscale_analyze_trace(target, CMD_CTX);
+ xscale_analyze_trace(target, CMD);
return ERROR_OK;
}
struct xscale_common *xscale = target_to_xscale(target);
int retval;
- retval = xscale_verify_pointer(CMD_CTX, xscale);
+ retval = xscale_verify_pointer(CMD, xscale);
if (retval != ERROR_OK)
return retval;
if (target->state != TARGET_HALTED) {
- command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
+ command_print(CMD, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK;
}
uint32_t reg_no = 0;
reg_no = XSCALE_CPACCESS;
break;
default:
- command_print(CMD_CTX, "invalid register number");
+ command_print(CMD, "invalid register number");
return ERROR_COMMAND_SYNTAX_ERROR;
}
reg = &xscale->reg_cache->reg_list[reg_no];
/* read cp15 control register */
xscale_get_reg(reg);
value = buf_get_u32(reg->value, 0, 32);
- command_print(CMD_CTX, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size),
+ command_print(CMD, "%s (/%i): 0x%" PRIx32 "", reg->name, (int)(reg->size),
value);
} else if (CMD_ARGC == 2) {
uint32_t value;
.handler = xscale_handle_cache_info_command,
.mode = COMMAND_EXEC,
.help = "display information about CPU caches",
+ .usage = "",
},
{
.name = "mmu",
.poll = xscale_poll,
.arch_state = xscale_arch_state,
- .target_request_data = NULL,
-
.halt = xscale_halt,
.resume = xscale_resume,
.step = xscale_step,
.deassert_reset = xscale_deassert_reset,
/* REVISIT on some cores, allow exporting iwmmxt registers ... */
+ .get_gdb_arch = arm_get_gdb_arch,
.get_gdb_reg_list = arm_get_gdb_reg_list,
.read_memory = xscale_read_memory,
.commands = xscale_command_handlers,
.target_create = xscale_target_create,
.init_target = xscale_init_target,
+ .deinit_target = xscale_deinit_target,
.virt2phys = xscale_virt2phys,
.mmu = xscale_mmu