[U-Boot] Save/restore global data pointer on API boundary

Message ID 5022350E.4050509@arm.com
State RFC
Headers show

Commit Message

Leif Lindholm Aug. 8, 2012, 9:44 a.m.
On 08/07/12 19:30, Wolfgang Denk wrote:
>> Most architectures keep the global data pointer (gd) in a register.
> This may, or may not be.  You should not make any assumptions on how
> gd is implemented.

The comment did, the code didn't, as long as gd was a pointer (which
should be a safe assumption). But that's irrelevant as I seem to have
gotten the wrong end of the stick.

>> When using the external app API, because they are calling us rather
>> than we calling them, this register can be corrupted.
> How can this be?  The caller should always use the same register
> convention as we do - otherwise we are in a much deeper trouble.
> It is up to the caller to make sure it uses the published API (resp.
> ABI).

Hmm, ok - this was not clear to me from the docs and example.

Indeed, the example does not reserve r8 (on ARM) or r2 (on PPC). Nor
does it save/restore it on entry/syscall. I don't know the exact ABI
semantics of r2 for PPC, but on ARM this is an error.

This could be worked around by something like:

An alternative would be to mandate DECLARE_GLOBAL_DATA_PTR for all API
applications, but I'd frankly prefer not providing direct access to gd.

Best Regards,



diff --git a/examples/api/crt0.S b/examples/api/crt0.S
index 6daf127..5f956e4 100644
--- a/examples/api/crt0.S
+++ b/examples/api/crt0.S
@@ -49,13 +49,21 @@  syscall:
         ldr     ip, =search_hint
         str     sp, [ip]
+       ldr     ip, =gd_backup
+       str     r8, [ip]
         b       main

         .globl syscall
+       push    {r6-r8, lr}
+       ldr     r6, =gd_backup
+       ldr     r8, [r6]
         ldr     ip, =syscall_ptr
+       mov     lr, pc
         ldr     pc, [ip]
+       str     r8, [r6]
+       pop     {r6-r8, pc}

  #error No support for this arch!
@@ -69,3 +77,7 @@  syscall_ptr:
         .globl search_hint
         .long   0
+       .globl gd_backup
+       .long   0