From: Sebastian Huber <sebastian.huber@embedded-brains.de>
To: gdb-patches@sourceware.org
Subject: [PATCH 4/4] sim/mips: Recognise a software interrupt request
Date: Mon, 17 Aug 2026 01:43:56 +0200 [thread overview]
Message-ID: <20260816234357.278358-5-sebastian.huber@embedded-brains.de> (raw)
In-Reply-To: <20260816234357.278358-1-sebastian.huber@embedded-brains.de>
Add support for the Cause.IP0 and Cause.IP1 software generated
interrupts defined by the MIPS Architecture For Programmers Volume III:
The MIPS Privileged Resource Architecture.
Deliver it from the event queue rather than in place, because
signal_exception() leaves the handler address in the program counter for
an interrupt and the instruction being executed would overwrite it.
Signed-off-by: Sebastian Huber <sebastian.huber@embedded-brains.de>
---
sim/mips/interp.c | 64 +++++++++++++++++++++++++++++++++++++++++++--
sim/mips/sim-main.h | 2 ++
2 files changed, 64 insertions(+), 2 deletions(-)
diff --git a/sim/mips/interp.c b/sim/mips/interp.c
index 5dbd1482b99..fddb96d00ed 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -295,6 +295,58 @@ static const OPTION mips_options[] =
int interrupt_pending;
+/* An interrupt is requested while the interrupts are enabled and a pending
+ bit of the Cause register meets its mask bit in the Status register:
+
+ Status.IE = 1, Status.EXL = 0, Status.ERL = 0, Cause.IP & Status.IM != 0
+
+ MIPS Architecture For Programmers Volume III: The MIPS Privileged Resource
+ Architecture, the Interrupts chapter. The R3000 generation, which the
+ R3900 belongs to, has no exception level and disables the interrupts by
+ shifting the interrupt enable stack of its Status register instead, so only
+ the current enable takes part; see the IDT R30xx Family Software Reference
+ Manual, the Status register of the CPU control chapter. */
+static int
+interrupt_requested (sim_cpu *cpu)
+{
+ if ((SR & status_IE) == 0)
+ return 0;
+
+#ifndef SUBTARGET_R3900
+ if ((SR & (status_EXL | status_ERL)) != 0)
+ return 0;
+#endif
+
+ /* Only the software interrupts. A hardware interrupt keeps its pending bit
+ set until its device is served. The device model delivers it. */
+ return ((CAUSE >> cause_IPSW_shift) & (SR >> status_IM_shift)
+ & cause_IPSW_mask) != 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);
+
+ /* Recheck, because the write which scheduled this may have been undone in
+ the meantime. */
+ if (interrupt_requested (cpu))
+ SignalExceptionInterrupt (0);
+}
+
+/* Deliver a pending interrupt at the next instruction boundary. It cannot be
+ delivered here: signal_exception() leaves the handler address in the program
+ counter for an interrupt and the instruction which is being executed would
+ overwrite it. This is why the hardware interrupts arrive through the event
+ queue as well. */
+static void
+check_interrupts (SIM_DESC sd, sim_cpu *cpu)
+{
+ if (interrupt_requested (cpu))
+ sim_events_schedule (sd, 1, software_interrupt_event, NULL);
+}
+
void
interrupt_event (SIM_DESC sd, void *data)
{
@@ -2269,14 +2321,20 @@ decode_coproc (SIM_DESC sd,
if (op == cp0_mfc0 || op == cp0_dmfc0)
GPR[rt] = SR;
else
- SR = GPR[rt];
+ {
+ SR = GPR[rt];
+ check_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_interrupts (sd, cpu);
+ }
break;
/* 14 = EPC R4000 VR4100 VR4300 */
case 14:
@@ -2391,6 +2449,7 @@ decode_coproc (SIM_DESC sd,
{
PC = EPC;
SR &= ~status_EXL;
+ check_interrupts (sd, cpu);
}
}
else if (op == cp0_rfe && sel == 0x10)
@@ -2401,6 +2460,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_interrupts (sd, cpu);
/* TODO: CACHE register */
#endif /* SUBTARGET_R3900 */
diff --git a/sim/mips/sim-main.h b/sim/mips/sim-main.h
index b6cb4e12258..3af02e49c0e 100644
--- a/sim/mips/sim-main.h
+++ b/sim/mips/sim-main.h
@@ -557,6 +557,8 @@ struct mips_sim_state {
#define cause_SW1 (1 << 9) /* Software interrupt 1 */
#define cause_IP_mask (0x3f) /* Interrupt pending field */
#define cause_IP_shift (10)
+#define cause_IPSW_mask (0x3) /* Software interrupt pending, IP1:IP0 */
+#define cause_IPSW_shift (8)
#define cause_set_EXC(x) CAUSE = (CAUSE & ~cause_EXC_mask) | ((x << cause_EXC_shift) & cause_EXC_mask)
#define cause_set_EXC2(x) CAUSE = (CAUSE & ~cause_EXC2_mask) | ((x << cause_EXC2_shift) & cause_EXC2_mask)
--
2.51.0
next prev parent reply other threads:[~2026-08-16 23:44 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-16 23:43 [PATCH 0/4] Fix some MIPS GDB simulator issues Sebastian Huber
2026-08-16 23:43 ` [PATCH 1/4] sim: Allow an overdue event to be descheduled Sebastian Huber
2026-08-18 9:59 ` Andrew Burgess
2026-08-16 23:43 ` [PATCH 2/4] sim/mips: Do not abort on a HI/LO hazard Sebastian Huber
2026-08-18 10:04 ` Andrew Burgess
2026-08-16 23:43 ` [PATCH 3/4] sim/mips: Deliver the reserved instruction exception Sebastian Huber
2026-08-18 10:18 ` Andrew Burgess
2026-08-16 23:43 ` Sebastian Huber [this message]
2026-08-18 10:42 ` [PATCH 4/4] sim/mips: Recognise a software interrupt request Andrew Burgess
2026-08-18 11:45 ` Sebastian Huber
2026-08-19 0:03 ` Maciej W. Rozycki
2026-08-19 0:27 ` Sebastian Huber
2026-08-19 13:17 ` Maciej W. Rozycki
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=20260816234357.278358-5-sebastian.huber@embedded-brains.de \
--to=sebastian.huber@embedded-brains.de \
--cc=gdb-patches@sourceware.org \
/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