Index | Thread | Search

From:
Geoff Steckel <gwes@oat.com>
Subject:
dev/ic/com.c - forcing a read of a device register
To:
tech <tech@openbsd.org>
Date:
Fri, 26 Dec 2025 16:36:42 -0500

Download raw body.

Thread
What is the accepted idiom used to force the compiler to
not optimize out a register read when the value is discarded?
My hope was that bus_space_read_N() would never be optimized out.

I'm trying to add a NetMos 9912 serial chip.
It purports to emulate a NS16650
It has (at least) two bugs.

a) clearing the input FIFO does not clear the "data available" bit if
    it was set before enabling the FIFO

I'll submit a separate patch for it and issues surrounding that.

b) the chip in question does not signal a subsequent output done
    interrupt unless the LSR is read twice at the entry to comintr()
    Only the first two characters are output.

comintr(void *arg)
{
         struct com_softc *sc = arg;
         struct tty *tp;
         u_char lsr, data, msr, delta;

         if (!sc->sc_tty)
                 return (0);             /* Can't do squat. */
-----> code inserted here <----
         if (ISSET(com_read_reg(sc, com_iir), IIR_NOPEND))
                 return (0);

Adding this works - the contents of lsr read back as 0!!

     printf("comintr %p lsr %x\n", sc, com_read_reg(sc, com_lsr));

A subsequent read in the following loop returns sensible data.

This doesn't work because the com_read_reg() is optimized out.

     (void) com_read_reg(sc, com_lsr);
printf("comintr %p\n", sc);

I assume that the printf() is just a way to force the register read
and the code will work without that function call.
I also assume that the added register read will not cause other
chips to fail. I hope - serial I/O is full of gotchas.

Once I have the proper code idiom I'll submit a patch and
ask for torture-testing it on other ICs.
The NetMos/ASIX chip is common on inexpensive add-in pci cards.

    thanks
    Geoff Steckel