+// SPDX-License-Identifier: GPL-2.0-or-later
+
/***************************************************************************
* Copyright (C) 2008 by Spencer Oliver *
* spen@spen-soft.co.uk *
* *
* Copyright (C) 2011 by Drasko DRASKOVIC *
* drasko.draskovic@gmail.com *
- * *
- * 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
#include "mips32_dmaacc.h"
#include "target_type.h"
#include "register.h"
+#include "smp.h"
static void mips_m4k_enable_breakpoints(struct target *target);
static void mips_m4k_enable_watchpoints(struct target *target);
static int mips_m4k_unset_breakpoint(struct target *target,
struct breakpoint *breakpoint);
static int mips_m4k_internal_restore(struct target *target, int current,
- uint32_t address, int handle_breakpoints,
+ target_addr_t address, int handle_breakpoints,
int debug_execution);
static int mips_m4k_halt(struct target *target);
-static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer);
static int mips_m4k_examine_debug_reason(struct target *target)
int retval;
if ((target->debug_reason != DBG_REASON_DBGRQ)
- && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
- /* get info about inst breakpoint support */
- retval = target_read_u32(target,
- ejtag_info->ejtag_ibs_addr, &break_status);
- if (retval != ERROR_OK)
- return retval;
- if (break_status & 0x1f) {
- /* we have halted on a breakpoint */
- retval = target_write_u32(target,
- ejtag_info->ejtag_ibs_addr, 0);
+ && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
+ if (ejtag_info->debug_caps & EJTAG_DCR_IB) {
+ /* get info about inst breakpoint support */
+ retval = target_read_u32(target,
+ ejtag_info->ejtag_ibs_addr, &break_status);
if (retval != ERROR_OK)
return retval;
- target->debug_reason = DBG_REASON_BREAKPOINT;
+ if (break_status & 0x1f) {
+ /* we have halted on a breakpoint */
+ retval = target_write_u32(target,
+ ejtag_info->ejtag_ibs_addr, 0);
+ if (retval != ERROR_OK)
+ return retval;
+ target->debug_reason = DBG_REASON_BREAKPOINT;
+ }
}
- /* get info about data breakpoint support */
- retval = target_read_u32(target,
- ejtag_info->ejtag_dbs_addr, &break_status);
- if (retval != ERROR_OK)
- return retval;
- if (break_status & 0x1f) {
- /* we have halted on a breakpoint */
- retval = target_write_u32(target,
- ejtag_info->ejtag_dbs_addr, 0);
+ if (ejtag_info->debug_caps & EJTAG_DCR_DB) {
+ /* get info about data breakpoint support */
+ retval = target_read_u32(target,
+ ejtag_info->ejtag_dbs_addr, &break_status);
if (retval != ERROR_OK)
return retval;
- target->debug_reason = DBG_REASON_WATCHPOINT;
+ if (break_status & 0x1f) {
+ /* we have halted on a breakpoint */
+ retval = target_write_u32(target,
+ ejtag_info->ejtag_dbs_addr, 0);
+ if (retval != ERROR_OK)
+ return retval;
+ target->debug_reason = DBG_REASON_WATCHPOINT;
+ }
}
}
/* attempt to find halt reason */
mips_m4k_examine_debug_reason(target);
+ mips32_read_config_regs(target);
+
/* default to mips32 isa, it will be changed below if required */
mips32->isa_mode = MIPS32_ISA_MIPS32;
- if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
- mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
+ /* other than mips32 only and isa bit set ? */
+ if (mips32->isa_imp && buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1))
+ mips32->isa_mode = mips32->isa_imp == 2 ? MIPS32_ISA_MIPS16E : MIPS32_ISA_MMIPS32;
LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
static struct target *get_mips_m4k(struct target *target, int32_t coreid)
{
struct target_list *head;
- struct target *curr;
- head = target->head;
- while (head != (struct target_list *)NULL) {
- curr = head->target;
+ foreach_smp_target(head, target->smp_targets) {
+ struct target *curr = head->target;
if ((curr->coreid == coreid) && (curr->state == TARGET_HALTED))
return curr;
- head = head->next;
}
return target;
}
{
int retval = ERROR_OK;
struct target_list *head;
- struct target *curr;
- head = target->head;
- while (head != (struct target_list *)NULL) {
+
+ foreach_smp_target(head, target->smp_targets) {
int ret = ERROR_OK;
- curr = head->target;
+ struct target *curr = head->target;
if ((curr != target) && (curr->state != TARGET_HALTED))
ret = mips_m4k_halt(curr);
if (ret != ERROR_OK) {
- LOG_ERROR("halt failed target->coreid: %d", curr->coreid);
+ LOG_ERROR("halt failed target->coreid: %" PRId32, curr->coreid);
retval = ret;
}
- head = head->next;
}
return retval;
}
/* the next polling trigger an halt event sent to gdb */
if ((target->state == TARGET_HALTED) && (target->smp) &&
(target->gdb_service) &&
- (target->gdb_service->target == NULL)) {
+ (!target->gdb_service->target)) {
target->gdb_service->target =
get_mips_m4k(target, target->gdb_service->core[1]);
target_call_event_callbacks(target, TARGET_EVENT_HALTED);
if (retval != ERROR_OK)
return retval;
+ ejtag_info->isa = (ejtag_ctrl & EJTAG_CTRL_DBGISA) ? 1 : 0;
+
/* clear this bit before handling polling
* as after reset registers will read zero */
if (ejtag_ctrl & EJTAG_CTRL_ROCC) {
struct mips_m4k_common *mips_m4k = target_to_m4k(target);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
+ /* 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));
srst_asserted = true;
}
- if (target->reset_halt) {
- /* use hardware to catch reset */
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
- } else
- mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
+
+ /* EJTAG before v2.5/2.6 does not support EJTAGBOOT or NORMALBOOT */
+ if (ejtag_info->ejtag_version != EJTAG_VERSION_20) {
+ if (target->reset_halt) {
+ /* use hardware to catch reset */
+ mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
+ } else
+ mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
+ }
if (jtag_reset_config & RESET_HAS_SRST) {
/* here we should issue a srst only, but we may have to assert trst as well */
jtag_add_reset(1, 1);
else if (!srst_asserted)
jtag_add_reset(0, 1);
+ } else if (target_has_event_action(target, TARGET_EVENT_RESET_ASSERT)) {
+ target_handle_event(target, TARGET_EVENT_RESET_ASSERT);
} else {
if (mips_m4k->is_pic32mx) {
LOG_DEBUG("Using MTAP reset to reset processor...");
{
int retval = ERROR_OK;
struct target_list *head;
- struct target *curr;
- head = target->head;
- while (head != (struct target_list *)NULL) {
+ foreach_smp_target(head, target->smp_targets) {
int ret = ERROR_OK;
- curr = head->target;
+ struct target *curr = head->target;
if ((curr != target) && (curr->state != TARGET_RUNNING)) {
/* resume current address , not in step mode */
ret = mips_m4k_internal_restore(curr, 1, address,
handle_breakpoints, 0);
if (ret != ERROR_OK) {
- LOG_ERROR("target->coreid :%d failed to resume at address :0x%x",
+ LOG_ERROR("target->coreid :%" PRId32 " failed to resume at address :0x%" PRIx32,
curr->coreid, address);
retval = ret;
}
}
- head = head->next;
}
return retval;
}
static int mips_m4k_internal_restore(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 mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
/* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) {
+ mips_m4k_isa_filter(mips32->isa_imp, &address);
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
- mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
- mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
+ mips32->core_cache->reg_list[MIPS32_PC].dirty = true;
+ mips32->core_cache->reg_list[MIPS32_PC].valid = true;
}
- if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
+ if ((mips32->isa_imp > 1) && debug_execution) /* if more than one isa supported */
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
if (!current)
/* Single step past breakpoint at current address */
breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) {
- LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
+ LOG_DEBUG("unset breakpoint at " TARGET_ADDR_FMT "",
+ breakpoint->address);
mips_m4k_unset_breakpoint(target, breakpoint);
mips_m4k_single_step_core(target);
mips_m4k_set_breakpoint(target, breakpoint);
}
static int mips_m4k_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)
{
int retval = ERROR_OK;
}
static int mips_m4k_step(struct target *target, int current,
- uint32_t address, int handle_breakpoints)
+ target_addr_t address, int handle_breakpoints)
{
/* get pointers to arch-specific information */
struct mips32_common *mips32 = target_to_mips32(target);
/* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) {
+ mips_m4k_isa_filter(mips32->isa_imp, &address);
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
- mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
- mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
+ mips32->core_cache->reg_list[MIPS32_PC].dirty = true;
+ mips32->core_cache->reg_list[MIPS32_PC].valid = true;
}
/* the front-end may request us not to handle breakpoints */
/* set any pending breakpoints */
while (breakpoint) {
- if (breakpoint->set == 0)
+ if (!breakpoint->is_set)
mips_m4k_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next;
}
struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval;
- if (breakpoint->set) {
+ if (breakpoint->is_set) {
LOG_WARNING("breakpoint already set");
return ERROR_OK;
}
while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
bp_num++;
if (bp_num >= mips32->num_inst_bpoints) {
- LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
+ LOG_ERROR("Can not find free FP Comparator(bpid: %" PRIu32 ")",
breakpoint->unique_id);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
- breakpoint->set = bp_num + 1;
+ breakpoint_hw_set(breakpoint, bp_num);
comparator_list[bp_num].used = 1;
comparator_list[bp_num].bp_value = breakpoint->address;
+ if (breakpoint->length != 4) /* make sure isa bit set */
+ comparator_list[bp_num].bp_value |= 1;
+ else /* make sure isa bit cleared */
+ comparator_list[bp_num].bp_value &= ~1;
+
/* EJTAG 2.0 uses 30bit IBA. First 2 bits are reserved.
* Warning: there is no IB ASID registers in 2.0.
* Do not set it! :) */
ejtag_info->ejtag_ibm_offs, 0x00000000);
target_write_u32(target, comparator_list[bp_num].reg_address +
ejtag_info->ejtag_ibc_offs, 1);
- LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
+ LOG_DEBUG("bpid: %" PRIu32 ", bp_num %i bp_value 0x%" PRIx32 "",
breakpoint->unique_id,
bp_num, comparator_list[bp_num].bp_value);
} else if (breakpoint->type == BKPT_SOFT) {
- LOG_DEBUG("bpid: %d", breakpoint->unique_id);
- if (breakpoint->length == 4) {
+ LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
+
+ uint32_t isa_req = breakpoint->length & 1; /* micro mips request bit */
+ uint32_t bplength = breakpoint->length & ~1; /* drop micro mips request bit for length */
+ uint32_t bpaddr = breakpoint->address & ~1; /* drop isa bit from address, if set */
+
+ if (bplength == 4) {
uint32_t verify = 0xffffffff;
+ uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+ if (ejtag_info->endianness && isa_req)
+ sdbbp32_instr = SWAP16(sdbbp32_instr);
- retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
- breakpoint->orig_instr);
- if (retval != ERROR_OK)
- return retval;
- retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP);
- if (retval != ERROR_OK)
- return retval;
+ if ((breakpoint->address & 3) == 0) { /* word aligned */
- retval = target_read_u32(target, breakpoint->address, &verify);
- if (retval != ERROR_OK)
- return retval;
- if (verify != MIPS32_SDBBP) {
- LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32
- " - check that memory is read/writable", breakpoint->address);
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, bpaddr, sdbbp32_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u32(target, bpaddr, &verify);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (verify != sdbbp32_instr)
+ verify = 0;
+
+ } else { /* 16 bit aligned */
+ retval = target_read_memory(target, bpaddr, 2, 2, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint8_t sdbbp_buf[4];
+ target_buffer_set_u32(target, sdbbp_buf, sdbbp32_instr);
+
+ retval = target_write_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (target_buffer_get_u32(target, sdbbp_buf) != sdbbp32_instr)
+ verify = 0;
+ }
+
+ if (verify == 0) {
+ LOG_ERROR("Unable to set 32bit breakpoint at address %08" TARGET_PRIxADDR
+ " - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
+
} else {
uint16_t verify = 0xffff;
- retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
- breakpoint->orig_instr);
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
- retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP);
+
+ retval = target_write_u16(target, bpaddr, MIPS16_SDBBP(isa_req));
if (retval != ERROR_OK)
return retval;
- retval = target_read_u16(target, breakpoint->address, &verify);
+ retval = target_read_u16(target, bpaddr, &verify);
if (retval != ERROR_OK)
return retval;
- if (verify != MIPS16_SDBBP) {
- LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32
+
+ if (verify != MIPS16_SDBBP(isa_req)) {
+ LOG_ERROR("Unable to set 16bit breakpoint at address %08" TARGET_PRIxADDR
" - check that memory is read/writable", breakpoint->address);
return ERROR_OK;
}
}
- breakpoint->set = 20; /* Any nice value but 0 */
+ breakpoint->is_set = true;
}
return ERROR_OK;
struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval;
- if (!breakpoint->set) {
+ if (!breakpoint->is_set) {
LOG_WARNING("breakpoint not set");
return ERROR_OK;
}
if (breakpoint->type == BKPT_HARD) {
- int bp_num = breakpoint->set - 1;
- if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints)) {
- LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
+ int bp_num = breakpoint->number;
+ if (bp_num >= mips32->num_inst_bpoints) {
+ LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %" PRIu32 ")",
breakpoint->unique_id);
return ERROR_OK;
}
- LOG_DEBUG("bpid: %d - releasing hw: %d",
+ LOG_DEBUG("bpid: %" PRIu32 " - releasing hw: %d",
breakpoint->unique_id,
bp_num);
comparator_list[bp_num].used = 0;
} else {
/* restore original instruction (kept in target endianness) */
- LOG_DEBUG("bpid: %d", breakpoint->unique_id);
- if (breakpoint->length == 4) {
- uint32_t current_instr;
-
- /* check that user program has not modified breakpoint instruction */
- retval = target_read_memory(target, breakpoint->address, 4, 1,
- (uint8_t *)¤t_instr);
- if (retval != ERROR_OK)
- return retval;
-
- /**
- * target_read_memory() gets us data in _target_ endianess.
- * If we want to use this data on the host for comparisons with some macros
- * we must first transform it to _host_ endianess using target_buffer_get_u32().
- */
- current_instr = target_buffer_get_u32(target, (uint8_t *)¤t_instr);
-
- if (current_instr == MIPS32_SDBBP) {
- retval = target_write_memory(target, breakpoint->address, 4, 1,
- breakpoint->orig_instr);
+ uint32_t isa_req = breakpoint->length & 1;
+ uint32_t bplength = breakpoint->length & ~1;
+ uint8_t current_instr[4];
+ LOG_DEBUG("bpid: %" PRIu32, breakpoint->unique_id);
+ if (bplength == 4) {
+ uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+ if (ejtag_info->endianness && isa_req)
+ sdbbp32_instr = SWAP16(sdbbp32_instr);
+
+ if ((breakpoint->address & 3) == 0) { /* 32bit aligned */
+ /* check that user program has not modified breakpoint instruction */
+ retval = target_read_memory(target, breakpoint->address, 4, 1, current_instr);
if (retval != ERROR_OK)
return retval;
+ /**
+ * target_read_memory() gets us data in _target_ endianness.
+ * If we want to use this data on the host for comparisons with some macros
+ * we must first transform it to _host_ endianness using target_buffer_get_u16().
+ */
+ if (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {
+ retval = target_write_memory(target, breakpoint->address, 4, 1,
+ breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+ } else { /* 16bit aligned */
+ retval = target_read_memory(target, breakpoint->address, 2, 2, current_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (sdbbp32_instr == target_buffer_get_u32(target, current_instr)) {
+ retval = target_write_memory(target, breakpoint->address, 2, 2,
+ breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ }
}
} else {
- uint16_t current_instr;
-
/* check that user program has not modified breakpoint instruction */
- retval = target_read_memory(target, breakpoint->address, 2, 1,
- (uint8_t *)¤t_instr);
+ retval = target_read_memory(target, breakpoint->address, 2, 1, current_instr);
if (retval != ERROR_OK)
return retval;
- current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr);
- if (current_instr == MIPS16_SDBBP) {
+
+ if (target_buffer_get_u16(target, current_instr) == MIPS16_SDBBP(isa_req)) {
retval = target_write_memory(target, breakpoint->address, 2, 1,
- breakpoint->orig_instr);
+ breakpoint->orig_instr);
if (retval != ERROR_OK)
return retval;
}
}
}
- breakpoint->set = 0;
+
+ breakpoint->is_set = false;
return ERROR_OK;
}
{
struct mips32_common *mips32 = target_to_mips32(target);
+ if ((breakpoint->length > 5 || breakpoint->length < 2) || /* out of range */
+ (breakpoint->length == 4 && (breakpoint->address & 2)) || /* mips32 unaligned */
+ (mips32->isa_imp == MIPS32_ONLY && breakpoint->length != 4) || /* misp32 specific */
+ ((mips32->isa_imp & 1) != (breakpoint->length & 1))) /* isa not implemented */
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+
if (breakpoint->type == BKPT_HARD) {
if (mips32->num_inst_bpoints_avail < 1) {
LOG_INFO("no hardware breakpoint available");
return ERROR_TARGET_NOT_HALTED;
}
- if (breakpoint->set)
+ if (breakpoint->is_set)
mips_m4k_unset_breakpoint(target, breakpoint);
if (breakpoint->type == BKPT_HARD)
* and exclude both load and store accesses from watchpoint
* condition evaluation
*/
- int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
- (0xff << EJTAG_DBCn_BLM_SHIFT);
+ int enable = EJTAG_DBCN_NOSB | EJTAG_DBCN_NOLB | EJTAG_DBCN_BE |
+ (0xff << EJTAG_DBCN_BLM_SHIFT);
- if (watchpoint->set) {
+ if (watchpoint->is_set) {
LOG_WARNING("watchpoint already set");
return ERROR_OK;
}
switch (watchpoint->rw) {
case WPT_READ:
- enable &= ~EJTAG_DBCn_NOLB;
+ enable &= ~EJTAG_DBCN_NOLB;
break;
case WPT_WRITE:
- enable &= ~EJTAG_DBCn_NOSB;
+ enable &= ~EJTAG_DBCN_NOSB;
break;
case WPT_ACCESS:
- enable &= ~(EJTAG_DBCn_NOLB | EJTAG_DBCn_NOSB);
+ enable &= ~(EJTAG_DBCN_NOLB | EJTAG_DBCN_NOSB);
break;
default:
LOG_ERROR("BUG: watchpoint->rw neither read, write nor access");
}
- watchpoint->set = wp_num + 1;
+ watchpoint->number = wp_num;
comparator_list[wp_num].used = 1;
comparator_list[wp_num].bp_value = watchpoint->address;
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
struct mips32_comparator *comparator_list = mips32->data_break_list;
- if (!watchpoint->set) {
+ if (!watchpoint->is_set) {
LOG_WARNING("watchpoint not set");
return ERROR_OK;
}
- int wp_num = watchpoint->set - 1;
- if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints)) {
+ int wp_num = watchpoint->number;
+ if (wp_num >= mips32->num_data_bpoints) {
LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK;
}
comparator_list[wp_num].bp_value = 0;
target_write_u32(target, comparator_list[wp_num].reg_address +
ejtag_info->ejtag_dbc_offs, 0);
- watchpoint->set = 0;
+ watchpoint->is_set = false;
return ERROR_OK;
}
return ERROR_TARGET_NOT_HALTED;
}
- if (watchpoint->set)
+ if (watchpoint->is_set)
mips_m4k_unset_watchpoint(target, watchpoint);
mips32->num_data_bpoints_avail++;
/* set any pending watchpoints */
while (watchpoint) {
- if (watchpoint->set == 0)
+ if (!watchpoint->is_set)
mips_m4k_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next;
}
}
-static int mips_m4k_read_memory(struct target *target, uint32_t address,
+static int mips_m4k_read_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
- 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);
if (target->state != TARGET_HALTED) {
if (size > 1) {
t = malloc(count * size * sizeof(uint8_t));
- if (t == NULL) {
+ if (!t) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
/* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
/* endianness, but byte array should represent target endianness */
- if (ERROR_OK == retval) {
+ if (retval == ERROR_OK) {
switch (size) {
case 4:
target_buffer_set_u32_array(target, buffer, count, t);
}
}
- if ((size > 1) && (t != NULL))
+ if (size > 1)
free(t);
return retval;
}
-static int mips_m4k_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_write_memory(struct target *target, target_addr_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
- 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);
if (target->state != TARGET_HALTED) {
if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
return ERROR_TARGET_UNALIGNED_ACCESS;
- /** correct endianess if we have word or hword access */
+ /** correct endianness if we have word or hword access */
void *t = NULL;
if (size > 1) {
/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
/* endianness, but byte array represents target endianness */
t = malloc(count * size * sizeof(uint8_t));
- if (t == NULL) {
+ if (!t) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
/* if noDMA off, use DMAACC mode for memory write */
int retval;
if (ejtag_info->impcode & EJTAG_IMP_NODMA)
- retval = mips32_pracc_write_mem(ejtag_info, address, size, count, (void *)buffer);
+ retval = mips32_pracc_write_mem(ejtag_info, address, size, count, buffer);
else
- retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, (void *)buffer);
+ retval = mips32_dmaacc_write_mem(ejtag_info, address, size, count, buffer);
- if (t != NULL)
- free(t);
+ free(t);
- if (ERROR_OK != retval)
+ if (retval != ERROR_OK)
return retval;
return ERROR_OK;
static int mips_m4k_examine(struct target *target)
{
- int retval;
struct mips_m4k_common *mips_m4k = target_to_m4k(target);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
- uint32_t idcode = 0;
if (!target_was_examined(target)) {
- retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
- if (retval != ERROR_OK)
+ int retval = mips_ejtag_get_idcode(ejtag_info);
+ if (retval != ERROR_OK) {
+ LOG_ERROR("idcode read failed");
return retval;
- ejtag_info->idcode = idcode;
-
- if (((idcode >> 1) & 0x7FF) == 0x29) {
+ }
+ if (((ejtag_info->idcode >> 1) & 0x7FF) == 0x29) {
/* we are using a pic32mx so select ejtag port
* as it is not selected by default */
mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
- LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
+ LOG_DEBUG("PIC32 Detected - using EJTAG Interface");
mips_m4k->is_pic32mx = true;
}
}
/* init rest of ejtag interface */
- retval = mips_ejtag_init(ejtag_info);
- if (retval != ERROR_OK)
- return retval;
-
- retval = mips32_examine(target);
+ int retval = mips_ejtag_init(ejtag_info);
if (retval != ERROR_OK)
return retval;
- return ERROR_OK;
+ return mips32_examine(target);
}
-static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
+static int mips_m4k_bulk_write_memory(struct target *target, target_addr_t address,
uint32_t count, const uint8_t *buffer)
{
struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+ struct working_area *fast_data_area;
int retval;
int write_t = 1;
- LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
+ LOG_DEBUG("address: " TARGET_ADDR_FMT ", count: 0x%8.8" PRIx32 "",
+ address, count);
/* check alignment */
if (address & 0x3u)
return ERROR_TARGET_UNALIGNED_ACCESS;
- if (mips32->fast_data_area == NULL) {
+ if (!mips32->fast_data_area) {
/* Get memory for block write handler
* we preserve this area between calls and gain a speed increase
* of about 3kb/sec when writing flash
ejtag_info->fast_access_save = -1;
}
+ fast_data_area = mips32->fast_data_area;
+
+ if (address <= fast_data_area->address + fast_data_area->size &&
+ fast_data_area->address <= address + count) {
+ LOG_ERROR("fast_data (" TARGET_ADDR_FMT ") is within write area "
+ "(" TARGET_ADDR_FMT "-" TARGET_ADDR_FMT ").",
+ fast_data_area->address, address, address + count);
+ LOG_ERROR("Change work-area-phys or load_image address!");
+ return ERROR_FAIL;
+ }
+
/* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
/* but byte array represents target endianness */
uint32_t *t = NULL;
t = malloc(count * sizeof(uint32_t));
- if (t == NULL) {
+ if (!t) {
LOG_ERROR("Out of memory");
return ERROR_FAIL;
}
retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
count, t);
- if (t != NULL)
- free(t);
+ free(t);
if (retval != ERROR_OK)
LOG_ERROR("Fastdata access Failed");
return retval;
}
-static int mips_m4k_verify_pointer(struct command_context *cmd_ctx,
+static int mips_m4k_verify_pointer(struct command_invocation *cmd,
struct mips_m4k_common *mips_m4k)
{
if (mips_m4k->common_magic != MIPSM4K_COMMON_MAGIC) {
- command_print(cmd_ctx, "target is not an MIPS_M4K");
+ command_print(cmd, "target is not an MIPS_M4K");
return ERROR_TARGET_INVALID;
}
return ERROR_OK;
struct mips_m4k_common *mips_m4k = target_to_m4k(target);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
- retval = mips_m4k_verify_pointer(CMD_CTX, mips_m4k);
+ retval = mips_m4k_verify_pointer(CMD, mips_m4k);
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 value;
retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
if (retval != ERROR_OK) {
- command_print(CMD_CTX,
- "couldn't access reg %" PRIi32,
+ command_print(CMD,
+ "couldn't access reg %" PRIu32,
cp0_reg);
return ERROR_OK;
}
- command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
+ command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
cp0_reg, cp0_sel, value);
} else if (CMD_ARGC == 3) {
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
if (retval != ERROR_OK) {
- command_print(CMD_CTX,
- "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
+ command_print(CMD,
+ "couldn't access cp0 reg %" PRIu32 ", select %" PRIu32,
cp0_reg, cp0_sel);
return ERROR_OK;
}
- command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
+ command_print(CMD, "cp0 reg %" PRIu32 ", select %" PRIu32 ": %8.8" PRIx32,
cp0_reg, cp0_sel, value);
}
}
return ERROR_OK;
}
-COMMAND_HANDLER(mips_m4k_handle_smp_off_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- /* check target is an smp target */
- struct target_list *head;
- struct target *curr;
- head = target->head;
- target->smp = 0;
- if (head != (struct target_list *)NULL) {
- while (head != (struct target_list *)NULL) {
- curr = head->target;
- curr->smp = 0;
- head = head->next;
- }
- /* fixes the target display to the debugger */
- target->gdb_service->target = target;
- }
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(mips_m4k_handle_smp_on_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- struct target_list *head;
- struct target *curr;
- head = target->head;
- if (head != (struct target_list *)NULL) {
- target->smp = 1;
- while (head != (struct target_list *)NULL) {
- curr = head->target;
- curr->smp = 1;
- head = head->next;
- }
- }
- return ERROR_OK;
-}
-
-COMMAND_HANDLER(mips_m4k_handle_smp_gdb_command)
-{
- struct target *target = get_current_target(CMD_CTX);
- int retval = ERROR_OK;
- struct target_list *head;
- head = target->head;
- if (head != (struct target_list *)NULL) {
- if (CMD_ARGC == 1) {
- int coreid = 0;
- COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], coreid);
- if (ERROR_OK != retval)
- return retval;
- target->gdb_service->core[1] = coreid;
-
- }
- command_print(CMD_CTX, "gdb coreid %d -> %d", target->gdb_service->core[0]
- , target->gdb_service->core[1]);
- }
- return ERROR_OK;
-}
-
COMMAND_HANDLER(mips_m4k_handle_scan_delay_command)
{
struct target *target = get_current_target(CMD_CTX);
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
if (CMD_ARGC == 1)
- COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], ejtag_info->scan_delay);
+ COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], ejtag_info->scan_delay);
else if (CMD_ARGC > 1)
return ERROR_COMMAND_SYNTAX_ERROR;
- command_print(CMD_CTX, "scan delay: %d nsec", ejtag_info->scan_delay);
- if (ejtag_info->scan_delay >= 20000000) {
+ command_print(CMD, "scan delay: %d nsec", ejtag_info->scan_delay);
+ if (ejtag_info->scan_delay >= MIPS32_SCAN_DELAY_LEGACY_MODE) {
ejtag_info->mode = 0;
- command_print(CMD_CTX, "running in legacy mode");
+ command_print(CMD, "running in legacy mode");
} else {
ejtag_info->mode = 1;
- command_print(CMD_CTX, "running in fast queued mode");
+ command_print(CMD, "running in fast queued mode");
}
return ERROR_OK;
.usage = "regnum [value]",
.help = "display/modify cp0 register",
},
- {
- .name = "smp_off",
- .handler = mips_m4k_handle_smp_off_command,
- .mode = COMMAND_EXEC,
- .help = "Stop smp handling",
- .usage = "",},
-
- {
- .name = "smp_on",
- .handler = mips_m4k_handle_smp_on_command,
- .mode = COMMAND_EXEC,
- .help = "Restart smp handling",
- .usage = "",
- },
- {
- .name = "smp_gdb",
- .handler = mips_m4k_handle_smp_gdb_command,
- .mode = COMMAND_EXEC,
- .help = "display/fix current core played to gdb",
- .usage = "",
- },
{
.name = "scan_delay",
.handler = mips_m4k_handle_scan_delay_command,
.help = "display/set scan delay in nano seconds",
.usage = "[value]",
},
+ {
+ .chain = smp_command_handlers,
+ },
COMMAND_REGISTRATION_DONE
};
-const struct command_registration mips_m4k_command_handlers[] = {
+static const struct command_registration mips_m4k_command_handlers[] = {
{
.chain = mips32_command_handlers,
},
.poll = mips_m4k_poll,
.arch_state = mips32_arch_state,
- .target_request_data = NULL,
-
.halt = mips_m4k_halt,
.resume = mips_m4k_resume,
.step = mips_m4k_step,