All of lore.kernel.org
 help / color / mirror / Atom feed
* what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
@ 2015-02-20  9:53 Robert P. J. Day
  2015-02-21  4:00 ` Matt Turner
  2015-02-21 21:03 ` Kevin Cernekee
  0 siblings, 2 replies; 8+ messages in thread
From: Robert P. J. Day @ 2015-02-20  9:53 UTC (permalink / raw)
  To: linux-mips


  was recently handed a MIPS-based dev board (can't name the vendor,
NDA) that *typically* runs in LE mode but, because of a proprietary
binary that must be run on the board and was compiled as BE, has to be
run in BE mode.

  the vendor supplied a yoctoproject layer that seems to work fine
but, in changing the DEFAULTTUNE to big-endian, the following patch
had to be applied to the 3.14 kernel tree to the file
arch/mips/include/asm/io.h in order to get output from the console
port as the system was booting:

326c326,333
< 		*__mem = __val;						\
---
> 	{										\
> 		if (sizeof(type) == sizeof(u32))		\
> 		{									\
> 			*__mem = __cpu_to_le32(__val);	\
> 		}									\
> 		else								\
> 			*__mem = __val;						\
> 	}											\
356a364
> 	{										\
357a366,368
> 		if (sizeof(type) == sizeof(u32))	\
> 			__val = __cpu_to_le32(__val);	\
> 	}											\

  without that patch, the initial conclusion was that the board was
just hanging at boot, but i was told, no, it was booting, there was
just no output at the console port. applied the patch and, voila.

  can someone explain *precisely* what the above is doing? i am by no
means a MIPS expert, but clearly the above is doing some sort of
explicit BE/LE conversion. can anyone supply more detail? thanks.

rday

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-20  9:53 what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h? Robert P. J. Day
@ 2015-02-21  4:00 ` Matt Turner
  2015-02-21  4:04   ` Matt Turner
  2015-02-21 21:03 ` Kevin Cernekee
  1 sibling, 1 reply; 8+ messages in thread
From: Matt Turner @ 2015-02-21  4:00 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: linux-mips@linux-mips.org

On Fri, Feb 20, 2015 at 1:53 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
>
>   was recently handed a MIPS-based dev board (can't name the vendor,
> NDA) that *typically* runs in LE mode but, because of a proprietary
> binary that must be run on the board and was compiled as BE, has to be
> run in BE mode.
>
>   the vendor supplied a yoctoproject layer that seems to work fine
> but, in changing the DEFAULTTUNE to big-endian, the following patch
> had to be applied to the 3.14 kernel tree to the file
> arch/mips/include/asm/io.h in order to get output from the console
> port as the system was booting:
>
> 326c326,333
> <               *__mem = __val;                                         \
> ---
>>       {                                                                               \
>>               if (sizeof(type) == sizeof(u32))                \
>>               {                                                                       \
>>                       *__mem = __cpu_to_le32(__val);  \

They're byte swapping a value if they're in big endian mode.

>>               }                                                                       \
>>               else                                                            \
>>                       *__mem = __val;                                         \

And they don't seem to really understand the __cpu_to_le32 macro...

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-21  4:00 ` Matt Turner
@ 2015-02-21  4:04   ` Matt Turner
  2015-02-21  8:11     ` Robert P. J. Day
  0 siblings, 1 reply; 8+ messages in thread
From: Matt Turner @ 2015-02-21  4:04 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: linux-mips@linux-mips.org

On Fri, Feb 20, 2015 at 8:00 PM, Matt Turner <mattst88@gmail.com> wrote:
> On Fri, Feb 20, 2015 at 1:53 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
>>
>>   was recently handed a MIPS-based dev board (can't name the vendor,
>> NDA) that *typically* runs in LE mode but, because of a proprietary
>> binary that must be run on the board and was compiled as BE, has to be
>> run in BE mode.
>>
>>   the vendor supplied a yoctoproject layer that seems to work fine
>> but, in changing the DEFAULTTUNE to big-endian, the following patch
>> had to be applied to the 3.14 kernel tree to the file
>> arch/mips/include/asm/io.h in order to get output from the console
>> port as the system was booting:
>>
>> 326c326,333
>> <               *__mem = __val;                                         \
>> ---
>>>       {                                                                               \
>>>               if (sizeof(type) == sizeof(u32))                \
>>>               {                                                                       \
>>>                       *__mem = __cpu_to_le32(__val);  \
>
> They're byte swapping a value if they're in big endian mode.
>
>>>               }                                                                       \
>>>               else                                                            \
>>>                       *__mem = __val;                                         \
>
> And they don't seem to really understand the __cpu_to_le32 macro...

Sorry, I should be more precise. They're byte swapping 32-bit values
if they're in big endian mode, and copying everything else without
conversion.

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-21  4:04   ` Matt Turner
@ 2015-02-21  8:11     ` Robert P. J. Day
  2015-02-21  8:23       ` Manuel Lauss
  0 siblings, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2015-02-21  8:11 UTC (permalink / raw)
  To: Matt Turner; +Cc: linux-mips@linux-mips.org

On Fri, 20 Feb 2015, Matt Turner wrote:

> On Fri, Feb 20, 2015 at 8:00 PM, Matt Turner <mattst88@gmail.com> wrote:
> > On Fri, Feb 20, 2015 at 1:53 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
> >>
> >>   was recently handed a MIPS-based dev board (can't name the vendor,
> >> NDA) that *typically* runs in LE mode but, because of a proprietary
> >> binary that must be run on the board and was compiled as BE, has to be
> >> run in BE mode.
> >>
> >>   the vendor supplied a yoctoproject layer that seems to work fine
> >> but, in changing the DEFAULTTUNE to big-endian, the following patch
> >> had to be applied to the 3.14 kernel tree to the file
> >> arch/mips/include/asm/io.h in order to get output from the console
> >> port as the system was booting:
> >>
> >> 326c326,333
> >> <               *__mem = __val;                                         \
> >> ---
> >>>       {                                                                               \
> >>>               if (sizeof(type) == sizeof(u32))                \
> >>>               {                                                                       \
> >>>                       *__mem = __cpu_to_le32(__val);  \
> >
> > They're byte swapping a value if they're in big endian mode.
> >
> >>>               }                                                                       \
> >>>               else                                                            \
> >>>                       *__mem = __val;                                         \
> >
> > And they don't seem to really understand the __cpu_to_le32 macro...
>
> Sorry, I should be more precise. They're byte swapping 32-bit values
> if they're in big endian mode, and copying everything else without
> conversion.

  i understand *in general* what the above is doing ... what i don't
understand is why it's necessary to hack a fundamental kernel header
file this way in order to run this board in BE versus LE mode.

  the kernel was already configured for BE mode, which i would have
thought would be sufficient, so it's a mystery to me why one would
still have to *further* hack the io.h file this way -- if the above is
a necessity, shouldn't it be a conditional change based on selecting
BE configuration?

  has anyone else ever needed to do this? or is this some weird,
one-off hack that perhaps applies *only* to some bizarre feature of
this board?

rday

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-21  8:11     ` Robert P. J. Day
@ 2015-02-21  8:23       ` Manuel Lauss
  2015-02-21  8:27         ` Robert P. J. Day
  0 siblings, 1 reply; 8+ messages in thread
From: Manuel Lauss @ 2015-02-21  8:23 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: Matt Turner, linux-mips@linux-mips.org

On Sat, Feb 21, 2015 at 9:11 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
>
>   has anyone else ever needed to do this? or is this some weird,
> one-off hack that perhaps applies *only* to some bizarre feature of
> this board?

My guess isthat the peripherals attached to the internal bus
only undestand little endian, and the bus doesn't do byte swaps when
the core isn't configured for LE. I.e. the BE feature is only
implemented in the mips core and the rest was designed for LE only.

Manuel

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-21  8:23       ` Manuel Lauss
@ 2015-02-21  8:27         ` Robert P. J. Day
  2015-02-21 20:00           ` Maciej W. Rozycki
  0 siblings, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2015-02-21  8:27 UTC (permalink / raw)
  To: Manuel Lauss; +Cc: Matt Turner, linux-mips@linux-mips.org

On Sat, 21 Feb 2015, Manuel Lauss wrote:

> On Sat, Feb 21, 2015 at 9:11 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
> >
> >   has anyone else ever needed to do this? or is this some weird,
> > one-off hack that perhaps applies *only* to some bizarre feature of
> > this board?
>
> My guess is that the peripherals attached to the internal bus
> only undestand little endian, and the bus doesn't do byte swaps when
> the core isn't configured for LE. I.e. the BE feature is only
> implemented in the mips core and the rest was designed for LE only.

  ok, that makes sense ... so it's very likely a "issue with *this*
particular board and setup" kind of thing. thanks.

rday

-- 

========================================================================
Robert P. J. Day                                 Ottawa, Ontario, CANADA
                        http://crashcourse.ca

Twitter:                                       http://twitter.com/rpjday
LinkedIn:                               http://ca.linkedin.com/in/rpjday
========================================================================

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-21  8:27         ` Robert P. J. Day
@ 2015-02-21 20:00           ` Maciej W. Rozycki
  0 siblings, 0 replies; 8+ messages in thread
From: Maciej W. Rozycki @ 2015-02-21 20:00 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: Manuel Lauss, Matt Turner, linux-mips@linux-mips.org

On Sat, 21 Feb 2015, Robert P. J. Day wrote:

> > >   has anyone else ever needed to do this? or is this some weird,
> > > one-off hack that perhaps applies *only* to some bizarre feature of
> > > this board?
> >
> > My guess is that the peripherals attached to the internal bus
> > only undestand little endian, and the bus doesn't do byte swaps when
> > the core isn't configured for LE. I.e. the BE feature is only
> > implemented in the mips core and the rest was designed for LE only.
> 
>   ok, that makes sense ... so it's very likely a "issue with *this*
> particular board and setup" kind of thing. thanks.

 It looks to me like either a platform setup or a driver bug, as for this 
very purpose we have two sets of these access macros, one that preserves 
the bit ordering (IOW the value accessed) and another that preserves the 
byte ordering (but the value accessed may come out byte-swapped).  The 
former will usually be used for accessing MMIO registers of peripherals 
and the latter for byte streams exchanged between a peripheral and host 
memory via DMA.  This is so that generic code (e.g. a PCI device driver 
that will run on any processor or system it is thrown at) does not have to 
be concerned about the actual host bus endianness.

 The names of these macros reflect their usual purpose, and there's a 
pass-through set of macros too that never byte-swaps, so you'll use:

* `readl'/`writel'/etc. -- to access MMIO, preserving the bit ordering,

* `__mem_readl'/`__mem_writel'/etc. -- to access DMA memory, preserving 
  the byte ordering,

* `__raw_readl'/`__raw_writel'/etc. -- to access data as it shows on the 
  bus it comes from or goes to.

Please note that there is only ever any difference between these accessors 
if a platform has a bus whose endianness is fixed regardless of the host 
endianness.

 For example PCI is fixed at the little endianness and therefore all these 
macros pass data through unchanged on a little-endian host.  When the host 
bus is big-endian then `readl'/`writel' will byte-swap data unless byte 
lane swapping already happens at the PCI host bridge.  In that case it is 
likely that `__mem_readl'/`__mem_writel' will have to swap data instead.  
And then you'll use `__raw_readl'/`__raw_writel' to access host MMIO 
registers that are never swapped, e.g. on-chip SOC registers, or host-side 
registers of the PCI host bridge.

 All this is arranged in a system-specific manner with the use of a set of 
`*ioswab?' macros, that a platform has to define in `mangle-port.h' unless 
it wants to use the defaults.  See the existing examples for a reference.  
There's a set of `__swizzle_addr_?' macros there too, for systems that 
need to adjust the address accessed to account for byte lane swapping done 
in hardware.

 Overall it all is system dependent, and there are systems in existence 
for example that have an alternative byte-lane swapping address space and 
therefore for accesses that need to be swapped they can take advantage of 
that feature and switch the address space rather than shuffling bytes, for 
a small performance advantage.  We don't use this feature at the moment 
though; it would be most beneficial for string I/O where a single address 
adjustment operation would do for the whole transfer whereas byte-swapping 
has to be done for every individual piece of data transferred.

 In any case it looks very likely to me that either a driver uses the 
wrong set of macros to access a resource or the platform has failed to 
define its `*ioswab*' macros correctly.

 Feel free to let me know if you find anything of this unclear or have any 
further questions.

  Maciej

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

* Re: what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h?
  2015-02-20  9:53 what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h? Robert P. J. Day
  2015-02-21  4:00 ` Matt Turner
@ 2015-02-21 21:03 ` Kevin Cernekee
  1 sibling, 0 replies; 8+ messages in thread
From: Kevin Cernekee @ 2015-02-21 21:03 UTC (permalink / raw)
  To: Robert P. J. Day; +Cc: Linux MIPS Mailing List

On Fri, Feb 20, 2015 at 1:53 AM, Robert P. J. Day <rpjday@crashcourse.ca> wrote:
>
>   was recently handed a MIPS-based dev board (can't name the vendor,
> NDA) that *typically* runs in LE mode but, because of a proprietary
> binary that must be run on the board and was compiled as BE, has to be
> run in BE mode.
>
>   the vendor supplied a yoctoproject layer that seems to work fine
> but, in changing the DEFAULTTUNE to big-endian, the following patch
> had to be applied to the 3.14 kernel tree to the file
> arch/mips/include/asm/io.h in order to get output from the console
> port as the system was booting:
>
> 326c326,333
> <               *__mem = __val;                                         \
> ---
>>       {                                                                               \
>>               if (sizeof(type) == sizeof(u32))                \
>>               {                                                                       \
>>                       *__mem = __cpu_to_le32(__val);  \
>>               }                                                                       \
>>               else                                                            \
>>                       *__mem = __val;                                         \
>>       }                                                                                       \
> 356a364
>>       {                                                                               \
> 357a366,368
>>               if (sizeof(type) == sizeof(u32))        \
>>                       __val = __cpu_to_le32(__val);   \
>>       }                                                                                       \
>
>   without that patch, the initial conclusion was that the board was
> just hanging at boot, but i was told, no, it was booting, there was
> just no output at the console port. applied the patch and, voila.

If it's using the serial8250 driver with a standard 16550A-ish UART,
MMIO accesses via readl()/writel() may be byteswapped on a BE system.

Historically I've dealt with this problem by locally modifying the
serial8250 driver to use the __raw_* variants, but here is a patch
that lets you instruct the driver to use either LE or BE accessors:

http://patchwork.linux-mips.org/patch/8572/

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

end of thread, other threads:[~2015-02-21 21:04 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-02-20  9:53 what is the purpose of the following LE->BE patch to arch/mips/include/asm/io.h? Robert P. J. Day
2015-02-21  4:00 ` Matt Turner
2015-02-21  4:04   ` Matt Turner
2015-02-21  8:11     ` Robert P. J. Day
2015-02-21  8:23       ` Manuel Lauss
2015-02-21  8:27         ` Robert P. J. Day
2015-02-21 20:00           ` Maciej W. Rozycki
2015-02-21 21:03 ` Kevin Cernekee

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.