Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Sebastian Huber <sebastian.huber@embedded-brains.de>
To: gdb-patches@sourceware.org
Cc: "Maciej W . Rozycki" <macro@orcam.me.uk>,
	Andrew Burgess <aburgess@redhat.com>
Subject: [PATCH v2 6/6] sim/mips: Recognise a software interrupt request
Date: Fri, 21 Aug 2026 05:23:04 +0200	[thread overview]
Message-ID: <20260821032304.293603-7-sebastian.huber@embedded-brains.de> (raw)
In-Reply-To: <20260821032304.293603-1-sebastian.huber@embedded-brains.de>

The simulator ignored the Cause.IP0 and Cause.IP1 software generated
interrupts of the MIPS Architecture For Programmers Volume III: The
MIPS Privileged Resource Architecture.  A client which requested one
got no exception.

Check the request wherever an instruction enables the interrupts or
writes a pending bit.  These places are the writes to the Status and
Cause registers, ERET, RFE and EI.  Deliver the interrupt through the
event queue and not in place, because signal_exception() leaves the
handler address in the program counter for an interrupt.  The
simulator would overwrite it with the result of the current
instruction.
---
 sim/mips/interp.c        | 51 ++++++++++++++++++++++++++++++++++++++--
 sim/mips/micromips.igen  |  1 +
 sim/mips/mips.igen       |  1 +
 sim/mips/mips3264r2.igen |  1 +
 sim/mips/sim-main.h      |  2 ++
 5 files changed, 54 insertions(+), 2 deletions(-)

diff --git a/sim/mips/interp.c b/sim/mips/interp.c
index 8118b290a17..4a461879804 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -321,6 +321,46 @@ interrupts_enabled (sim_cpu *cpu)
   return (Debug & Debug_DM) == 0;
 }
 
+/* A software interrupt is requested while the interrupts are enabled and a
+   software interrupt pending bit of the Cause register meets its mask bit in
+   the Status register.  The Cause.IP bits meet the Status.IM bits.  See the
+   MIPS Architecture For Programmers Volume III: The MIPS Privileged Resource
+   Architecture, the Interrupts chapter.  */
+static int
+software_interrupt_requested (sim_cpu *cpu)
+{
+  if (!interrupts_enabled (cpu))
+    return 0;
+
+  /* Only the software interrupts.  A hardware interrupt keeps its pending bit
+     set until its device is served.  The device model delivers it.  */
+  return (CAUSE & SR & (cause_SW1 | cause_SW0)) != 0;
+}
+
+static void
+software_interrupt_event (SIM_DESC sd, void *data)
+{
+  sim_cpu *cpu = STATE_CPU (sd, 0);
+  address_word cia = CPU_PC_GET (cpu);
+
+  /* Check again, because the write which scheduled this event may have been
+     undone in the meantime.  */
+  if (software_interrupt_requested (cpu))
+    SignalExceptionInterrupt (0);
+}
+
+/* Deliver a requested software interrupt at the next instruction boundary.
+   The delivery cannot happen here: signal_exception() leaves the handler
+   address in the program counter for an interrupt and the instruction which
+   the simulator executes would overwrite it.  This is why the hardware
+   interrupts arrive through the event queue as well.  */
+void
+check_software_interrupts (SIM_DESC sd, sim_cpu *cpu)
+{
+  if (software_interrupt_requested (cpu))
+    sim_events_schedule (sd, 1, software_interrupt_event, NULL);
+}
+
 void
 interrupt_event (SIM_DESC sd, void *data)
 {
@@ -2295,14 +2335,20 @@ decode_coproc (SIM_DESC sd,
 		if (op == cp0_mfc0 || op == cp0_dmfc0)
 		  GPR[rt] = SR;
 		else
-		  SR = GPR[rt];
+		  {
+		    SR = GPR[rt];
+		    check_software_interrupts (sd, cpu);
+		  }
 		break;
 		/* 13 = Cause              R4000   VR4100  VR4300 */
 	      case 13:
 		if (op == cp0_mfc0 || op == cp0_dmfc0)
 		  GPR[rt] = CAUSE;
 		else
-		  CAUSE = GPR[rt];
+		  {
+		    CAUSE = GPR[rt];
+		    check_software_interrupts (sd, cpu);
+		  }
 		break;
 		/* 14 = EPC                R4000   VR4100  VR4300 */
 	      case 14:
@@ -2427,6 +2473,7 @@ decode_coproc (SIM_DESC sd,
 
 	    /* shift IE/KU history bits right */
 	    SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
+	    check_software_interrupts (sd, cpu);
 
 	    /* TODO: CACHE register */
 #endif /* SUBTARGET_R3900 */
diff --git a/sim/mips/micromips.igen b/sim/mips/micromips.igen
index 8bb48cac1e4..2149aee352f 100644
--- a/sim/mips/micromips.igen
+++ b/sim/mips/micromips.igen
@@ -995,6 +995,7 @@
       NIA = EPC;
       SR &= ~status_EXL;
     }
+  check_software_interrupts (SD, CPU);
 }
 
 
diff --git a/sim/mips/mips.igen b/sim/mips/mips.igen
index 3b52f2df43f..4becc3da31e 100644
--- a/sim/mips/mips.igen
+++ b/sim/mips/mips.igen
@@ -6715,6 +6715,7 @@
       NIA = EPC;
       SR &= ~status_EXL;
     }
+  check_software_interrupts (SD, CPU);
 }
 
 
diff --git a/sim/mips/mips3264r2.igen b/sim/mips/mips3264r2.igen
index 67598e84433..2864d9b77de 100644
--- a/sim/mips/mips3264r2.igen
+++ b/sim/mips/mips3264r2.igen
@@ -94,6 +94,7 @@
   TRACE_ALU_INPUT0 ();
   GPR[rt] = EXTEND32 (SR);
   SR |= status_IE;
+  check_software_interrupts (SD, CPU);
   TRACE_ALU_RESULT1 (GPR[rt]);
 }
 
diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h
index 28a4221dfd5..73a3f9c992b 100644
--- a/sim/mips/sim-main.h
+++ b/sim/mips/sim-main.h
@@ -655,6 +655,8 @@ enum ExceptionCause {
 
 void interrupt_event (SIM_DESC sd, void *data);
 
+void check_software_interrupts (SIM_DESC sd, sim_cpu *cpu);
+
 void signal_exception (SIM_DESC sd, sim_cpu *cpu, address_word cia, int exception, ...);
 #define SignalException(exc,instruction)     signal_exception (SD, CPU, cia, (exc), (instruction))
 #define SignalExceptionInterrupt(level)      signal_exception (SD, CPU, cia, Interrupt, level)
-- 
2.51.0


      parent reply	other threads:[~2026-08-21  3:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-21  3:22 [PATCH v2 0/6] sim: Fix MIPS livelocks and add software interrupts Sebastian Huber
2026-08-21  3:22 ` [PATCH v2 1/6] sim: Allow an overdue event to be descheduled Sebastian Huber
2026-08-21  3:23 ` [PATCH v2 2/6] sim/mips: Do not abort on a HI/LO hazard Sebastian Huber
2026-08-21  3:23 ` [PATCH v2 3/6] sim/mips: Deliver the reserved instruction exception Sebastian Huber
2026-08-21  3:23 ` [PATCH v2 4/6] sim/mips: Check all interrupt enable conditions Sebastian Huber
2026-08-21  3:23 ` [PATCH v2 5/6] sim/mips: Keep the pending interrupts in Cause Sebastian Huber
2026-08-21  3:23 ` Sebastian Huber [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260821032304.293603-7-sebastian.huber@embedded-brains.de \
    --to=sebastian.huber@embedded-brains.de \
    --cc=aburgess@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=macro@orcam.me.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox