Serializing memory with respect to IN/OUT
Mouse <[email protected]>
| Newsgroups | gmane.os.netbsd.ports.i386,gmane.os.netbsd.ports.x86-64 |
|---|---|
| Message-ID | <[email protected]> |
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 [email protected] / \ Email! 7D C8 61 52 5D E7 2D 39 4E F1 31 3E E8 B3 27 4B