PCI endianess

Todd Inglett tinglett at vnet.ibm.com
Thu Sep 5 00:43:04 EST 2002


On Wed, 2002-09-04 at 03:00, Anil K Prasad wrote:
>
> >Do you mean this happens without conversion (e.g. read/write{bwl]) ?
> >Then it is exactly what I need.
> >If I do on my big endian machine:
> > unsigned short val = 0x1234;
> > x->command = val;
> you must do something like this:
>
> out_le16(x->command, val); for 16 bit data
> and out_le32 for 32 bit data.
>
> Using these out_le16/32 will ensure portability across different endian
> platforms.

You want to use the read/write macros that you get when you include
<asm/io.h>.  You don't need to specify the "le" macros because PCI by
definition is little endian.  Therefore you will find that on big endian
machines the macros will byteswap for you.  Thus:

val = readb(addr) will read an 8-bit value
val = readw(addr) will read a 16-bit value (with implied byte swap)
val = readl(addr) will read a 32-bit value (with implied byte swap)

likewise:

writeb(val, addr), writew(val,addr) and writel(val, addr) will write 8,
16 and 32 bit values respectively and they will do the byte swap for
you.

If you want to copy/clear ranges of bytes note also the memset_io,
memcpy_fromio and memcpy_toio macros (these don't do swapping -- they
work at the byte level).

The "addr" for these macros is always an address within a range you got
when you ioremap a particular memory BAR of your PCI adapter.  If you
are using an I/O BAR use the inb, inw, inl, outb, outw or outl macros
instead.

One final point:  an important reason not to write your own variations
of these accessor functions is that you don't know what is required for
access for each individual architecture.  On ppc64 there are barrier
instructions that must be executed for these operations to succeed
correctly.  If "Enhanced Error Handling" is enabled (true under a
hypervisor at least) the "addresses" returned by ioremap are actually
token values that are trivially translated by the io macros.  You don't
want to try to replicate that in your driver.

-todd


** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list