- /* Automatic ISR masking mode off: Just step over the next instruction */
- if ((cortex_m3->isrmasking_mode != CORTEX_M3_ISRMASK_AUTO))
- {
- cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
- }
- else
- {
- /* Process interrupts during stepping in a way they don't interfere
- * debugging.
- *
- * Principle:
- *
- * Set a temporary break point at the current pc and let the core run
- * with interrupts enabled. Pending interrupts get served and we run
- * into the breakpoint again afterwards. Then we step over the next
- * instruction with interrupts disabled.
- *
- * If the pending interrupts don't complete within time, we leave the
- * core running. This may happen if the interrupts trigger faster
- * than the core can process them or the handler doesn't return.
- *
- * If no more breakpoints are available we simply do a step with
- * interrupts enabled.
- *
- */
-
- /* Set a temporary break point */
- retval = breakpoint_add(target, pc_value , 2, BKPT_TYPE_BY_ADDR(pc_value));
- bool tmp_bp_set = (retval == ERROR_OK);
-
- /* No more breakpoints left, just do a step */
- if (!tmp_bp_set)
- {
- cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
- }
- else
- {
- /* Start the core */
- LOG_DEBUG("Starting core to serve pending interrupts");
- int64_t t_start = timeval_ms();
- cortex_m3_write_debug_halt_mask(target, 0, C_HALT | C_STEP);
-
- /* Wait for pending handlers to complete or timeout */
- do {
- retval = mem_ap_read_atomic_u32(swjdp, DCB_DHCSR, &cortex_m3->dcb_dhcsr);
- if (retval != ERROR_OK)
- {
- target->state = TARGET_UNKNOWN;
- return retval;
- }
- isr_timed_out = ((timeval_ms() - t_start) > 500);
- } while (!((cortex_m3->dcb_dhcsr & S_HALT) || isr_timed_out));
-
- /* Remove the temporary breakpoint */
- breakpoint_remove(target, pc_value);
-
- if (isr_timed_out)
- {
- LOG_DEBUG("Interrupt handlers didn't complete within time, "
- "leaving target running");
- }
- else
- {
- /* Step over next instruction with interrupts disabled */
- cortex_m3_write_debug_halt_mask(target, C_HALT | C_MASKINTS, 0);
- cortex_m3_write_debug_halt_mask(target, C_STEP, C_HALT);
- /* Re-enable interrupts */
- cortex_m3_write_debug_halt_mask(target, C_HALT, C_MASKINTS);
- }
- }
- }