For some time now, I've known my KA630 emulator has a bug somewhere.
I've managed to make the symptom go away; I'm wondering if anyone here
knows enough details of the KA630 console implementation to help me
figure out whether my fix is the right one.
If (pre-"fix") I boot, then halt, then boot again, all within the same
emulator run, the second boot panics early in startup:
NetBSD 1.4T (UVAXII) #1: Sun Dec 24 22:00:33 EST 2023
mouse@:/root/kbuild/UVAXII
MicroVAX II
total memory = 16372 KB
panic: ptelen fault in system space: addr 6c pc 80018730
panic: ptelen fault in system space: addr 70 pc 8001878a
Stopped in at _arithflt+0x22a: movl $5, r0
db>
Today I dug more. It turns out that this is an artifact of how I'm
handling console receive interrupts.
I wrote a comment
/*
* Console SLU.
*
* According to EK-KA630-UG-001:
*
* RXCS_ACT is set at the middle of the start bit and cleared at the
* (expected) middle of the stop bit. RXCS_DONE is set one bit time
* after RXCS_ACT clears. RXCS_IE is the interrupt enable it looks
* like; its interrupt condition is "RXCS_DONE is set".
[...]
* The info above (apparently from EK-KA630-UG-001) is at least
* partially false. The IE bits in RXCS and TXCS are not enables
* for level-triggered interrupts; rather, the interrupts are
* edge-triggered, interrupting whenever the function "IE & DONE"
* (RXCS) or "IE & RDY" (TXCS) changes from 0 to 1. This comes from
* the VARM and also seems to be how NetBSD's kernel treats it.
* This is why cons_intr exists: to record these interrupt requests.
[...]
*/
The cons_intr mentioned above records whether the edge-triggered
interrupt described is pending.
However, it appears that the crashes I'm seeing arise from this
sequence of events:
- NetBSD boots and starts using console interrupts.
- User halts NetBSD. IE is still set in RXCS.
- User types "b dua0" to the ROM >>> prompt.
- Receiving the b causes DONE to be set in RXCS, meaning RXCS&IE goes
from 0 to 1. This sets "RX interrupt wanted" in cons_intr. No
interrupt happens because the CPU is doing polled I/O in the ROM
code, running at or above IPL 0x14 the whole time.
- Boot sequence happens. Kernel loads.
- Kernel finally drops IPL below 0x14 (to 0, as it happens).
- Console RX interrupt, pending all this time, happens.
- Kernel is not ready for interrupt yet and falls over as a result.
Obviously, something is wrong in the emulation. Hence, I'm wondering
if anyone knows enough of the KA630 console's details to help me figure
out what I've got wrong. Is my paradigm (edge-triggered interrupts)
wrong? Is RXCS initialized during halt? Something else?
I had a look at simh, and, while I'm very far from sure I understand
the relevant code, it looks to me as though it's doing edge-triggered
much the way I am, but clearing the pending-interrupt bits as part of
Qbus resets, even though the console is not a Qbus device, because it
uses the same array of "interrupt wanted" values it uses for Qbus
interrupts. Pages 4-45 and 4-46 of EK-KA630-UG-001 contain ambiguous
language, discussing SLU interrupts with Qbus interrupts, but not
clearly stating whether Qbus resets clear pending SLU interrupts. Is
clearing pending interrupts on Qbus reset the right thing here? Doing
that does make the symptom go away, but it's far from clear to me that
it's the correct fix.
/~\ The ASCII Mouse
\ / Ribbon Campaign
X Against HTML mouse%rodents-montreal.org@localhost
/ \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B