[PATCH v1 03/28] target/riscv: enter Debug Mode from pending DM halt requests

Chao Liu posted 28 patches 1 month ago
[PATCH v1 03/28] target/riscv: enter Debug Mode from pending DM halt requests
Posted by Chao Liu 1 month ago
Consume pending Debug Module halt requests from the regular CPU
execution path and enter Debug Mode with the recorded debug cause
before normal interrupt delivery.

This routes haltreq and reset-haltreq through the same entry path
used by other debug stops, clears the pending request once it is
taken, and jumps to the Debug Module ROM when the hart is wired
to one.

Signed-off-by: Chao Liu <chao.liu.zevorn@gmail.com>
---
 target/riscv/cpu_helper.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 714dcb446e..e477016d4a 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -655,12 +655,31 @@ static int riscv_cpu_local_irq_pending(CPURISCVState *env)
 
 bool riscv_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
 {
-    uint32_t mask = CPU_INTERRUPT_HARD | CPU_INTERRUPT_RNMI;
+    uint32_t mask = CPU_INTERRUPT_HARD | CPU_INTERRUPT_RNMI |
+                    CPU_INTERRUPT_DM_HALT;
 
     if (interrupt_request & mask) {
         RISCVCPU *cpu = RISCV_CPU(cs);
         CPURISCVState *env = &cpu->env;
 
+        /* DM halt request: enter debug mode before checking regular IRQs */
+        if (env->dm_halt_request && !env->debug_mode) {
+            uint32_t halt_cause = env->dm_halt_cause;
+
+            qemu_log_mask(CPU_LOG_INT,
+                          "exec_interrupt: dm_halt cause=%u pc=0x%" PRIx64
+                          " halt_addr=0x%" PRIx64 "\n",
+                          halt_cause,
+                          (uint64_t)env->pc,
+                          (uint64_t)env->dm_halt_addr);
+            env->dm_halt_request = false;
+            env->dm_halt_cause = DCSR_CAUSE_HALTREQ;
+            cpu_reset_interrupt(cs, CPU_INTERRUPT_DM_HALT);
+            riscv_cpu_enter_debug_mode(env, env->pc, halt_cause);
+            env->pc = env->dm_halt_addr;
+            return true;
+        }
+
         if (cpu->cfg.ext_sdext && !env->debug_mode &&
             (env->dcsr & DCSR_STEP) && !(env->dcsr & DCSR_STEPIE)) {
             return false;
-- 
2.53.0