NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: port-emips/45080 (emips GENERIC kernel doesn't boot)
The following reply was made to PR port-emips/45080; it has been noted by GNATS.
From: Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: tsutsui%ceres.dti.ne.jp@localhost
Subject: Re: port-emips/45080 (emips GENERIC kernel doesn't boot)
Date: Wed, 11 Dec 2019 00:41:01 +0900
Now I've checked the Giano simulator implementation, then
it turns out eMIPS CPU core simulated by Giano updates interrupt
register bits in the CAUSE register only when the interrupt
(exception) is triggered. This is the reason why checking
CAUSE register via splintr() in a while loop (to check if
another interrupt is triggered during interrupt) doesn't
work as expected on Giano.
I guess the author of the Giano simulator choose this design
because MIPS R4000 Microprocessor User's Manual says
"Cause register describes the cause of the most recent exception"
in the "Cause Register (13)" section. However I don't think it is
correct because the manual also says "bits in the interrupt register
are directly readable as bits of the Cause register", in section
15.3 "Asserting Interrupt".
I don't know whether the real FPGA eMIPS has the same design
as the Giano simulator , but for now I'd like to choose
'call only one handler per each interrupt' strategy, as
the original NetBSD/emips implementation. (It also just works)
Comments?
---
Index: emips/interrupt.c
===================================================================
RCS file: /cvsroot/src/sys/arch/emips/emips/interrupt.c,v
retrieving revision 1.7
diff -u -p -d -r1.7 interrupt.c
--- emips/interrupt.c 9 Dec 2019 16:19:11 -0000 1.7
+++ emips/interrupt.c 10 Dec 2019 15:30:45 -0000
@@ -102,6 +102,19 @@ cpu_intr(int ppl, vaddr_t pc, uint32_t s
curcpu()->ci_data.cpu_nintr++;
+#if 0
+ /*
+ * According to Giano simulator sources (Cpus/mips_cpu.cpp),
+ * interrupt register bits in CAUSE register are updated
+ * only when the exception is triggered. This means checking
+ * CAUSE register via splintr() in a while loop in this
+ * interrupt handler doesn't work as expected on Giano.
+ *
+ * I don't know whether the real FPGA eMIPS has the same
+ * design as the Giano simulator, but for now I'd like to
+ * choose 'call only one handler per each interrupt' strategy,
+ * as the original NetBSD/emips implementation.
+ */
while (ppl < (ipl = splintr(&ipending))) {
splx(ipl);
/* device interrupts */
@@ -110,6 +123,14 @@ cpu_intr(int ppl, vaddr_t pc, uint32_t s
}
(void)splhigh();
}
+#else
+ ipl = splintr(&ipending);
+ __USE(ipl);
+ /* device interrupts */
+ if (ipending & MIPS_INT_MASK_5) {
+ (*platform.iointr)(status, pc, ipending);
+ }
+#endif
}
/*
---
Izumi Tsutsui
Home |
Main Index |
Thread Index |
Old Index