+ struct pracc_queue_info ctx = {.ejtag_info = ejtag_info};
+ pracc_queue_init(&ctx);
+
+ pracc_add(&ctx, 0, MIPS32_MFC0(ctx.isa, 8, 23, 0)); /* move COP0 Debug to $8 */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, 0x0100)); /* set SSt bit in debug reg */
+ if (!enable_step)
+ pracc_add(&ctx, 0, MIPS32_XORI(ctx.isa, 8, 8, 0x0100)); /* clear SSt bit in debug reg */
+
+ pracc_add(&ctx, 0, MIPS32_MTC0(ctx.isa, 8, 23, 0)); /* move $8 to COP0 Debug */
+ pracc_add(&ctx, 0, MIPS32_LUI(ctx.isa, 8, UPPER16(ejtag_info->reg8))); /* restore upper 16 bits of $8 */
+ pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */
+ pracc_add(&ctx, 0, MIPS32_ORI(ctx.isa, 8, 8, LOWER16(ejtag_info->reg8))); /* restore lower 16 bits of $8 */
+
+ ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1);
+ pracc_queue_free(&ctx);
+ return ctx.retval;
+}
+
+/*
+ * Disable memory protection for 0xFF20.0000–0xFF3F.FFFF
+ * It is needed by EJTAG 1.5-2.0, especially for BMIPS CPUs
+ * For example bcm7401 and others. At leas on some
+ * CPUs, DebugMode wont start if this bit is not removed.
+ */
+static int disable_dcr_mp(struct mips_ejtag *ejtag_info)
+{
+ uint32_t dcr;
+ int retval;
+
+ retval = mips32_dmaacc_read_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
+ if (retval != ERROR_OK)
+ goto error;
+
+ dcr &= ~EJTAG_DCR_MP;
+ retval = mips32_dmaacc_write_mem(ejtag_info, EJTAG_DCR, 4, 1, &dcr);
+ if (retval != ERROR_OK)
+ goto error;
+ return ERROR_OK;
+error:
+ LOG_ERROR("Failed to remove DCR MPbit!");
+ return retval;