KA630: how does console I/O actually work?
Mouse <[email protected]>
| Newsgroups | gmane.os.netbsd.ports.vax |
|---|---|
| Message-ID | <[email protected]> |
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 [email protected] / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B