RE: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?

2 messages, 2 authors, 2006-02-01 · open the first message on its own page

RE: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?

From: Jenkins, Clive <hidden>
Date: 2006-02-01 11:28:16

quoted
quoted
readl() and ioread32() read the registers in little-endian format!
Correct. That's how it is implemented on all platforms. Think for
example of an pci device driver. Using these IO functions, the
driver will become platform independent, running without
modifications on little- and big-endian machines.
I just stumbled across the section in Rubini 3rd Ed that mislead
me into believing that the readl()/writel() were machine endianness
dependent, i.e., LE on x86, BE on PPC.
p453 of his book has a PCI DMA example, where he uses the
cpu_to_le32() macros inside calls writel().
However, since these functions are internally implemented to
perform LE operations, this example appears to be incorrect.
Would you agree?
No, I think it is correct.

On most architectures readl() and writel() assume you are
accessing MMIO on the PCI bus, which is little-endian.
So these macros convert between the endian-ness of the CPU
and the endian-ness of the PCI bus.

Clive

Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?

From: David Hawkins <hidden>
Date: 2006-02-01 17:00:37

Jenkins, Clive wrote:
quoted
quoted
quoted
readl() and ioread32() read the registers in little-endian format!
Correct. That's how it is implemented on all platforms. Think for
example of an pci device driver. Using these IO functions, the
driver will become platform independent, running without
modifications on little- and big-endian machines.
I just stumbled across the section in Rubini 3rd Ed that mislead
me into believing that the readl()/writel() were machine endianness
dependent, i.e., LE on x86, BE on PPC.
quoted
p453 of his book has a PCI DMA example, where he uses the
cpu_to_le32() macros inside calls writel().
quoted
However, since these functions are internally implemented to
perform LE operations, this example appears to be incorrect.
quoted
Would you agree?

No, I think it is correct.

On most architectures readl() and writel() assume you are
accessing MMIO on the PCI bus, which is little-endian.
So these macros convert between the endian-ness of the CPU
and the endian-ness of the PCI bus.

Clive
Hey Clive,

Right, but in the 440EP source, and probably on other PowerPC
ports, readl() and writel() perform the endian conversion for
you, so if you wrote an operation as

   writel(register_address, cpu_to_le32(data));

you would get *two* little endian conversions, i.e., you
would write the bytes in the wrong order.

I haven't looked in the source for other big-endian architecures
yet. I wonder if the ARM stuff is big, or little endian?

The original question came about while I was trying to read
back PLX-9054 registers (a PCI-to-local bus bridge on a PCI
adapter board).

I search through the other drivers for the 440EP peripherals
that are not on the PCI bus showed that the authors used
the in_be32() and out_be32() calls. The comment at the top
of this email indicates that the readl() and writel() are
effectively 'reserved' for PCI accesses. I didn't get this
impression from reading Rubini.

Thanks for you comments. Feel free to add more comments!

Cheers
Dave
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help