+
+int mips32_examine(struct target_s *target)
+{
+ struct mips32_common *mips32 = target->arch_info;
+
+ if (!target_was_examined(target))
+ {
+ target_set_examined(target);
+
+ /* we will configure later */
+ mips32->bp_scanned = 0;
+ mips32->num_inst_bpoints = 0;
+ mips32->num_data_bpoints = 0;
+ mips32->num_inst_bpoints_avail = 0;
+ mips32->num_data_bpoints_avail = 0;
+ }
+
+ return ERROR_OK;
+}
+
+int mips32_configure_break_unit(struct target_s *target)
+{
+ /* get pointers to arch-specific information */
+ struct mips32_common *mips32 = target->arch_info;
+ int retval;
+ uint32_t dcr, bpinfo;
+ int i;
+
+ if (mips32->bp_scanned)
+ return ERROR_OK;
+
+ /* get info about breakpoint support */
+ if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK)
+ return retval;
+
+ if (dcr & (1 << 16))
+ {
+ /* get number of inst breakpoints */
+ if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK)
+ return retval;
+
+ mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
+ mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
+ mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(struct mips32_comparator));
+ for (i = 0; i < mips32->num_inst_bpoints; i++)
+ {
+ mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i);
+ }
+
+ /* clear IBIS reg */
+ if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK)
+ return retval;
+ }
+
+ if (dcr & (1 << 17))
+ {
+ /* get number of data breakpoints */
+ if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK)
+ return retval;
+
+ mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
+ mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
+ mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(struct mips32_comparator));
+ for (i = 0; i < mips32->num_data_bpoints; i++)
+ {
+ mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i);
+ }
+
+ /* clear DBIS reg */
+ if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK)
+ return retval;
+ }
+
+ LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, mips32->num_data_bpoints);
+
+ mips32->bp_scanned = 1;
+
+ return ERROR_OK;
+}
+
+int mips32_enable_interrupts(struct target_s *target, int enable)
+{
+ int retval;
+ int update = 0;
+ uint32_t dcr;
+
+ /* read debug control register */
+ if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK)
+ return retval;
+
+ if (enable)
+ {
+ if (!(dcr & (1 << 4)))
+ {
+ /* enable interrupts */
+ dcr |= (1 << 4);
+ update = 1;
+ }
+ }
+ else
+ {
+ if (dcr & (1 << 4))
+ {
+ /* disable interrupts */
+ dcr &= ~(1 << 4);
+ update = 1;
+ }
+ }
+
+ if (update)
+ {
+ if ((retval = target_write_u32(target, EJTAG_DCR, dcr)) != ERROR_OK)
+ return retval;
+ }
+
+ return ERROR_OK;
+}