X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Ftarget%2Fmips_m4k.c;h=f4fd7d333cff3c78e16a55cb6c292a1393e285cf;hb=80a94681de4c304ed8d550d4da547cdc523d2207;hp=fc2a3f808a27e6175cbb2c0e1288c09f3c91c108;hpb=b8c44b3fd7265ff7c5c057bf5d4573344706a55e;p=openocd.git diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index fc2a3f808a..f4fd7d333c 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -51,30 +51,36 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, static int mips_m4k_examine_debug_reason(struct target *target) { + struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; uint32_t break_status; 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_IBS, &break_status); + 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_IBS, 0); + 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_DBS, &break_status); + 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_DBS, 0); + retval = target_write_u32(target, + ejtag_info->ejtag_dbs_addr, 0); if (retval != ERROR_OK) return retval; target->debug_reason = DBG_REASON_WATCHPOINT; @@ -364,12 +370,6 @@ static int mips_m4k_deassert_reset(struct target *target) return ERROR_OK; } -static int mips_m4k_soft_reset_halt(struct target *target) -{ - /* TODO */ - return ERROR_OK; -} - static int mips_m4k_single_step_core(struct target *target) { struct mips32_common *mips32 = target_to_mips32(target); @@ -587,6 +587,7 @@ static int mips_m4k_set_breakpoint(struct target *target, struct breakpoint *breakpoint) { struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips32_comparator *comparator_list = mips32->inst_break_list; int retval; @@ -608,10 +609,19 @@ static int mips_m4k_set_breakpoint(struct target *target, breakpoint->set = bp_num + 1; comparator_list[bp_num].used = 1; comparator_list[bp_num].bp_value = breakpoint->address; + + /* 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! :) */ + if (ejtag_info->ejtag_version == EJTAG_VERSION_20) + comparator_list[bp_num].bp_value &= 0xFFFFFFFC; + target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value); - target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000); - target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1); + target_write_u32(target, comparator_list[bp_num].reg_address + + 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 "", breakpoint->unique_id, bp_num, comparator_list[bp_num].bp_value); @@ -668,6 +678,7 @@ static int mips_m4k_unset_breakpoint(struct target *target, { /* get pointers to arch-specific information */ struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips32_comparator *comparator_list = mips32->inst_break_list; int retval; @@ -688,7 +699,8 @@ static int mips_m4k_unset_breakpoint(struct target *target, bp_num); comparator_list[bp_num].used = 0; comparator_list[bp_num].bp_value = 0; - target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0); + target_write_u32(target, comparator_list[bp_num].reg_address + + ejtag_info->ejtag_ibc_offs, 0); } else { /* restore original instruction (kept in target endianness) */ @@ -777,6 +789,7 @@ static int mips_m4k_set_watchpoint(struct target *target, struct watchpoint *watchpoint) { struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips32_comparator *comparator_list = mips32->data_break_list; int wp_num = 0; /* @@ -826,11 +839,25 @@ static int mips_m4k_set_watchpoint(struct target *target, watchpoint->set = wp_num + 1; comparator_list[wp_num].used = 1; comparator_list[wp_num].bp_value = watchpoint->address; - target_write_u32(target, comparator_list[wp_num].reg_address, comparator_list[wp_num].bp_value); - target_write_u32(target, comparator_list[wp_num].reg_address + 0x08, 0x00000000); - target_write_u32(target, comparator_list[wp_num].reg_address + 0x10, 0x00000000); - target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, enable); - target_write_u32(target, comparator_list[wp_num].reg_address + 0x20, 0); + + /* EJTAG 2.0 uses 29bit DBA. First 3 bits are reserved. + * There is as well no ASID register support. */ + if (ejtag_info->ejtag_version == EJTAG_VERSION_20) + comparator_list[wp_num].bp_value &= 0xFFFFFFF8; + else + target_write_u32(target, comparator_list[wp_num].reg_address + + ejtag_info->ejtag_dbasid_offs, 0x00000000); + + target_write_u32(target, comparator_list[wp_num].reg_address, + comparator_list[wp_num].bp_value); + target_write_u32(target, comparator_list[wp_num].reg_address + + ejtag_info->ejtag_dbm_offs, 0x00000000); + + target_write_u32(target, comparator_list[wp_num].reg_address + + ejtag_info->ejtag_dbc_offs, enable); + /* TODO: probably this value is ignored on 2.0 */ + target_write_u32(target, comparator_list[wp_num].reg_address + + ejtag_info->ejtag_dbv_offs, 0); LOG_DEBUG("wp_num %i bp_value 0x%" PRIx32 "", wp_num, comparator_list[wp_num].bp_value); return ERROR_OK; @@ -841,6 +868,7 @@ static int mips_m4k_unset_watchpoint(struct target *target, { /* get pointers to arch-specific information */ struct mips32_common *mips32 = target_to_mips32(target); + struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips32_comparator *comparator_list = mips32->data_break_list; if (!watchpoint->set) { @@ -855,7 +883,8 @@ static int mips_m4k_unset_watchpoint(struct target *target, } comparator_list[wp_num].used = 0; comparator_list[wp_num].bp_value = 0; - target_write_u32(target, comparator_list[wp_num].reg_address + 0x18, 0); + target_write_u32(target, comparator_list[wp_num].reg_address + + ejtag_info->ejtag_dbc_offs, 0); watchpoint->set = 0; return ERROR_OK; @@ -1355,15 +1384,12 @@ struct target_type mips_m4k_target = { .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, .assert_reset = mips_m4k_assert_reset, .deassert_reset = mips_m4k_deassert_reset, - .soft_reset_halt = mips_m4k_soft_reset_halt, .get_gdb_reg_list = mips32_get_gdb_reg_list,