Re: How to write portable MMIO code?

Kai Germaschewski (kai@tp1.ruhr-uni-bochum.de)
Tue, 30 Apr 2002 14:41:56 -0500 (CDT)


On Tue, 30 Apr 2002, José Fonseca wrote:

> Unfortunately one of the problems occurs in a idle wait loop, when a
> register is being sucessively read.

Hmmh, suppose you have different problem (most likely elsewhere) then.

> And if so, how the wmb() example in "Linux Device Drivers"
> (http://www.xml.com/ldd/chapter/book/ch08.html#t1) can be explained? The
> "Bus-Independent Device Accesses"
> (http://www.kernelnewbies.org/documents/kdoc/deviceiobook/x44.html) also
> refers what you suggested, but it also mentions the use of memory
> barriers. So how and when should they be used?

Well, my understanding is the following: (if I get something wrong,
hopefully somebody who's reading this will correct me)

the barrier(), {,r,w}mb() stuff is for actually for normal memory
accesses.

About barrier():

If you have

*p1 = 1; *p2 = 2;

the compiler may decide to reorder this to (if it knows that p1 != p2)

*p2 = 2; *p1 = 1;

A barrier() in between will inhibit this reordering.

For some archs, even the barrier() is not sufficient to serialize the
accesses to RAM. The compiler may generate something like

mov [p1], 1
mov [p2], 2

but on e.g. alpha (where the asm would look differently ;-), the processor
may decide to put the second instruction on the memory bus before the
first one. Only an mb in between will guarantee the ordering on the
memory bus.

Now, for IO, basically the same holds, though I wouldn't want to guarantee
that the macros designed for the memory bus would work on the PCI bus as
expected.

However, I do *believe*, that the readl/writel functions implicitly do the
right thing and introduce barriers where needed. On x86 e.g., the macros
do a cast to (volatile *), which will ensure that these functions are
compiled without reordering. As x86 is strongly ordered, no additional
mb() or whatever is necessary (nor does it exist) to make sure that this
ordering will propagate to the PCI bus.

There's definitely people here who know that stuff better than I do,
though.

--Kai

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/