linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* RE: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
@ 2006-02-01 11:19 Jenkins, Clive
  2006-02-01 17:02 ` David Hawkins
  0 siblings, 1 reply; 22+ messages in thread
From: Jenkins, Clive @ 2006-02-01 11:19 UTC (permalink / raw)
  To: David Hawkins, Stefan Roese; +Cc: linuxppc-embedded

> >>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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  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
  0 siblings, 1 reply; 22+ messages in thread
From: David Hawkins @ 2006-02-01 17:02 UTC (permalink / raw)
  To: Jenkins, Clive; +Cc: linuxppc-embedded

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?

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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 17:02 ` David Hawkins
@ 2006-02-01 17:44   ` Matt Porter
  2006-02-01 17:53     ` David Hawkins
                       ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Matt Porter @ 2006-02-01 17:44 UTC (permalink / raw)
  To: David Hawkins; +Cc: linuxppc-embedded, Jenkins, Clive

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

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 17:44   ` Matt Porter
@ 2006-02-01 17:53     ` David Hawkins
  2006-02-01 18:04     ` David Hawkins
  2006-02-01 21:14     ` Peter Korsgaard
  2 siblings, 0 replies; 22+ messages in thread
From: David Hawkins @ 2006-02-01 17:53 UTC (permalink / raw)
  To: Matt Porter; +Cc: linuxppc-embedded, Jenkins, Clive


> 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.

Great! An authoritive answer!

Re: endianness, even cooler on the 440EP, in your mmap()
implementation you can set the _PAGE_ENDIAN flag, and
user-space will see the PCI device in little endian
format. Fun stuff!

Thanks Matt.

Dave

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 17:44   ` Matt Porter
  2006-02-01 17:53     ` David Hawkins
@ 2006-02-01 18:04     ` David Hawkins
  2006-02-01 18:11       ` Eugene Surovegin
  2006-02-01 21:14     ` Peter Korsgaard
  2 siblings, 1 reply; 22+ messages in thread
From: David Hawkins @ 2006-02-01 18:04 UTC (permalink / raw)
  To: Matt Porter; +Cc: linuxppc-embedded

Matt,

In the same vein as the readl()/writel() question, what
are the assumptions regarding memcpy_toio and memcpy_fromio?

If the memcpy_to/fromio operations are intended only
for access to PCI devices, then they should also inherently
perform little-endianness conversion. For the test driver
I was working on, I did *not* find this the case, eg.
I implemented the test driver read() and write() using the
memcpy_to/fromio calls, and the data transfers occur
in big-endian (well, 'native' mode, since I also test the
same test driver with the PCI adapter in an x86 system).

If memcpy_to/fromio can be used in a more general context,
then I can see why they operate in native mode.

Just looking for enlightenment.

Cheers
Dave

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 18:04     ` David Hawkins
@ 2006-02-01 18:11       ` Eugene Surovegin
  2006-02-01 18:20         ` David Hawkins
  0 siblings, 1 reply; 22+ messages in thread
From: Eugene Surovegin @ 2006-02-01 18:11 UTC (permalink / raw)
  To: David Hawkins; +Cc: linuxppc-embedded

On Wed, Feb 01, 2006 at 10:04:15AM -0800, David Hawkins wrote:
> Matt,
> 
> In the same vein as the readl()/writel() question, what
> are the assumptions regarding memcpy_toio and memcpy_fromio?
> 
> If the memcpy_to/fromio operations are intended only
> for access to PCI devices, then they should also inherently
> perform little-endianness conversion. For the test driver
> I was working on, I did *not* find this the case, eg.
> I implemented the test driver read() and write() using the
> memcpy_to/fromio calls, and the data transfers occur
> in big-endian (well, 'native' mode, since I also test the
> same test driver with the PCI adapter in an x86 system).
> 
> If memcpy_to/fromio can be used in a more general context,
> then I can see why they operate in native mode.
> 
> Just looking for enlightenment.

This commands IIRC are intended for copying chunk of _bytes_. There 
are no issues with endianess for bytes, e.g. they work just like 
ordinary memcpy.

-- 
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 18:11       ` Eugene Surovegin
@ 2006-02-01 18:20         ` David Hawkins
  2006-02-01 18:23           ` Eugene Surovegin
  0 siblings, 1 reply; 22+ messages in thread
From: David Hawkins @ 2006-02-01 18:20 UTC (permalink / raw)
  To: Eugene Surovegin; +Cc: linuxppc-embedded

Eugene Surovegin wrote:
> On Wed, Feb 01, 2006 at 10:04:15AM -0800, David Hawkins wrote:
> 
>>Matt,
>>
>>In the same vein as the readl()/writel() question, what
>>are the assumptions regarding memcpy_toio and memcpy_fromio?
>>
>>If the memcpy_to/fromio operations are intended only
>>for access to PCI devices, then they should also inherently
>>perform little-endianness conversion. For the test driver
>>I was working on, I did *not* find this the case, eg.
>>I implemented the test driver read() and write() using the
>>memcpy_to/fromio calls, and the data transfers occur
>>in big-endian (well, 'native' mode, since I also test the
>>same test driver with the PCI adapter in an x86 system).
>>
>>If memcpy_to/fromio can be used in a more general context,
>>then I can see why they operate in native mode.
>>
>>Just looking for enlightenment.
> 
> 
> This commands IIRC are intended for copying chunk of _bytes_. There 
> are no issues with endianess for bytes, e.g. they work just like 
> ordinary memcpy.
> 

True, good point.

I quite often implement a 'control' device to read/write/mmap PCI
device registers. In that case, the registers are usually 32-bit, so
if I wanted endian neutrality, I could either let the user-space
app determine the endianness and act accordingly, or force the
user-space app to always see little-endian registers by replacing
memcpy_to/fromio calls with a loop over read;/writel, and in mmap
making sure to set the _PAGE_ENDIAN flag. Of course, making mmap
endian-neutral depends on the 440EP page flags, which say an
ARM might not have.

Thanks for the valuable feedback guys.

Dave

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 18:20         ` David Hawkins
@ 2006-02-01 18:23           ` Eugene Surovegin
  0 siblings, 0 replies; 22+ messages in thread
From: Eugene Surovegin @ 2006-02-01 18:23 UTC (permalink / raw)
  To: David Hawkins

On Wed, Feb 01, 2006 at 10:20:42AM -0800, David Hawkins wrote:
> Eugene Surovegin wrote:
> >On Wed, Feb 01, 2006 at 10:04:15AM -0800, David Hawkins wrote:
> >
> >>Matt,
> >>
> >>In the same vein as the readl()/writel() question, what
> >>are the assumptions regarding memcpy_toio and memcpy_fromio?
> >>
> >>If the memcpy_to/fromio operations are intended only
> >>for access to PCI devices, then they should also inherently
> >>perform little-endianness conversion. For the test driver
> >>I was working on, I did *not* find this the case, eg.
> >>I implemented the test driver read() and write() using the
> >>memcpy_to/fromio calls, and the data transfers occur
> >>in big-endian (well, 'native' mode, since I also test the
> >>same test driver with the PCI adapter in an x86 system).
> >>
> >>If memcpy_to/fromio can be used in a more general context,
> >>then I can see why they operate in native mode.
> >>
> >>Just looking for enlightenment.
> >
> >
> >This commands IIRC are intended for copying chunk of _bytes_. There 
> >are no issues with endianess for bytes, e.g. they work just like 
> >ordinary memcpy.
> >
> 
> True, good point.
> 
> I quite often implement a 'control' device to read/write/mmap PCI
> device registers. In that case, the registers are usually 32-bit, so
> if I wanted endian neutrality, I could either let the user-space
> app determine the endianness and act accordingly, or force the
> user-space app to always see little-endian registers by replacing
> memcpy_to/fromio calls with a loop over read;/writel,

You seem to assume that memcpy should do 32-bit reads/writes. Why not 
16-bit ones? That's why memcpy cannot do any byte swapping, because it 
can "theoretically" do 2 different types of it (16-bit and 32-bit), 
which is obviously not specified in memcpy interface.

-- 
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
@ 2006-02-01 18:35 Jenkins, Clive
  2006-02-01 20:35 ` David Hawkins
  0 siblings, 1 reply; 22+ messages in thread
From: Jenkins, Clive @ 2006-02-01 18:35 UTC (permalink / raw)
  To: David Hawkins; +Cc: linuxppc-embedded

>>>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?
=20
>> No, I think it is correct.

I said this without looking up the example you cited.
I agree now, the example is incorrect; and yes, file a bug
report at oreilly!

I think, from memory, that elsewhere in the book Rubini does
say that readl()... are for the PCI bus, but cross-arch issues
are only addressed in certain sections.

I always find out exactly what these macros do on the arch
I am using, then I know where I stand. I find LXR (Google it if
you don't know it) good for browsing the source of vanilla
kernels. After finding out how and where it is done, I then
double check the relevant files of the actual kernel I am using.

ppc implementations of readl, writel, cpu_to_le32 use the byte-
reversed load/store word instructions.

Clive

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 18:35 Jenkins, Clive
@ 2006-02-01 20:35 ` David Hawkins
  0 siblings, 0 replies; 22+ messages in thread
From: David Hawkins @ 2006-02-01 20:35 UTC (permalink / raw)
  To: Jenkins, Clive; +Cc: linuxppc-embedded

> I said this without looking up the example you cited.
> I agree now, the example is incorrect; and yes, file a bug
> report at oreilly!

Ok, I will.

> I think, from memory, that elsewhere in the book Rubini does
> say that readl()... are for the PCI bus, but cross-arch issues
> are only addressed in certain sections.

I didn't find anything that specifically mentioned their
use was for the PCI bus only. The endianness swapping
features of the pci_config_xxx functions are clearly
stated, but not the readl/writel. And of course the
example I refer to clearly uses those functions on the
PCI bus incorrectly.

But its still a great book.

> I always find out exactly what these macros do on the arch
> I am using, then I know where I stand. I find LXR (Google it if
> you don't know it) good for browsing the source of vanilla
> kernels. After finding out how and where it is done, I then
> double check the relevant files of the actual kernel I am using.
> 
> ppc implementations of readl, writel, cpu_to_le32 use the byte-
> reversed load/store word instructions.

Ahh, very good advice. I think I read about LXR in one of
Freescale's app notes on porting Linux. I'll go take a look
on Google.

Thanks
Dave

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-01 17:44   ` Matt Porter
  2006-02-01 17:53     ` David Hawkins
  2006-02-01 18:04     ` David Hawkins
@ 2006-02-01 21:14     ` Peter Korsgaard
  2006-02-02  0:54       ` Kumar Gala
  2 siblings, 1 reply; 22+ messages in thread
From: Peter Korsgaard @ 2006-02-01 21:14 UTC (permalink / raw)
  To: Matt Porter; +Cc: Jenkins, Clive, linuxppc-embedded

>>>>> "Matt" == Matt Porter <mporter@kernel.crashing.org> writes:

 Matt> read*/write* and ioread*/iowrite* generate outbound little
 Matt> endian cycles on ALL arches, period.  They are intended
 Matt> only for PCI use and have generic names only because of
 Matt> the assumption that "all the world is a PC".

What is the preferred way of accessing non-PCI devices then? Direct
pointer access?

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  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
  0 siblings, 2 replies; 22+ messages in thread
From: Kumar Gala @ 2006-02-02  0:54 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: linuxppc-embedded, Jenkins, Clive

On Wed, 1 Feb 2006, Peter Korsgaard wrote:

> >>>>> "Matt" == Matt Porter <mporter@kernel.crashing.org> writes:
> 
>  Matt> read*/write* and ioread*/iowrite* generate outbound little
>  Matt> endian cycles on ALL arches, period.  They are intended
>  Matt> only for PCI use and have generic names only because of
>  Matt> the assumption that "all the world is a PC".
> 
> What is the preferred way of accessing non-PCI devices then? Direct
> pointer access?

No direct pointer access is bad. On PPC You can use
in_be{8,16,32}/out_be{8,16,32}

- kumar

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02  0:54       ` Kumar Gala
@ 2006-02-02  3:07         ` Matt Porter
  2006-02-02  8:09         ` Peter Korsgaard
  1 sibling, 0 replies; 22+ messages in thread
From: Matt Porter @ 2006-02-02  3:07 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded, Jenkins, Clive

On Wed, Feb 01, 2006 at 06:54:09PM -0600, Kumar Gala wrote:
> On Wed, 1 Feb 2006, Peter Korsgaard wrote:
> 
> > >>>>> "Matt" == Matt Porter <mporter@kernel.crashing.org> writes:
> > 
> >  Matt> read*/write* and ioread*/iowrite* generate outbound little
> >  Matt> endian cycles on ALL arches, period.  They are intended
> >  Matt> only for PCI use and have generic names only because of
> >  Matt> the assumption that "all the world is a PC".
> > 
> > What is the preferred way of accessing non-PCI devices then? Direct
> > pointer access?
> 
> No direct pointer access is bad. On PPC You can use
> in_be{8,16,32}/out_be{8,16,32}

Ack. Also, it should be pointed out that there are countless
examples of PPC drivers where this is done properly. 4xx, 83xx,
85xx, etc. on-chip peripherals all do this since they are
naturally BE registers.

-Matt

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  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 14:21           ` Matt Porter
  1 sibling, 2 replies; 22+ messages in thread
From: Peter Korsgaard @ 2006-02-02  8:09 UTC (permalink / raw)
  To: Kumar Gala; +Cc: linuxppc-embedded, Jenkins, Clive

On 2/2/06, Kumar Gala <galak@kernel.crashing.org> wrote:
> > What is the preferred way of accessing non-PCI devices then? Direct
> > pointer access?
>
> No direct pointer access is bad. On PPC You can use
> in_be{8,16,32}/out_be{8,16,32}

What about arch independent drivers? Are there any generic approach
for this or do you have to stick to ugly #ifdefs to decide between
in_be32/inl ?

--
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  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
  1 sibling, 1 reply; 22+ messages in thread
From: Eugene Surovegin @ 2006-02-02  9:08 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: Jenkins, Clive, linuxppc-embedded

On Thu, Feb 02, 2006 at 09:09:17AM +0100, Peter Korsgaard wrote:
> On 2/2/06, Kumar Gala <galak@kernel.crashing.org> wrote:
> > > What is the preferred way of accessing non-PCI devices then? Direct
> > > pointer access?
> >
> > No direct pointer access is bad. On PPC You can use
> > in_be{8,16,32}/out_be{8,16,32}
> 
> What about arch independent drivers? Are there any generic approach
> for this or do you have to stick to ugly #ifdefs to decide between
> in_be32/inl ?

I'm curious, could you give an example of such arch independent 
driver?

-- 
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* RE: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
@ 2006-02-02  9:35 Jenkins, Clive
  2006-02-02  9:46 ` Eugene Surovegin
  0 siblings, 1 reply; 22+ messages in thread
From: Jenkins, Clive @ 2006-02-02  9:35 UTC (permalink / raw)
  To: Eugene Surovegin, Peter Korsgaard; +Cc: linuxppc-embedded

A driver for some device that could be connected to (or plugged into)
a variety of different platforms of different architecture.
A driver for a core that could be implemented within an FPGA on
multiple platforms.

Clive

-----Original Message-----
From: Eugene Surovegin [mailto:ebs@ebshome.net]=20
Sent: 02 February 2006 09:08
To: Peter Korsgaard
Cc: Kumar Gala; linuxppc-embedded@ozlabs.org; Jenkins, Clive
Subject: Re: Yosemite/440EP why are readl()/ioread32() setup to
readlittle-endian?


On Thu, Feb 02, 2006 at 09:09:17AM +0100, Peter Korsgaard wrote:
> On 2/2/06, Kumar Gala <galak@kernel.crashing.org> wrote:
> > > What is the preferred way of accessing non-PCI devices then?
Direct
> > > pointer access?
> >
> > No direct pointer access is bad. On PPC You can use
> > in_be{8,16,32}/out_be{8,16,32}
>=20
> What about arch independent drivers? Are there any generic approach
> for this or do you have to stick to ugly #ifdefs to decide between
> in_be32/inl ?

I'm curious, could you give an example of such arch independent=20
driver?

--=20
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02  9:35 Jenkins, Clive
@ 2006-02-02  9:46 ` Eugene Surovegin
  2006-02-02 14:37   ` Matt Porter
  0 siblings, 1 reply; 22+ messages in thread
From: Eugene Surovegin @ 2006-02-02  9:46 UTC (permalink / raw)
  To: Jenkins, Clive; +Cc: linuxppc-embedded

On Thu, Feb 02, 2006 at 09:35:56AM -0000, Jenkins, Clive wrote:
> A driver for some device that could be connected to (or plugged into)
> a variety of different platforms of different architecture.
> A driver for a core that could be implemented within an FPGA on
> multiple platforms.

Well, this is all nice but I was wondering about _real_ examples.
When you are talking about "connecting" or "plugging" you have to keep 
in mind actual bus interconnect. So far AFAIK PCI (and derivatives) 
are the only cross-arch bus.

So basically, you have no _real_ life examples, so I'm wondering why 
people need this "arch-independent" non-PCI I/O accessors for 
something which doesn't exist.

I think the reason why Linux doesn't have this stuff follows from the 
previous paragraph.

-- 
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02  8:09         ` Peter Korsgaard
  2006-02-02  9:08           ` Eugene Surovegin
@ 2006-02-02 14:21           ` Matt Porter
  1 sibling, 0 replies; 22+ messages in thread
From: Matt Porter @ 2006-02-02 14:21 UTC (permalink / raw)
  To: Peter Korsgaard; +Cc: linuxppc-embedded, Jenkins, Clive

On Thu, Feb 02, 2006 at 09:09:17AM +0100, Peter Korsgaard wrote:
> On 2/2/06, Kumar Gala <galak@kernel.crashing.org> wrote:
> > > What is the preferred way of accessing non-PCI devices then? Direct
> > > pointer access?
> >
> > No direct pointer access is bad. On PPC You can use
> > in_be{8,16,32}/out_be{8,16,32}
> 
> What about arch independent drivers? Are there any generic approach
> for this or do you have to stick to ugly #ifdefs to decide between
> in_be32/inl ?

ioread*be()/iowrite*be() can be used for this. Since the generic
big endian accessors became a standard thing a little while back,
all the PPC on-chip drivers should move to that. It's just a matter
of time.

-Matt

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02  9:46 ` Eugene Surovegin
@ 2006-02-02 14:37   ` Matt Porter
  2006-02-02 17:45     ` Eugene Surovegin
  0 siblings, 1 reply; 22+ messages in thread
From: Matt Porter @ 2006-02-02 14:37 UTC (permalink / raw)
  To: Jenkins, Clive, Peter Korsgaard, Kumar Gala, linuxppc-embedded

On Thu, Feb 02, 2006 at 01:46:41AM -0800, Eugene Surovegin wrote:
> On Thu, Feb 02, 2006 at 09:35:56AM -0000, Jenkins, Clive wrote:
> > A driver for some device that could be connected to (or plugged into)
> > a variety of different platforms of different architecture.
> > A driver for a core that could be implemented within an FPGA on
> > multiple platforms.
> 
> Well, this is all nice but I was wondering about _real_ examples.
> When you are talking about "connecting" or "plugging" you have to keep 
> in mind actual bus interconnect. So far AFAIK PCI (and derivatives) 
> are the only cross-arch bus.
> 
> So basically, you have no _real_ life examples, so I'm wondering why 
> people need this "arch-independent" non-PCI I/O accessors for 
> something which doesn't exist.
> 
> I think the reason why Linux doesn't have this stuff follows from the 
> previous paragraph.

I mentioned the BE iomap variants that are being used on some non-pci
parisc devices already. I'll give a partial example of something that
is non-pci yet "arch-independent".

Take a non-pci EHCI core (yes, I know it's little endian by definition
but suspend reality for a second).  You can create an arch-independent
EHCI driver that uses the platform bus by using the iomap accessors.
Since these cores are licensed every day by XYZ startups for their
latest "gee-whiz" SoC, it reasons that you'll see the same core on
multiple licensable SoC architectures. I've seen one such thing
on MIPS.

We also know that major semiconductor companies do the same thing
for their peripherals in some cases. They're just as willing to
buy somebody else's USB core, for example.  So, having a BE
non-pci device cross platform isn't a stretch.

Take a look at drivers/scsi/53c700.{c,h}. That generic driver
is why BE iomap accessors were added. It's in the process of
being shared between parisc and m68k.

-Matt

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02  9:08           ` Eugene Surovegin
@ 2006-02-02 17:34             ` Dale Farnsworth
  0 siblings, 0 replies; 22+ messages in thread
From: Dale Farnsworth @ 2006-02-02 17:34 UTC (permalink / raw)
  To: Linuxppc-embedded

In article <20060202090827.GA12810@gate.ebshome.net> you write:
> On Thu, Feb 02, 2006 at 09:09:17AM +0100, Peter Korsgaard wrote:
> > On 2/2/06, Kumar Gala <galak@kernel.crashing.org> wrote:
> > > > What is the preferred way of accessing non-PCI devices then? Direct
> > > > pointer access?
> > >
> > > No direct pointer access is bad. On PPC You can use
> > > in_be{8,16,32}/out_be{8,16,32}
> > 
> > What about arch independent drivers? Are there any generic approach
> > for this or do you have to stick to ugly #ifdefs to decide between
> > in_be32/inl ?
> 
> I'm curious, could you give an example of such arch independent 
> driver?

Such #ifdefs are found in drivers/net/smc91x.h

-Dale

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02 14:37   ` Matt Porter
@ 2006-02-02 17:45     ` Eugene Surovegin
  2006-02-02 18:16       ` Matt Porter
  0 siblings, 1 reply; 22+ messages in thread
From: Eugene Surovegin @ 2006-02-02 17:45 UTC (permalink / raw)
  To: Matt Porter; +Cc: linuxppc-embedded, Jenkins, Clive

On Thu, Feb 02, 2006 at 07:37:01AM -0700, Matt Porter wrote:
> I mentioned the BE iomap variants that are being used on some non-pci
> parisc devices already. I'll give a partial example of something that
> is non-pci yet "arch-independent".
> 
> Take a non-pci EHCI core (yes, I know it's little endian by definition
> but suspend reality for a second).  You can create an arch-independent
> EHCI driver that uses the platform bus by using the iomap accessors.
> Since these cores are licensed every day by XYZ startups for their
> latest "gee-whiz" SoC, it reasons that you'll see the same core on
> multiple licensable SoC architectures. I've seen one such thing
> on MIPS.
> 
> We also know that major semiconductor companies do the same thing
> for their peripherals in some cases. They're just as willing to
> buy somebody else's USB core, for example.  So, having a BE
> non-pci device cross platform isn't a stretch.
> 
> Take a look at drivers/scsi/53c700.{c,h}. That generic driver
> is why BE iomap accessors were added. It's in the process of
> being shared between parisc and m68k.
> 

Matt, my problem with this approach is that it repeats the same 
old mistakes but in "BE-mode", e.g. _assuming_ some access mode and 
hard-coding it into the driver. I fail to see how assuming big-endian 
is any better than assuming little-endian in this case. And this is 
not _portable_ in my book, no matter what some people want me to 
believe.

This fails miserably when for example you have a bus which does byte 
swaps in every half-word. And yes, I have such device on my table and 
I have to port PCMCIA/PCI drivers to this SoC :).

Here is how inb looks like:

static inline u8 fpi_inb(unsigned long port)
{
    port ^= 1;
    return inb(port);
}

IMO, truly portable and driver independent I/O accessors should be 
implemented as a function pointers on per-bus (at least) basis which 
can be overridden by arch or board code. In this case we can get rid 
of "ugly" ifdefs in driver code :).

-- 
Eugene

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: Yosemite/440EP why are readl()/ioread32() setup to readlittle-endian?
  2006-02-02 17:45     ` Eugene Surovegin
@ 2006-02-02 18:16       ` Matt Porter
  0 siblings, 0 replies; 22+ messages in thread
From: Matt Porter @ 2006-02-02 18:16 UTC (permalink / raw)
  To: Jenkins, Clive, Peter Korsgaard, Kumar Gala, linuxppc-embedded

On Thu, Feb 02, 2006 at 09:45:04AM -0800, Eugene Surovegin wrote:
> On Thu, Feb 02, 2006 at 07:37:01AM -0700, Matt Porter wrote:
> > I mentioned the BE iomap variants that are being used on some non-pci
> > parisc devices already. I'll give a partial example of something that
> > is non-pci yet "arch-independent".
> > 
> > Take a non-pci EHCI core (yes, I know it's little endian by definition
> > but suspend reality for a second).  You can create an arch-independent
> > EHCI driver that uses the platform bus by using the iomap accessors.
> > Since these cores are licensed every day by XYZ startups for their
> > latest "gee-whiz" SoC, it reasons that you'll see the same core on
> > multiple licensable SoC architectures. I've seen one such thing
> > on MIPS.
> > 
> > We also know that major semiconductor companies do the same thing
> > for their peripherals in some cases. They're just as willing to
> > buy somebody else's USB core, for example.  So, having a BE
> > non-pci device cross platform isn't a stretch.
> > 
> > Take a look at drivers/scsi/53c700.{c,h}. That generic driver
> > is why BE iomap accessors were added. It's in the process of
> > being shared between parisc and m68k.
> > 
> 
> Matt, my problem with this approach is that it repeats the same 
> old mistakes but in "BE-mode", e.g. _assuming_ some access mode and 
> hard-coding it into the driver. I fail to see how assuming big-endian 
> is any better than assuming little-endian in this case. And this is 
> not _portable_ in my book, no matter what some people want me to 
> believe.
> 
> This fails miserably when for example you have a bus which does byte 
> swaps in every half-word. And yes, I have such device on my table and 
> I have to port PCMCIA/PCI drivers to this SoC :).

Yuck. But a good example that there are always ill-behaved exceptions.

> Here is how inb looks like:
> 
> static inline u8 fpi_inb(unsigned long port)
> {
>     port ^= 1;
>     return inb(port);
> }
> 
> IMO, truly portable and driver independent I/O accessors should be 
> implemented as a function pointers on per-bus (at least) basis which 
> can be overridden by arch or board code. In this case we can get rid 
> of "ugly" ifdefs in driver code :).

There are a ton of reasons for this too, but there's been resistance
in the past to anything adding an additional dereference to the ia32
case.  I think there's been some proposals to get around this and
maybe even some small level of acceptance. However, since the server
folks don't need it, it's slow going to get such a major change pushed
through.

FWIW, some Xscale IXPs could use the per-bus pointer accessors to
manage the some floating I/O windows more cleanly as well. RapidIO
has some use for it too. It's not just byte swapping at least.

You could drive this change, you know. :)

-Matt

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2006-02-02 18:16 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).