X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fmips_m4k.c;h=d69a0a0aa3c5aa9d83d5125b37c2b4c120f4d792;hb=d86100261252805215282b17d214c48021ef7f79;hp=7e7733e9c682047c7f8ec164e5103ec3440d0760;hpb=0cba0d4df3fe120f08945703506f8405760325c9;p=openocd.git diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index 7e7733e9c6..d69a0a0aa3 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -26,11 +26,8 @@ #include "mips32.h" #include "mips_m4k.h" #include "mips32_dmaacc.h" -#include "jtag.h" -#include "log.h" +#include "target_type.h" -#include -#include /* cli handling */ @@ -50,6 +47,7 @@ int mips_m4k_target_create(struct target_s *target, Jim_Interp *interp); int mips_m4k_examine(struct target_s *target); int mips_m4k_assert_reset(target_t *target); int mips_m4k_deassert_reset(target_t *target); +int mips_m4k_checksum_memory(target_t *target, u32 address, u32 size, u32 *checksum); target_type_t mips_m4k_target = { @@ -73,7 +71,7 @@ target_type_t mips_m4k_target = .read_memory = mips_m4k_read_memory, .write_memory = mips_m4k_write_memory, .bulk_write_memory = mips_m4k_bulk_write_memory, - .checksum_memory = NULL, + .checksum_memory = mips_m4k_checksum_memory, .blank_check_memory = NULL, .run_algorithm = mips32_run_algorithm, @@ -92,7 +90,7 @@ target_type_t mips_m4k_target = int mips_m4k_examine_debug_reason(target_t *target) { - int break_status; + u32 break_status; int retval; if ((target->debug_reason != DBG_REASON_DBGRQ) @@ -163,7 +161,7 @@ int mips_m4k_poll(target_t *target) u32 ejtag_ctrl = ejtag_info->ejtag_ctrl; /* read ejtag control reg */ - jtag_add_end_state(TAP_IDLE); + jtag_set_end_state(TAP_IDLE); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); @@ -173,7 +171,7 @@ int mips_m4k_poll(target_t *target) { /* we have detected a reset, clear flag * otherwise ejtag will not work */ - jtag_add_end_state(TAP_IDLE); + jtag_set_end_state(TAP_IDLE); ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC; mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL); @@ -186,7 +184,7 @@ int mips_m4k_poll(target_t *target) { if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { - jtag_add_end_state(TAP_IDLE); + jtag_set_end_state(TAP_IDLE); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL); target->state = TARGET_HALTED; @@ -278,12 +276,12 @@ int mips_m4k_assert_reset(target_t *target) if (target->reset_halt) { /* use hardware to catch reset */ - jtag_add_end_state(TAP_IDLE); + jtag_set_end_state(TAP_IDLE); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT, NULL); } else { - jtag_add_end_state(TAP_IDLE); + jtag_set_end_state(TAP_IDLE); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT, NULL); } @@ -347,8 +345,11 @@ int mips_m4k_single_step_core(target_t *target) /* configure single step mode */ mips_ejtag_config_step(ejtag_info, 1); + /* disable interrupts while stepping */ + mips32_enable_interrupts(target, 0); + /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info, 1); + mips_ejtag_exit_debug(ejtag_info); mips_m4k_debug_entry(target); @@ -400,8 +401,11 @@ int mips_m4k_resume(struct target_s *target, int current, u32 address, int handl } } - /* exit debug mode - enable interrupts if required */ - mips_ejtag_exit_debug(ejtag_info, !debug_execution); + /* enable interrupts if we are running */ + mips32_enable_interrupts(target, !debug_execution); + + /* exit debug mode */ + mips_ejtag_exit_debug(ejtag_info); target->debug_reason = DBG_REASON_NOTHALTED; /* registers are now invalid */ @@ -455,8 +459,11 @@ int mips_m4k_step(struct target_s *target, int current, u32 address, int handle_ target_call_event_callbacks(target, TARGET_EVENT_RESUMED); + /* disable interrupts while stepping */ + mips32_enable_interrupts(target, 0); + /* exit debug mode */ - mips_ejtag_exit_debug(ejtag_info, 1); + mips_ejtag_exit_debug(ejtag_info); /* registers are now invalid */ mips32_invalidate_core_regs(target); @@ -489,7 +496,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"); @@ -518,7 +526,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_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_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; @@ -529,7 +584,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"); @@ -550,7 +606,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_read_memory(target, breakpoint->address, 4, 1, (u8*)¤t_instr)) != ERROR_OK) + { + return retval; + } + if (current_instr == MIPS32_SDBBP) + { + if((retval = target_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_read_memory(target, breakpoint->address, 2, 1, (u8*)¤t_instr)) != ERROR_OK) + { + return retval; + } + + if (current_instr == MIPS16_SDBBP) + { + if((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr)) != ERROR_OK) + { + return retval; + } + } + } } breakpoint->set = 0; @@ -561,16 +652,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; @@ -763,10 +855,11 @@ int mips_m4k_examine(struct target_s *target) mips_ejtag_t *ejtag_info = &mips32->ejtag_info; u32 idcode = 0; - if (!target->type->examined) + if (!target_was_examined(target)) { - mips_ejtag_get_idcode(ejtag_info, &idcode, NULL); - + mips_ejtag_get_idcode(ejtag_info, &idcode); + ejtag_info->idcode = idcode; + if (((idcode >> 1) & 0x7FF) == 0x29) { /* we are using a pic32mx so select ejtag port @@ -790,3 +883,8 @@ int mips_m4k_bulk_write_memory(target_t *target, u32 address, u32 count, u8 *buf { return mips_m4k_write_memory(target, address, 4, count, buffer); } + +int mips_m4k_checksum_memory(target_t *target, u32 address, u32 size, u32 *checksum) +{ + return ERROR_FAIL; /* use bulk read method */ +}