OSDN Git Service

unbreak support for ARM no MMU case
authorWaldemar Brodkorb <wbx@openadk.org>
Thu, 12 Feb 2015 20:06:43 +0000 (14:06 -0600)
committerWaldemar Brodkorb <wbx@openadk.org>
Thu, 12 Feb 2015 20:08:52 +0000 (14:08 -0600)
As suggested on the uCLibc mailing list:
http://lists.uclibc.org/pipermail/uclibc/2014-November/048702.html
http://lists.uclibc.org/pipermail/uclibc/2014-November/048703.html
http://lists.uclibc.org/pipermail/uclibc/2014-November/048704.html

extra/Configs/Config.arm
extra/Configs/Config.in
libc/sysdeps/linux/arm/clone.S
libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h

index a16c919..00cf982 100644 (file)
@@ -28,6 +28,7 @@ config CONFIG_ARM_EABI
 config COMPILE_IN_THUMB_MODE
        bool "Build using Thumb mode"
        select USE_BX
+       select USE_LDREXSTREX
        help
          Say 'y' here to force building uClibc in thumb mode.
          Say 'n' to use your compiler's default mode.
@@ -38,3 +39,10 @@ config USE_BX
          Say 'y' to use BX to return from functions on your thumb-aware
          processor. Say 'y' if you need to use interworking. Say 'n' if not.
          It is safe to say 'y' even if you're not doing interworking.
+
+config USE_LDREXSTREX
+       bool "Use load-store exclusive ASM ops (not supported in SmartFusion)"
+       depends on COMPILE_IN_THUMB_MODE
+       default n
+       help
+         Say 'y' to use LDREX/STREX ASM ops.
index c7a3b2d..31944be 100644 (file)
@@ -524,7 +524,6 @@ config LINUXTHREADS_OLD
        # linuxthreads and linuxthreads.old need nanosleep()
        select UCLIBC_HAS_REALTIME
        depends on !TARGET_arc && \
-                  !TARGET_arm && \
                   !TARGET_i386 && \
                   !TARGET_metag && \
                   !TARGET_mips && \
index 29045ef..d1c9239 100644 (file)
 #include <sys/syscall.h>
 #include <bits/arm_asm.h>
 #include <bits/arm_bx.h>
+
+#if defined __UCLIBC_HAS_THREADS__ && !defined __LINUXTHREADS_OLD__
 #include <sysdep-cancel.h>
+#endif
 
 #define CLONE_VM      0x00000100
 #define CLONE_THREAD  0x00010000
@@ -57,23 +60,22 @@ __clone:
        @ get flags
        mov     r0, r2
        @ new sp is already in r1
-       @ load remaining arguments off the stack
-       stmfd   sp!, {r4}
-       ldr     r2, [sp, #4]
-       ldr     r3, [sp, #8]
-       ldr     r4, [sp, #12]
        DO_CALL (clone)
        movs    a1, a1
        blt     __error
-       ldmnefd sp!, {r4}
        beq     1f
        bx      lr
 1:
 
        @ pick the function arg and call address off the stack and execute
        ldr     r0, [sp, #4]
+#if defined(__USE_BX__)
        ldr     r1, [sp]
        bl      2f      @ blx r1
+#else
+       mov     lr, pc
+       ldr     pc, [sp]
+#endif
 
        @ and we are done, passing the return value through r0
        bl      HIDDEN_JUMPTARGET(_exit)
index 438c12a..2b877f9 100644 (file)
 #ifndef _PT_MACHINE_H
 #define _PT_MACHINE_H   1
 
-#include <features.h>
+#include <sys/syscall.h>
+#include <unistd.h>
 
 #ifndef PT_EI
 # define PT_EI __extern_always_inline
 #endif
 
+#if defined(__thumb__)
+#if defined(__USE_LDREXSTREX__)
+PT_EI long int ldrex(int *spinlock)
+{
+       long int ret;
+       __asm__ __volatile__(
+               "ldrex %0, [%1]\n"
+               : "=r"(ret)
+               : "r"(spinlock) : "memory");
+       return ret;
+}
+
+PT_EI long int strex(int val, int *spinlock)
+{
+       long int ret;
+       __asm__ __volatile__(
+               "strex %0, %1, [%2]\n"
+               : "=r"(ret)
+               : "r" (val), "r"(spinlock) : "memory");
+       return ret;
+}
+
+/* Spinlock implementation; required.  */
+PT_EI long int
+testandset (int *spinlock)
+{
+  register unsigned int ret;
+
+  do {
+         ret = ldrex(spinlock);
+  } while (strex(1, spinlock));
+
+  return ret;
+}
+
+#else /* __USE_LDREXSTREX__ */
+
 /* This will not work on ARM1 or ARM2 because SWP is lacking on those
    machines.  Unfortunately we have no way to detect this at compile
    time; let's hope nobody tries to use one.  */
@@ -36,8 +74,6 @@ PT_EI long int testandset (int *spinlock);
 PT_EI long int testandset (int *spinlock)
 {
   register unsigned int ret;
-
-#if defined(__thumb__)
   void *pc;
   __asm__ __volatile__(
        ".align 0\n"
@@ -50,15 +86,21 @@ PT_EI long int testandset (int *spinlock)
        "\t.force_thumb"
        : "=r"(ret), "=r"(pc)
        : "0"(1), "r"(spinlock));
-#else
+  return ret;
+}
+#endif
+#else /* __thumb__ */
+
+PT_EI long int testandset (int *spinlock);
+PT_EI long int testandset (int *spinlock)
+{
+  register unsigned int ret;
   __asm__ __volatile__("swp %0, %1, [%2]"
                       : "=r"(ret)
                       : "0"(1), "r"(spinlock));
-#endif
-
   return ret;
 }
-
+#endif
 
 /* Get some notion of the current stack.  Need not be exactly the top
    of the stack, just something somewhere in the current frame.  */