This is an automated email from Gerrit. "Sigurður Ásgeirsson <siggi+sourcefo...@sort.is>" just uploaded a new patch set to Gerrit, which you can find at https://review.openocd.org/c/openocd/+/8519
-- gerrit commit 30ee6e398c285a7e055d250fa9287bbd643a8315 Author: Sigurdur Asgeirsson <siggi+sourcefo...@sort.is> Date: Thu Oct 3 13:21:03 2024 -0400 target/m4k: fix SDBBP breakpoint handling. The cachability of the written pages was not derived correctly, leading to stale ICache under the right circumstances. The debug entry cause on SDBBP exception was not correctly derived, leading to extra stops in gdb when e.g. continuing from a breakpoint. Change-Id: Ib7e629ebb21475472fc5ae365654b40e61f0c52b Reported-by: Sigurdur Asgeirsson <siggi+sourcefo...@sort.is> BugLink: https://sourceforge.net/p/openocd/tickets/438/ Signed-off-by: Sigurdur Asgeirsson <siggi+sourcefo...@sort.is> diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c index aaf3875fb7..95e9ff0620 100644 --- a/src/target/mips32_pracc.c +++ b/src/target/mips32_pracc.c @@ -839,32 +839,45 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz * is the region cacheable or uncached. * If cacheable we have to synchronize the cache */ - if (cached == 3 || cached == 0) { /* Write back cache or write through cache */ - uint32_t start_addr = addr; - uint32_t end_addr = addr + count * size; - uint32_t rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT; - /* FIXME: In MIPS Release 6, the encoding of CACHE instr has changed */ - if (rel > MIPS32_RELEASE_2) { - LOG_DEBUG("Unsupported MIPS Release ( > 5)"); - return ERROR_FAIL; + switch (cached) { + case 0: // m4k/mips32 reserved. + case 3: // m4k WB. + case 4: // m4k CWBE. + case 5: // m4k CWB. + { + uint32_t start_addr = addr; + uint32_t end_addr = addr + count * size; + uint32_t rel = (conf & MIPS32_CONFIG0_AR_MASK) >> MIPS32_CONFIG0_AR_SHIFT; + /* FIXME: In MIPS Release 6, the encoding of CACHE instr has changed */ + if (rel > MIPS32_RELEASE_2) { + LOG_DEBUG("Unsupported MIPS Release ( > 5)"); + return ERROR_FAIL; + } + retval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, end_addr, cached, rel); + break; } - retval = mips32_pracc_synchronize_cache(ejtag_info, start_addr, end_addr, cached, rel); - } else { - struct pracc_queue_info ctx = {.ejtag_info = ejtag_info}; - - pracc_queue_init(&ctx); - if (mips32_cpu_support_sync(ejtag_info)) - pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa)); - if (mips32_cpu_support_hazard_barrier(ejtag_info)) - pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa)); - pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */ - pracc_add(&ctx, 0, MIPS32_NOP); - ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1); - if (ctx.retval != ERROR_OK) { - LOG_ERROR("Unable to barrier"); - retval = ctx.retval; + case 1: // m4k/mips32 reserved. + case 2: // m4k UC. + case 6: // m4k/mips32 reserved. + case 7: // m4k UCA. + default: { + struct pracc_queue_info ctx = {.ejtag_info = ejtag_info}; + + pracc_queue_init(&ctx); + if (mips32_cpu_support_sync(ejtag_info)) + pracc_add(&ctx, 0, MIPS32_SYNC(ctx.isa)); + if (mips32_cpu_support_hazard_barrier(ejtag_info)) + pracc_add(&ctx, 0, MIPS32_EHB(ctx.isa)); + pracc_add(&ctx, 0, MIPS32_B(ctx.isa, NEG16((ctx.code_count + 1) << ctx.isa))); /* jump to start */ + pracc_add(&ctx, 0, MIPS32_NOP); + ctx.retval = mips32_pracc_queue_exec(ejtag_info, &ctx, NULL, 1); + if (ctx.retval != ERROR_OK) { + LOG_ERROR("Unable to barrier"); + retval = ctx.retval; + } + pracc_queue_free(&ctx); + break; } - pracc_queue_free(&ctx); } return retval; diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c index ad98089614..2da1b67965 100644 --- a/src/target/mips_m4k.c +++ b/src/target/mips_m4k.c @@ -43,11 +43,21 @@ 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 debug; uint32_t break_status; int retval; if ((target->debug_reason != DBG_REASON_DBGRQ) && (target->debug_reason != DBG_REASON_SINGLESTEP)) { + /* Check the Bp bit in the debug register to see whether this + debug entry is due to an SDBBP instruction. */ + retval = mips32_cp0_read(ejtag_info, &debug, 23, 0); + if (retval != ERROR_OK) + return retval; + if (debug & 0x2) { + target->debug_reason = DBG_REASON_BREAKPOINT; + } + if (ejtag_info->debug_caps & EJTAG_DCR_IB) { /* get info about inst breakpoint support */ retval = target_read_u32(target, --