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/mips_m4k.c | 109 ++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 97 insertions(+), 12 deletions(-) (limited to 'src/target/mips_m4k.c') 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; -- cgit v1.2.3