From: Matt Porter <mporter@kernel.crashing.org>
To: David Hawkins <dwh@ovro.caltech.edu>
Cc: linuxppc-embedded@ozlabs.org, "Jenkins, Clive" <Clive.Jenkins@xerox.com>
Subject: Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
Date: Wed, 1 Feb 2006 10:44:05 -0700 [thread overview]
Message-ID: <20060201104405.C16064@cox.net> (raw)
In-Reply-To: <43E0E9A7.4040508@ovro.caltech.edu>; from dwh@ovro.caltech.edu on Wed, Feb 01, 2006 at 09:02:31AM -0800
On Wed, Feb 01, 2006 at 09:02:31AM -0800, David Hawkins wrote:
> Jenkins, Clive wrote:
> >>>>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
>
> 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?
Both
> 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).
Those regs are little endian since it's a PCI device. You
use the old read*/write* or new ioread*/iowrite* since it's
a PCI device.
> 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.
The book implicitly focuses on x86 driver developers, that's
why you don't get an explicit statement about this...
"everything" is PCI in that world.
read*/write* and ioread*/iowrite* generate outbound little
endian cycles on ALL arches, period. They are intended
only for PCI use and have generic names only because of
the assumption that "all the world is a PC".
Now, what it takes to to generate outbound little endian cycles
varies. On some arches, it's just a store (native LE) on
other arches, it's a reversed store (PPC), others still configure
their PCI bridge hardware to do byte swapping in hardware (typically
if their arch doesn't have a simple byte-swapping store like PPC).
The example you cite on pg. 453 of Rubini looks broken for BE
systems. It works on LE systems since cpu_to_le32() does nothing
and writel is a simply dereference. That's pure luck. On PPC,
for example, that would write a big endian bus_addr to the fictitious
PCI device which is not what they want.
-Matt
next prev parent reply other threads:[~2006-02-01 17:44 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-02-01 11:19 Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian? Jenkins, Clive
2006-02-01 17:02 ` David Hawkins
2006-02-01 17:44 ` Matt Porter [this message]
2006-02-01 17:53 ` David Hawkins
2006-02-01 18:04 ` David Hawkins
2006-02-01 18:11 ` Eugene Surovegin
2006-02-01 18:20 ` David Hawkins
2006-02-01 18:23 ` Eugene Surovegin
2006-02-01 21:14 ` Peter Korsgaard
2006-02-02 0:54 ` Kumar Gala
2006-02-02 3:07 ` Matt Porter
2006-02-02 8:09 ` Peter Korsgaard
2006-02-02 9:08 ` Eugene Surovegin
2006-02-02 17:34 ` Dale Farnsworth
2006-02-02 14:21 ` Matt Porter
-- strict thread matches above, loose matches on Subject: below --
2006-02-01 18:35 Jenkins, Clive
2006-02-01 20:35 ` David Hawkins
2006-02-02 9:35 Jenkins, Clive
2006-02-02 9:46 ` Eugene Surovegin
2006-02-02 14:37 ` Matt Porter
2006-02-02 17:45 ` Eugene Surovegin
2006-02-02 18:16 ` Matt Porter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060201104405.C16064@cox.net \
--to=mporter@kernel.crashing.org \
--cc=Clive.Jenkins@xerox.com \
--cc=dwh@ovro.caltech.edu \
--cc=linuxppc-embedded@ozlabs.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.