+ 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;
+
+ if (breakpoint->set) {
+ LOG_WARNING("breakpoint already set");
+ return ERROR_OK;
+ }
+
+ if (breakpoint->type == BKPT_HARD) {
+ int bp_num = 0;
+
+ 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: %" PRIu32 ")",
+ breakpoint->unique_id);
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+ 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 +
+ 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: %" 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: %" PRIu32, breakpoint->unique_id);
+ if (breakpoint->length == 4) {
+ uint32_t verify = 0xffffffff;
+
+ 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;
+
+ 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);
+ return ERROR_OK;
+ }
+ } else {
+ uint16_t verify = 0xffff;
+
+ retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
+ breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u16(target, breakpoint->address, &verify);
+ if (retval != ERROR_OK)
+ return retval;
+ if (verify != MIPS16_SDBBP) {
+ LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32
+ " - check that memory is read/writable", breakpoint->address);
+ return ERROR_OK;
+ }
+ }
+
+ breakpoint->set = 20; /* Any nice value but 0 */
+ }
+