On Wed, Oct 27, 2010 at 4:17 AM, David Peverley <[email protected]> wrote:
> Hi all,
>
> The realtime tests aren't compiled for ARM currently as there's no
> implementation of atomic_add() in :
> testcases/realtime/include/librttest.h
>
> As a side note - in this function can we change the #error to not be
> blank and read something along the lines of :
> #error ERROR: atomic_add: Architecture not supported for compilation
>
> Anyway, the existing function here supports three architectures and
> lifts the implementations as follows :
> __x86_64__ || __i386__
> arch/x86/include/asm/atomic_32.h
> __powerpc__
> arch/powerpc/include/asm/atomic.h (might need review!)
> __sh__
> arch/sh/include/asm/atomic-llsc.h (might need review!)
>
> Logically we can add an ARM case following the same logic. Looking in :
> arch/arm/include/asm/atomic.h
>
> We can implement this easily for v6+ architectures. The case for
> atomic_add in librttest.h would look something like :
> #elif defined(__arm__) && (__LINUX_ARM_ARCH__ >= 6)
> unsigned long tmp;
> int result;
>
> __asm__ __volatile__(
> "1: ldrex %0, [%2]\n"
> " add %0, %0, %3\n"
> " strex %1, %0, [%2]\n"
> " teq %1, #0\n"
> " bne 1b"
> : "=&r" (result), "=&r" (tmp)
> : "r" (&v->counter), "Ir" (i)
> : "cc");
>
> return result;
>
> For < v6 architectures this isn't easy as they don't implement
> ldrex/strex. The atomic.h implementation won't work as it's a kernel
> only implementation using local_irq_save() and local_irq_restore() so
> obviously no use for userspace atomic add.
>
> After reading up for a while I've come across a very cunning trick in
> the kernel where an atomic compare/exchange is implemented in
> __kuser_cmpxchg. This is implemented in :
> arch/arm/kernel/entry-armv.S
>
> This tantalisingly comments :
> /*
> * For example, a user space atomic_add implementation could look like this:
> *
> * #define atomic_add(ptr, val) \
> * ({ register unsigned int *__ptr asm("r2") = (ptr); \
> * register unsigned int __result asm("r1"); \
> * asm volatile ( \
> * "1: @ atomic_add\n\t" \
> * "ldr r0, [r2]\n\t" \
> * "mov r3, #0xffff0fff\n\t" \
> * "add lr, pc, #4\n\t" \
> * "add r1, r0, %2\n\t" \
> * "add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t" \
> * "bcc 1b" \
> * : "=&r" (__result) \
> * : "r" (__ptr), "rIL" (val) \
> * : "r0","r3","ip","lr","cc","memory" ); \
> * __result; })
> */
>
> So translating this into librttest.h format gives :
> #elif defined(__arm__) && (__LINUX_ARM_ARCH__ < 6)
> register unsigned int result asm("r1");
>
> /* See, arm/kernel/entry-armv.S:__kernel_cmpxchg() */
> __asm__ __volatile__ (
> "1: ldr r0, [r2]\n\t"
> " mov r3, #0xffff0fff\n\t"
> " add lr, pc, #4\n\t"
> " add r1, r0, %2\n\t"
> " add pc, r3, #(0xffff0fc0 - 0xffff0fff)\n\t"
> " bcc 1b"
> : "=&r" (result)
> : "r" (&v->counter), "rIL" (i)
> : "r0","r3","ip","lr","cc","memory" );
>
> return result;
>
> Does this look reasonable to you guys?
CCing Gowrishankar from IBM.
Thanks,
-Garrett
------------------------------------------------------------------------------
Nokia and AT&T present the 2010 Calling All Innovators-North America contest
Create new apps & games for the Nokia N8 for consumers in U.S. and Canada
$10 million total in prizes - $4M cash, 500 devices, nearly $6M in marketing
Develop with Nokia Qt SDK, Web Runtime, or Java and Publish to Ovi Store
http://p.sf.net/sfu/nokia-dev2dev
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list