+ if (breakpoint->length != 4) /* make sure isa bit set */
+ comparator_list[bp_num].bp_value |= 1;
+ else /* make sure isa bit cleared */
+ comparator_list[bp_num].bp_value &= ~1;
+
+ /* 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);
+
+ uint32_t isa_req = breakpoint->length & 1; /* micro mips request bit */
+ uint32_t bplength = breakpoint->length & ~1; /* drop micro mips request bit for length */
+ uint32_t bpaddr = breakpoint->address & ~1; /* drop isa bit from address, if set */
+
+ if (bplength == 4) {
+ uint32_t verify = 0xffffffff;
+ uint32_t sdbbp32_instr = MIPS32_SDBBP(isa_req);
+ if (ejtag_info->endianness && isa_req)
+ sdbbp32_instr = SWAP16(sdbbp32_instr);
+
+ if ((breakpoint->address & 3) == 0) { /* word alligned */
+
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u32(target, bpaddr, sdbbp32_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u32(target, bpaddr, &verify);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (verify != sdbbp32_instr)
+ verify = 0;
+
+ } else { /* 16 bit aligned */
+ retval = target_read_memory(target, bpaddr, 2, 2, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ uint8_t sdbbp_buf[4];
+ target_buffer_set_u32(target, sdbbp_buf, sdbbp32_instr);
+
+ retval = target_write_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_memory(target, bpaddr, 2, 2, sdbbp_buf);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (target_buffer_get_u32(target, sdbbp_buf) != sdbbp32_instr)
+ verify = 0;
+ }
+
+ if (verify == 0) {
+ LOG_ERROR("Unable to set 32bit breakpoint at address %08" TARGET_PRIxADDR
+ " - check that memory is read/writable", breakpoint->address);
+ return ERROR_OK;
+ }
+
+ } else {
+ uint16_t verify = 0xffff;
+
+ retval = target_read_memory(target, bpaddr, bplength, 1, breakpoint->orig_instr);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_write_u16(target, bpaddr, MIPS16_SDBBP(isa_req));
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = target_read_u16(target, bpaddr, &verify);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (verify != MIPS16_SDBBP(isa_req)) {
+ LOG_ERROR("Unable to set 16bit breakpoint at address %08" TARGET_PRIxADDR
+ " - check that memory is read/writable", breakpoint->address);
+ return ERROR_OK;
+ }
+ }
+
+ breakpoint->set = 20; /* Any nice value but 0 */