From 6fda8707668c413a78f44ae4f58a79f5765376c2 Mon Sep 17 00:00:00 2001 From: ntfreak Date: Tue, 13 Jan 2009 11:33:19 +0000 Subject: - added mips software breakpoint support - changed some jtag LOG_DEBUG to only output when _DEBUG_JTAG_IO_ defined. Makes debugging other parts of openocd not as noisy - updated correct jtag id for pic32mx git-svn-id: svn://svn.berlios.de/openocd/trunk@1313 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/target/mips32.h | 4 ++ src/target/mips_m4k.c | 109 +++++++++++++++++++++++++++++++++++++----- src/target/target/pic32mx.cfg | 2 +- 3 files changed, 102 insertions(+), 13 deletions(-) (limited to 'src/target') diff --git a/src/target/mips32.h b/src/target/mips32.h index 646edb7d..9ada0b4e 100644 --- a/src/target/mips32.h +++ b/src/target/mips32.h @@ -116,7 +116,11 @@ typedef struct mips32_core_reg_s #define MIPS32_SB(reg, off, base) MIPS32_I_INST(MIPS32_OP_SB, base, reg, off) #define MIPS32_SH(reg, off, base) MIPS32_I_INST(MIPS32_OP_SH, base, reg, off) #define MIPS32_SW(reg, off, base) MIPS32_I_INST(MIPS32_OP_SW, base, reg, off) + +/* ejtag specific instructions */ #define MIPS32_DRET 0x4200001F +#define MIPS32_SDBBP 0x7000003F +#define MIPS16_SDBBP 0xE801 extern int mips32_arch_state(struct target_s *target); extern int mips32_init_arch_info(target_t *target, mips32_common_t *mips32, jtag_tap_t *tap); diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 09766594..b1a4e46a 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -490,7 +490,8 @@ int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) { mips32_common_t *mips32 = target->arch_info; mips32_comparator_t * comparator_list = mips32->inst_break_list; - + int retval; + if (breakpoint->set) { LOG_WARNING("breakpoint already set"); @@ -519,7 +520,54 @@ int mips_m4k_set_breakpoint(struct target_s *target, breakpoint_t *breakpoint) } else if (breakpoint->type == BKPT_SOFT) { - + if (breakpoint->length == 4) + { + u32 verify = 0xffffffff; + + if((retval = target->type->read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK) + { + return retval; + } + if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK) + { + return retval; + } + + if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK) + { + return retval; + } + if (verify != MIPS32_SDBBP) + { + LOG_ERROR("Unable to set 32bit breakpoint at address %08x - check that memory is read/writable", breakpoint->address); + return ERROR_OK; + } + } + else + { + u16 verify = 0xffff; + + if((retval = target->type->read_memory(target, breakpoint->address, breakpoint->length, 1, breakpoint->orig_instr)) != ERROR_OK) + { + return retval; + } + if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK) + { + return retval; + } + + if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK) + { + return retval; + } + if (verify != MIPS16_SDBBP) + { + LOG_ERROR("Unable to set 16bit breakpoint at address %08x - check that memory is read/writable", breakpoint->address); + return ERROR_OK; + } + } + + breakpoint->set = 20; /* Any nice value but 0 */ } return ERROR_OK; @@ -530,7 +578,8 @@ int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint) /* get pointers to arch-specific information */ mips32_common_t *mips32 = target->arch_info; mips32_comparator_t * comparator_list = mips32->inst_break_list; - + int retval; + if (!breakpoint->set) { LOG_WARNING("breakpoint not set"); @@ -551,7 +600,42 @@ int mips_m4k_unset_breakpoint(struct target_s *target, breakpoint_t *breakpoint) } else { - + /* restore original instruction (kept in target endianness) */ + if (breakpoint->length == 4) + { + u32 current_instr; + + /* check that user program has not modified breakpoint instruction */ + if ((retval = target->type->read_memory(target, breakpoint->address, 4, 1, (u8*)¤t_instr)) != ERROR_OK) + { + return retval; + } + if (current_instr == MIPS32_SDBBP) + { + if((retval = target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr)) != ERROR_OK) + { + return retval; + } + } + } + else + { + u16 current_instr; + + /* check that user program has not modified breakpoint instruction */ + if ((retval = target->type->read_memory(target, breakpoint->address, 2, 1, (u8*)¤t_instr)) != ERROR_OK) + { + return retval; + } + + if (current_instr == MIPS16_SDBBP) + { + if((retval = target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK) + { + return retval; + } + } + } } breakpoint->set = 0; @@ -562,16 +646,17 @@ int mips_m4k_add_breakpoint(struct target_s *target, breakpoint_t *breakpoint) { mips32_common_t *mips32 = target->arch_info; - if (mips32->num_inst_bpoints_avail < 1) + if (breakpoint->type == BKPT_HARD) { - LOG_INFO("no hardware breakpoint available"); - return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; - } - - /* default to hardware for now */ - breakpoint->type = BKPT_HARD; + if (mips32->num_inst_bpoints_avail < 1) + { + LOG_INFO("no hardware breakpoint available"); + return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; + } + + mips32->num_inst_bpoints_avail--; + } - mips32->num_inst_bpoints_avail--; mips_m4k_set_breakpoint(target, breakpoint); return ERROR_OK; diff --git a/src/target/target/pic32mx.cfg b/src/target/target/pic32mx.cfg index a2ebf492..139f801f 100644 --- a/src/target/target/pic32mx.cfg +++ b/src/target/target/pic32mx.cfg @@ -15,7 +15,7 @@ if { [info exists CPUTAPID ] } { set _CPUTAPID $CPUTAPID } else { # force an error till we get a good number - set _CPUTAPID 0xffffffff + set _CPUTAPID 0x30938053 } jtag_nsrst_delay 100 -- cgit v1.2.3