@@ -25,6 +25,9 @@
#include "exec/cpu-interrupt.h"
#include "qemu/cpu-float.h"
#include "cpu-qom.h"
+#include "exec/cpu-defs.h"
+
+#define CPU_INTERRUPT_NMI CPU_INTERRUPT_TGT_EXT_1
#define OS_BYTE 0
#define OS_WORD 1
@@ -148,6 +151,7 @@ typedef struct CPUArchState {
int pending_vector;
int pending_level;
+ bool nmi_pending;
/* Fields up to this point are cleared by a CPU reset */
struct {} end_reset_fields;
@@ -949,6 +949,12 @@ void m68k_set_irq_level(M68kCPU *cpu, int level, uint8_t vector)
CPUState *cs = CPU(cpu);
CPUM68KState *env = &cpu->env;
+ if (level == 7 && env->pending_level != 7) {
+ env->nmi_pending = true;
+ } else if (level != 7) {
+ env->nmi_pending = false;
+ }
+
env->pending_level = level;
env->pending_vector = vector;
if (level) {
@@ -522,14 +522,12 @@ bool m68k_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
{
CPUM68KState *env = cpu_env(cs);
- if (interrupt_request & CPU_INTERRUPT_HARD
- && ((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) {
- /*
- * Real hardware gets the interrupt vector via an IACK cycle
- * at this point. Current emulated hardware doesn't rely on
- * this, so we provide/save the vector when the interrupt is
- * first signalled.
- */
+ if (env->nmi_pending) {
+ env->nmi_pending = false;
+ cs->exception_index = env->pending_vector;
+ do_interrupt_m68k_hardirq(env);
+ return true;
+ } else if (((env->sr & SR_I) >> SR_I_SHIFT) < env->pending_level) {
cs->exception_index = env->pending_vector;
do_interrupt_m68k_hardirq(env);
return true;
Why this change is made & How it will be used: Level 7 interrupts are Non-Maskable Interrupts (NMI) on the M68k architecture. The hardware asserts an NMI only on the rising edge of the level 7 signal. The current QEMU implementation treats level 7 like a standard level interrupt. This patch ensures proper NMI edge-triggered semantics for level 7, which is strictly required by the Sun-3 keyboard/mouse NMI routing logic. Impact on existing functionality: Corrects NMI edge-triggering for all M68k boards, adhering closely to the Motorola specifications. Existing boards will now correctly require an edge transition to trigger consecutive NMIs. Signed-off-by: 54weasels <54weasels@gmail.com> --- target/m68k/cpu.h | 4 ++++ target/m68k/helper.c | 6 ++++++ target/m68k/op_helper.c | 14 ++++++-------- 3 files changed, 16 insertions(+), 8 deletions(-)