Update:

On Mon, 27 Feb 2017 07:52:10 +0100, Albert ARIBAUD
<albert.u.b...@aribaud.net> wrote:
> Hello Tom,
> 
> On Sun, 26 Feb 2017 20:04:28 -0500, Tom Rini <tr...@konsulko.com> wrote:
> > On Sun, Feb 26, 2017 at 04:29:32PM +0100, Albert ARIBAUD wrote:
> >   
> > > The switch to private LIBGCC causes 'undefined instruction'
> > > exception in at least the Open-RD Ultimate and Client, and
> > > quite probably the Open-RD Base as well.
> > > 
> > > While debugging this issue, it appeared the switch to
> > > architecture-optimized memset and memcpy also causes the
> > > same exceptions.
> > > 
> > > Until a fix to private libgcc and architecture-optimized
> > > memcpy and memset is mainlined, disable their use in all
> > > openrd configurations.
> > > 
> > > Signed-off-by: Albert ARIBAUD <albert.u.b...@aribaud.net>    
> > 
> > Implementation wise, there's two big problems here.  First, all of the
> > code we're talking about is a direct drop-in from the kernel.  So
> > whatever is wrong here is a problem that the kernel itself can trigger,
> > so needs sorting out and fixing.  Second, do you have more details on
> > how to recreate (or not recreate) these problems?  
> 
> Second answer first: the easy way to reproduce this is to build for any
> Thumb-1 board and wait for memset, memcpy or a libgcc function to be
> called, which eventually results in an 'undefined instruction' trap.
> Then add the three CONFIG...=n lines in the board's config file, build,
> and see that the issue is gone. This is 100% reproducible.
> 
> First answer:
> 
> I've looked into a 'slow general fix' in parallel to this 'fast fix',
> starting with the memset case (and assuming the issue is common to the
> memcpy and libgcc cases.
> 
> The cause seems to stem from this:
> 
> - for Thumb-1 boards, the arch/arm/lib/memset.S et al. are built for
>   ARM state, due AFAIR to incompatibilities with the Thumb-1 instruction
>   set.
> 
> - apparently the 'ret lr' in arch/arm/lib/memset.S gets translated into
>   a 'mov pc, lr' which, at least for ATMv5TE, is a simple branch, not
>   an interworking branch.
> 
> - consequently, upon return from the memset call, the CPU remains in
>   ARM state while trying to execute Thumb-1 instructions.
> 
> ISTR there are gnu as, gcc or ldoptions to be passed to cause the 'ret
> lr' to be turned into a 'bx lr', but I could not find them yesterday.
> 
> The 'slow and more correct' fix consists in building the Linux and
> U-Boot source code for the Open-RD board and looking into what code the
> memset.S produces in Linux and what compiler/assembler options were
> passed to it (or digging into the memset, memcpy and libgcc of the
> GCC C compiler, but that's a bit less simple).

I dropped the Linux trail because it builds Kirkwood (not Orion, as I
wrongly stated previously) with ARM instruction set rather than the
Thumb-1 set U-Boot uses, so the issue will never appear in the kernel
(it might possibly happen in userland code if that code uses a custom
libgcc, which I consider quite improbable).

So I dug into the 'ret' pseudo-opcode, which is in fact a macro,
introduced to produce the most adequate opcode for the exact ARM
architecture; it is defined in arch/arm/include/asm/assembler.h.
Currently, defining __ARM_ARCH_5TE__ causes 'ret lr' to be encoded
as 'mov pc, lr' rather than the 'bx lr' which should work.

I will have access again to my Open-RD board later today; I will test
if making 'ret' use 'bx' for ARMv5TE works, and also if the current
Linux version of arch/arm/include/asm/assembler.h can be used with
current U-Boot, but that would be a wider change.

Amicalement,
-- 
Albert.
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/listinfo/u-boot

Reply via email to