Re: KA630: how does console I/O actually work?

Johnny Billquist <[email protected]>
Newsgroups gmane.os.netbsd.ports.vax
Message-ID <[email protected]>
On 2023-12-26 19:41, Mouse wrote:
>>>>                                   at IPL 14 (hex).  That is, an  interrupt  is
>>>>                                   requested  whenever  the function {interrupt
>>>>                                   enable AND ready} changes from 0 to 1.
>>> I don't, however, see any language implying that the interrupt
>>> request is - or isn't - rescinded if DONE or IE is cleared before
>>> the interrupt is taken.  I don't rescind them.  simh does.  NetBSD
>>> seems to tolerate either (not surprising).
>> Well, this whole thread started because you noted that NetBSD does in
>> fact not tolerate your implementation under some circumstances...
> 
> There are at least three versions of "[my] implementation" under
> discussion here: (1) a pure level-triggered version; (2) an
> edge-triggered version which (2a) doesn't or (2b) does clear the
> request state bit on I/O reset.  We can, for sake of discussion, add
> (3) which is just like (2b) except that it clears any untaken interrupt
> request if the RDY&IE function drops to 0.
> 
> (1) goes into a TX interrupt livelock once NetBSD finishes autoconf and
> goes to userland.
> 
> (2a) works in most circumstances, but fails when rebooting after halt.
> 
> (2b) works in every test case I've tried so far.
> 
> (3) is what simh does, I think; the code I have makes it look that way
> to me, at least.  None of my versions do this.
> 
> I first implemented version 1, ran into the livelock, and turned it
> into version 2a.  Back at the beginning of this thread, I dug into the
> issue, determined what was behind the crash, and created version 2b.
> That's what prompted my post.

Right.

> At this point, I'm moderately sure the TX hardware acts edge-triggered
> in that taking the interrupt clears the interrupt request even if RDY
> and IE are both still set.  simh acts level-triggered in that clearing
> RDY or IE will withdraw any pending (ie, not yet taken) interrupt
> request; my code is pure edge-triggered, in that a pending interrupt
> request cannot be withdrawn except by taking the interrupt or doing an
> I/O reset.  NetBSD and the ROMs appear to be tolerant of both 2b and 3.

I would agree. But I also think that the documentation seems to support 3.

> The VARM contains language implying each way, thus arguing that simh's
> model is more accurate.  Real hardware clearly has at least one bit of
> state (for TX; we don't have any particular evidence either way for RX,
> at least not based on what I've seen here), so the simplest hardware
> implementation would be pure edge-triggered - to clear the state bit
> when RDY&IE drops would probably mean additional circuitry.

I do think simh is more accurate. However, I have yet not found any 
source for how this should be implemented. But it must be as you say 
that when the interrupt is taken, it will not be taken again unless 
there is some kind of retrigger.

As for easier to implement in hardware - well, I think that's really 
hard to tell. In general level based interrupts are simpler to do, but 
it's obvious (I think) that the interface for this one is more 
complicated. Exactly how, and where, that complexity is, I have no clue.

What we do know is that anything on the Qbus *have* to be level 
triggered. Otherwise it wouldn't work. But the console isn't on the Qbus...

> But those arguments are relatively weak.  That's why I'm trying to find
> out whether simh's code or mine is a more accurate model of the
> hardware: is it pure edge-triggered, or is it a mashup, edge-triggered
> in some respects and level-triggered in others?

Since I totally fail to find any details in any documentation I read, I 
guess the best source is simh.

(And I should point out that the machine I know the best - the 86x0, 
works very different here, and is much more reasonable, but it looks 
like that is the odd machine out here...)

So, as far as I can tell, simh works this way:

There is an interrupt pending flip flip.

It get set when a transmit completes (DONE is set), if IE is already 
enabled.
It get set when IE is enabled, and DONE is already set.
It get cleared if the TXDB is loaded.
It get cleared if IE is disabled.

All of these are clearly documented.
In addition, writing to BIR will clear RXIE and TXIE, as well as setting 
TXDONE and clearing RXDONE, so in effect that will also clear the 
interrupt flip flop (also documented).

Now, simh have one more, which I cannot find any documentation for, and 
which is the crucial bit here.

The interrupt pending flip flop is also cleared at interrupt acknowledge.

And the flip flop is only changed when any register change happens. So 
in that sense, it is sortof like edge triggered. But at the same time, 
it is not really, as the interrupt flip flop will only remain set if the 
conditions remain. If you turn off the IE for TX, the interrupt flip 
flop will immediately clear. No matter if the CPU have picked up the 
interrupt or not.

How this is implemented in the hardware, I don't know. Maybe they have 
an additional interrupt pending which does all the above, or maybe they 
have an interrupt blocked, which is cleared if the interrupt request 
goes away. I haven't found any way to tell.

   Johnny

-- 
Johnny Billquist                  || "I'm on a bus
                                   ||  on a psychedelic trip
email: [email protected]             ||  Reading murder books
pdp is alive!                     ||  tryin' to stay hip" - B. Idol
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.