• Inmos B008 interrupts - do they work?

    From Tom Ivar Helbekkmo@21:1/5 to All on Sat Jun 19 20:38:54 2021
    Hi there!

    I'm new to the Transputer community, although I've wanted to play with
    them since I first read about them in 1986... :)

    I recently got hold of an original Inmos B008 ISA board, and four T800
    TRAM modules to mount on it. The host system is an old Pentium III
    machine running MINIX 3.4. I've written a B004 driver for MINIX, and it
    works fine - in polled mode:

    luna.hamartun.priv.no$ ./ispy
    Using /dev/link0 ispy 3.23
    # Part rate Link# [ Link0 Link1 Link2 Link3 ] by Andy!
    0 T805d-25 39k 0 [ HOST 1:1 3:1 ... ]
    1 T2 -20 959k 1 [ ... 0:1 ... C004 ]
    3 T800d-25 1.8M 1 [ ... 0:2 4:1 ... ]
    4 T805d-25 1.8M 1 [ ... 3:2 5:1 ... ]
    5 T800d-25 1.8M 1 [ ... 4:2 ... ... ]
    luna.hamartun.priv.no$

    The ispy running there is the one written in C by Andy Rabagliati; it
    was a clean drop-in to MINIX, with just a little bit of editing to fit
    the ioctl calls I have in my B004 driver.

    My problem is that I'd like to make use of the extended functionality of
    the B008 board. It supports delivering interrupts when the I/O channels
    are ready, instead of the driver having to poll for them, and it also
    supports DMA transfer. I've tried to extend my driver to be interrupt
    driven when the board is a B008, but I can't make the board actually
    generate any interrupts. I can't find any examples of interrupts being
    used, either, on the net.

    Am I barking up a dead tree here? Does anyone know if the interrupt
    driven mode even works as documented on the B008? Is there a quirk that
    I need to know about? Any help or hints would be appreciated!

    -tih
    --
    Most people who graduate with CS degrees don't understand the significance
    of Lisp. Lisp is the most important idea in computer science. --Alan Kay

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike B.@21:1/5 to All on Sun Jun 20 14:02:11 2021
    Hi Tom!

    You have to enable the interrupts twice. One time in the STATUS registers (C012) and once in the INT_ENABLE.

    #define STATUS_IN ( BOARD_BASE + 0x2 )
    #define STATUS_OUT ( BOARD_BASE + 0x3 )
    #define INT_ENABLE ( BOARD_BASE + 0x13 )

    0 T805d-25 39k 0 [ HOST 1:1 3:1 ... ]

    39k ... that's horrible slow. Check you ISA IO settings in the BIOS.

    Kind regards
    Mike

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Ivar Helbekkmo@21:1/5 to Mike B. on Mon Jun 21 08:44:23 2021
    "Mike B." <michael_bruestle@yahoo.com> writes:

    You have to enable the interrupts twice. One time in the STATUS
    registers (C012) and once in the INT_ENABLE.

    Thanks, Mike! I just tried that -- still no luck.

    Am I right in assuming that while the DMA interrupt enable bit will need
    to be turned off and on again by the driver in order to enable it for
    the next transaction, the input and output enables are automatically
    cleared by reading or writing a byte, so they just need to be re-enabled
    for the next round? This is what the manual seems to say, but I haven't
    found any text that's really clear on these points.

    Right now, following the "belt and suspenders" plan, this is what I do
    in the interrupt handler (plus another, similar, block for the receiving
    part, of course):

    if (wlink_busy && (wbuf_read_offset != wbuf_write_offset)) {
    sys_inb(B004_OSR, &b);
    if (b & B004_READY) {
    sys_outb(B004_OSR, B004_INT_DIS);
    b008_intmask &= ~B008_OUTINT_ENA;
    sys_outb(B008_INT, b008_intmask);
    sys_outb(B004_ODR, wlinkbuf[wbuf_read_offset++]);
    if (wbuf_read_offset == wbuf_write_offset) {
    wlink_busy = 0;
    } else {
    b008_intmask |= B008_OUTINT_ENA;
    sys_outb(B008_INT, b008_intmask);
    sys_outb(B004_OSR, B004_INT_ENA);
    }
    }
    }

    I check whether I'm currently writing, then whether the output is ready.
    If it is, I disable that interrupt (both ways), and write the next byte.
    If that wasn't the last one, I re-enable the interrupt.

    Actually, it just strikes me that doing things this way in MINIX may be
    too slow for interrupt-per-byte communication with the transputers. The sys_outb() calls use message passing through the microkernel between the
    driver and the kernel proper, and I may just be too slow re-enabling.
    Maybe do this polled, for now, ditch this part of the interrupt
    handling, and start experimenting with DMA, instead?

    Incidentally, is there a way for the driver to detect whether it's
    talking to a B004 or a B008? The interrupt control register is,
    according to the documentation for the older version of the B008 that I
    have, write only, which seems to leave nothing the driver can depend on.

    Maybe I can, just after the reset, when I know the output ready bit in
    the OSR is 1, compare what happens when I enable the interrupt in the
    OSR with and without the enabling bit in the B008 specific interrupt
    control register set? If the B008 specific bit turns out to make a
    difference, that must be the board I have... I'll give that a go.

    0 T805d-25 39k 0 [ HOST 1:1 3:1 ... ]

    39k ... that's horrible slow. Check you ISA IO settings in the BIOS.

    Yeah - I still have some usleep() delays in there that I probably don't
    need, and some debug output to console. I should get better speeds once
    I tidy up that stuff. Been too focused on figuring out interrupts... :)

    -tih
    --
    Most people who graduate with CS degrees don't understand the significance
    of Lisp. Lisp is the most important idea in computer science. --Alan Kay

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Mike B.@21:1/5 to All on Mon Jun 21 05:29:48 2021
    Hi Tom

    " I just tried that -- still no luck.

    After an Reset of the Root Transputer via +0x10 also the C012 will be reseted. (from http://transputer.net/mg/b008ug/b008ug.html)

    Reset initialises the IMS C012 to the following state: LinkOut is held low; the interrupt outputs InputInt
    and OutputInt are held low; interrupts are disabled; D0-7 are high impedance. (from http://transputer.net/ibooks/dsheets/c012.pdf)

    So after the reset has been deactivated AND an safety delay from 100ms (INMOS recommendation) I would enable both C012 interrupts only once and control the interrupts only via the B008 interrupt register.

    The C012 interrupt enable are not auto-reset in any other way.

    For a first approach I would leave the Error & DMA interrupt disabled.

    DMA Code sample can be found here http://transputer.net/mg/b008ug/b008ug.html (Appendix C). No clue if correct or useful.

    Incidentally, is there a way for the driver to detect whether it's
    talking to a B004 or a B008?

    I think an auto-detect is useless. There are many other similar cards in the field, so let the user specify it.
    Maybe (and this happens often) is a B008 used with only the C012 e.g. B004 parts for which reason ever.

    Trying to understand you code snippet ...

    I would stay in the loop (and read each available ready data) until an defined successive number (may be 1) of not ready are detected. After that I would enable the interrupt and continue in the ISR.
    All in combination with the number of requested bytes.

    Finally, it's may be possible to check the logic level of the OutputInt (as you said, which is 1 after reset) on the C012 with a simple logic tester and if that's ok also check the IRQ line.

    -Mike

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Tom Ivar Helbekkmo@21:1/5 to Mike B. on Mon Jun 21 16:09:15 2021
    "Mike B." <michael_bruestle@yahoo.com> writes:

    So after the reset has been deactivated AND an safety delay from 100ms
    (INMOS recommendation) I would enable both C012 interrupts only once
    and control the interrupts only via the B008 interrupt register.

    Sounds reasonable. I have code to do the "can I get the interrupt just
    by enabling on the C012, or do I have to enable on the B008 as well?"
    thing, to try to determine whether I'm talking to a B008, but since I
    can't get interrupts, other than this one that happens just after I give
    up, that hasn't led anywhere.

    Anyway, I see that I can get 200kB/s out of the link running polled,
    which is still slow, because I have to go two rounds of message passing
    to the kernel and back for each byte transfered. I think I'll ignore
    the C012 interrupts for now, and start looking into DMA instead. I want
    to run Helios on this board, and I'll want all the bandwidth I can get
    toward the host's file system. :)

    DMA Code sample can be found here
    http://transputer.net/mg/b008ug/b008ug.html (Appendix C). No clue if
    correct or useful.

    Thanks - and thanks for the other links, too!

    -tih
    --
    Most people who graduate with CS degrees don't understand the significance
    of Lisp. Lisp is the most important idea in computer science. --Alan Kay

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)