+// 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, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
/* 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 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;
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;
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;
TAP_IDLE);
static const uint8_t t0;
- uint8_t t1[4];
+ uint8_t t1[4] = { 0 };
static const uint8_t t2 = 1;
struct scan_field fields[3] = {
{ .num_bits = 3, .out_value = &t0 },
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;
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;
}
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;
}
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;
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;
/* 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;
+ for (unsigned binary_size = sizeof(xscale_debug_handler);
binary_size > 0;
binary_size -= buf_cnt, buffer += buf_cnt) {
uint32_t cache_line[8];
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);
} 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)) {
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)
/* 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++) {
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)
{
arm = &xscale->arm;
- /* store architecture specfic data */
+ /* store architecture specific data */
xscale->common_magic = XSCALE_COMMON_MAGIC;
/* PXA3xx with 11 bit IR shifts the JTAG instructions */
/* 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 > 0x800) {
+ if (sizeof(xscale_debug_handler) > 0x800) {
LOG_ERROR("debug_handler.bin: larger than 2kb");
return ERROR_FAIL;
}
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;
}
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->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) {
.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