Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Serializing memory with respect to IN/OUT



Thanks to some bare-metal code I'm trying to write, I've got myself
wondering about something NetBSD doesn't seem to have trouble with -
and I can't see why not.  Perhaps I'm just exposing my ignorance here;
if so, perhaps some kind soul will help alleviate that ignorance.

Specifically, let's consider (say) an rtk interface behind PCI.  Let's
suppose it's one of the ones that provides both I/O and memory space
views of the chip's registers.  The driver - at least the driver code
I've found - will prefer I/O space, using IN and OUT instructions to
access chip registers.

But then, I'm puzzled how serialization is achieved.  The packet gets
stored into a DMAable memory buffer, and needs to be pushed far enough
out that the chip's DMA accesses will see it before the register write
that starts DMA reaches the chip.

i386 seems to use "lock addl #0, -4(%esp)".  What I've found so far
says that just makes the add's RMW operation atomic; it doesn't
guarantee anything about ordering previous stores with respect to later
IN/OUT operations.

amd64 seems to use LFENCE, SFENCE, and MFENCE, which look even dodgier;
they appear to be specifically just _memory_ barriers, and IN and OUT
aren't memory accesses.

But the code appears to work in practice.  So I'm clearly missing
something.  Have I just not found enough documentation to understand
all the effects of LOCK or the xFENCE instructions, or are IN and OUT
serialized as if they were memory accesses, or do things just delay
long enough that everything happens to get pushed in practice, or what?

/~\ 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


Home | Main Index | Thread Index | Old Index