pkgsrc-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

lang/nodejs and evbearm



Hi! all,


On OpenBlocks A6 (evbearm V5TE core) of 6.99.46, with some diffs, I built
lang/nodejs and worked.
It is working to Web server of HTTPS using client certification now, and
it is operating with 'fs' and 'child_process' module.  Maybe good!  :-)


However, the MP of ARMv7 will not work. 
Furthermore, the multithread which uses cluster module may not operate
correctly.

And gcc reports error:
  /var/tmp//ccNwICKV.s: Assembler messages:
  /var/tmp//ccNwICKV.s:187: Error: selected processor does not support ARM mode 
`ldrex ip,[r2]'
  /var/tmp//ccNwICKV.s:190: Error: selected processor does not support ARM mode 
`strexeq r3,r1,[r2]'

Do you know pre-processing macros for ARMv7?

in diff6 --->
+#ifdef __ARMv7_definition      // I don't know...  tested only v5 machine
+               asm volatile(
+                   "ldrex      %1, [%2]\n"
+                   "mov        %0, #0\n"
+                   "teq        %1, %3\n"
+                   "strexeq    %0, %4, [%2]\n"
+                   : "=&r"(res), "=&r"(oldval)
+                   : "r"(ptr), "Ir"(old_value), "r"(new_value)
+                   : "memory", "cc");
+#endif
<--- in diff6

Have you better idea?


Thanks,
--
kiyohara

--- work/node-v0.10.29/deps/v8/src/platform-openbsd.cc.orig     2014-06-10 
02:04:36.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/platform-openbsd.cc  2014-08-30 
16:07:23.000000000 +0900
@@ -46,6 +46,7 @@
 #include <strings.h>    // index
 #include <errno.h>
 #include <stdarg.h>
+#include <ctype.h>
 
 #undef MAP_TYPE
 
@@ -211,10 +212,126 @@
 
 
 void OS::DebugBreak() {
+#if (defined(__arm__) || defined(__thumb__))
+# if defined(CAN_USE_ARMV5_INSTRUCTIONS)
+  asm("bkpt 0");
+# endif
+#else
   asm("int $3");
+#endif
 }
 
 
+#ifdef __NetBSD__
+static bool DmesgBootContainsString(const char * driver, const char * 
search_string) {
+  const char* file_name = "/var/run/dmesg.boot";
+  FILE* f = NULL;
+  const char* who = driver;
+  const char* what = search_string;
+  char *s;
+  size_t size;
+
+  if (search_string == NULL)
+    return false;
+
+  if (NULL == (f = fopen(file_name, "r")))
+    return false;
+
+  unsigned int i;
+  while (NULL != (s = fgetln(f, &size))) {
+    i = 0;
+    if (who != NULL) {
+      for ( ; i < size && *who != '\0'; i++, who++)
+       if (*who != s[i])
+          break;
+      if (*who != '\0') {
+       who = driver;
+       continue;
+      }
+      while (i < size && isdigit(s[i]))
+       i++;
+      if (i == size || (s[i] != ':' && s[i] != ' ')) {
+       who = driver;
+        continue;
+      }
+    }
+    while (i < size) {
+      if (s[i++] == *what) {
+        ++what;
+        while (*what != '\0' && i < size && *what == s[i++]) {
+          ++what;
+        }
+        if (*what == '\0') {
+          fclose(f);
+          return true;
+        } else {
+          what = search_string;
+        }
+      }
+    }
+    who = driver;
+  }
+  fclose(f);
+
+  // Did not find string in the dmesg.boot.
+  return false;
+}
+
+
+#ifdef __arm__
+bool OS::ArmCpuHasFeature(CpuFeature feature) {
+  const char* search_driver = NULL;
+  const char* search_string = NULL;
+  switch (feature) {
+//    case VFP2:
+//      search_driver = "vfp";
+//      search_string = "vfp";
+//      break;
+    case VFP3:
+      search_driver = "vfp";
+      search_string = " VFP3,";
+      break;
+    case ARMv7:
+      search_driver = "cpu";
+      search_string = " V7";
+      break;
+//    case SUDIV:
+//      search_driver = "vfp";
+//      search_string = "idiva";
+//      break;
+    default:
+      UNREACHABLE();
+  }
+
+  if (DmesgBootContainsString(search_driver, search_string)) {
+    return true;
+  }
+
+  if (feature == VFP3) {
+    if (DmesgBootContainsString("vfp", " VFP 4.0+,") || 
DmesgBootContainsString("vfp", " NEON MPE (VFP 3.0+),")) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
+
+CpuImplementer OS::GetCpuImplementer() {
+  static bool use_cached_value = false;
+  static CpuImplementer cached_value = UNKNOWN_IMPLEMENTER;
+  if (use_cached_value) {
+    return cached_value;
+  }
+  /* XXXX: always Implementer ARM? */
+  /* XXXX: or find SoC on dmesg.boot? */
+  cached_value = ARM_IMPLEMENTER;
+  use_cached_value = true;
+  return cached_value;
+}
+#endif
+#endif
+
 class PosixMemoryMappedFile : public OS::MemoryMappedFile {
  public:
   PosixMemoryMappedFile(FILE* file, void* memory, int size)
--- work/node-v0.10.29/deps/v8/src/atomicops_internals_arm_gcc.h.orig   
2014-06-10 02:04:36.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/atomicops_internals_arm_gcc.h        
2014-09-02 11:01:30.000000000 +0900
@@ -35,28 +35,44 @@
 namespace v8 {
 namespace internal {
 
+typedef Atomic32 (*CmpxchgFunc)(Atomic32 old_value,
+                                Atomic32 new_value,
+                                volatile Atomic32* ptr);
+#ifdef __linux__
 // 0xffff0fc0 is the hard coded address of a function provided by
 // the kernel which implements an atomic compare-exchange. On older
 // ARM architecture revisions (pre-v6) this may be implemented using
 // a syscall. This address is stable, and in active use (hard coded)
 // by at least glibc-2.7 and the Android C library.
-typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value,
-                                           Atomic32 new_value,
-                                           volatile Atomic32* ptr);
-LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) =
-    (LinuxKernelCmpxchgFunc) 0xffff0fc0;
+CmpxchgFunc pCmpxchg __attribute__((weak)) = (CmpxchgFunc) 0xffff0fc0;
 
 typedef void (*LinuxKernelMemoryBarrierFunc)(void);
 LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) =
     (LinuxKernelMemoryBarrierFunc) 0xffff0fa0;
 
+#else
+
+static Atomic32
+V5CmpxchgFunc(Atomic32 old_value, Atomic32 new_value, volatile Atomic32* ptr)
+{
+       Atomic32 prev;
+
+       // Must disable interrupts?
+       prev = *ptr;
+       if (prev == old_value)
+               *ptr = new_value;
+       return prev;
+}
+CmpxchgFunc pCmpxchg __attribute__((weak)) = V5CmpxchgFunc;
+#endif
+
 
 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
                                          Atomic32 old_value,
                                          Atomic32 new_value) {
   Atomic32 prev_value = *ptr;
   do {
-    if (!pLinuxKernelCmpxchg(old_value, new_value,
+    if (!pCmpxchg(old_value, new_value,
                              const_cast<Atomic32*>(ptr))) {
       return old_value;
     }
@@ -70,7 +86,7 @@
   Atomic32 old_value;
   do {
     old_value = *ptr;
-  } while (pLinuxKernelCmpxchg(old_value, new_value,
+  } while (pCmpxchg(old_value, new_value,
                                const_cast<Atomic32*>(ptr)));
   return old_value;
 }
@@ -86,7 +102,7 @@
     // Atomic exchange the old value with an incremented one.
     Atomic32 old_value = *ptr;
     Atomic32 new_value = old_value + increment;
-    if (pLinuxKernelCmpxchg(old_value, new_value,
+    if (pCmpxchg(old_value, new_value,
                             const_cast<Atomic32*>(ptr)) == 0) {
       // The exchange took place as expected.
       return new_value;
@@ -112,7 +128,11 @@
 }
 
 inline void MemoryBarrier() {
+#ifdef __linux__
   pLinuxKernelMemoryBarrier();
+#else
+  __sync_synchronize();
+#endif
 }
 
 inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
--- work/node-v0.10.29/deps/v8/src/arm/cpu-arm.cc.orig  2014-06-10 
02:04:36.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/arm/cpu-arm.cc       2014-08-29 
22:58:18.000000000 +0900
@@ -65,44 +65,7 @@
   // around whether or not to generate the code when building snapshots.
   Simulator::FlushICache(Isolate::Current()->simulator_i_cache(), start, size);
 #else
-  // Ideally, we would call
-  //   syscall(__ARM_NR_cacheflush, start,
-  //           reinterpret_cast<intptr_t>(start) + size, 0);
-  // however, syscall(int, ...) is not supported on all platforms, especially
-  // not when using EABI, so we call the __ARM_NR_cacheflush syscall directly.
-
-  register uint32_t beg asm("a1") = reinterpret_cast<uint32_t>(start);
-  register uint32_t end asm("a2") =
-      reinterpret_cast<uint32_t>(start) + size;
-  register uint32_t flg asm("a3") = 0;
-  #if defined (__arm__) && !defined(__thumb__)
-    // __arm__ may be defined in thumb mode.
-    register uint32_t scno asm("r7") = __ARM_NR_cacheflush;
-    asm volatile(
-        "svc 0x0"
-        : "=r" (beg)
-        : "0" (beg), "r" (end), "r" (flg), "r" (scno));
-  #else
-    // r7 is reserved by the EABI in thumb mode.
-    asm volatile(
-    "@   Enter ARM Mode  \n\t"
-        "adr r3, 1f      \n\t"
-        "bx  r3          \n\t"
-        ".ALIGN 4        \n\t"
-        ".ARM            \n"
-    "1:  push {r7}       \n\t"
-        "mov r7, %4      \n\t"
-        "svc 0x0         \n\t"
-        "pop {r7}        \n\t"
-    "@   Enter THUMB Mode\n\t"
-        "adr r3, 2f+1    \n\t"
-        "bx  r3          \n\t"
-        ".THUMB          \n"
-    "2:                  \n\t"
-        : "=r" (beg)
-        : "0" (beg), "r" (end), "r" (flg), "r" (__ARM_NR_cacheflush)
-        : "r3");
-  #endif
+  __builtin___clear_cache(start, start + size);
 #endif
 }
 
--- work/node-v0.10.29/deps/v8/src/atomicops.h.orig     2014-08-27 
10:41:00.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/atomicops.h  2014-08-27 10:42:04.000000000 
+0900
@@ -69,7 +69,7 @@
 
 // Use AtomicWord for a machine-sized pointer.  It will use the Atomic32 or
 // Atomic64 routines below, depending on your architecture.
-#if defined(__OpenBSD__) && defined(__i386__)
+#ifndef _LP64
 typedef Atomic32 AtomicWord;
 #else
 typedef intptr_t AtomicWord;
--- work/node-v0.10.29/deps/v8/src/platform.h.orig      2014-08-27 
10:40:29.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/platform.h   2014-08-27 10:40:13.000000000 
+0900
@@ -110,7 +110,7 @@
 
 // Use AtomicWord for a machine-sized pointer. It is assumed that
 // reads and writes of naturally aligned values of this type are atomic.
-#if defined(__OpenBSD__) && defined(__i386__)
+#ifndef _LP64
 typedef Atomic32 AtomicWord;
 #else
 typedef intptr_t AtomicWord;
--- work/node-v0.10.29/deps/v8/src/objects-inl.h.orig   2014-08-29 
22:46:21.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/objects-inl.h        2014-08-29 
22:46:26.000000000 +0900
@@ -892,11 +892,11 @@
     }                                                                   \
   }
 
-#ifndef V8_TARGET_ARCH_MIPS
+#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32)
   #define READ_DOUBLE_FIELD(p, offset) \
     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
-#else  // V8_TARGET_ARCH_MIPS
-  // Prevent gcc from using load-double (mips ldc1) on (possibly)
+#else
+  // Prevent gcc from using load-double on (possibly)
   // non-64-bit aligned HeapNumber::value.
   static inline double read_double_field(void* p, int offset) {
     union conversion {
@@ -908,13 +908,13 @@
     return c.d;
   }
   #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
-#endif  // V8_TARGET_ARCH_MIPS
+#endif
 
-#ifndef V8_TARGET_ARCH_MIPS
+#if defined(V8_TARGET_ARCH_X64) || defined(V8_TARGET_ARCH_IA32)
   #define WRITE_DOUBLE_FIELD(p, offset, value) \
     (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
-#else  // V8_TARGET_ARCH_MIPS
-  // Prevent gcc from using store-double (mips sdc1) on (possibly)
+#else
+  // Prevent gcc from using store-double on (possibly)
   // non-64-bit aligned HeapNumber::value.
   static inline void write_double_field(void* p, int offset,
                                         double value) {
--- work/node-v0.10.29/deps/v8/src/arm/assembler-arm.cc.orig    2014-09-02 
16:43:34.000000000 +0900
+++ work/node-v0.10.29/deps/v8/src/arm/assembler-arm.cc 2014-09-02 
16:38:59.000000000 +0900
@@ -85,6 +85,28 @@
 }
 
 
+// This function supports ARMv7 MP?
+static Atomic32
+V7CmpxchgFunc(Atomic32 old_value, Atomic32 new_value, volatile Atomic32* ptr)
+{
+       unsigned long oldval, res;
+
+       __builtin_prefetch((void *)ptr, 1);
+       do {
+#ifdef __ARMv7_definition      // I don't know...  tested only v5 machine
+               asm volatile(
+                   "ldrex      %1, [%2]\n"
+                   "mov        %0, #0\n"
+                   "teq        %1, %3\n"
+                   "strexeq    %0, %4, [%2]\n"
+                   : "=&r"(res), "=&r"(oldval)
+                   : "r"(ptr), "Ir"(old_value), "r"(new_value)
+                   : "memory", "cc");
+#endif
+       } while (res);
+       return old_value;
+}
+
 void CpuFeatures::Probe() {
   unsigned standard_features = static_cast<unsigned>(
       OS::CpuFeaturesImpliedByPlatform()) | CpuFeaturesImpliedByCompiler();
@@ -150,6 +172,11 @@
   }
 
   supported_ |= found_by_runtime_probing_;
+
+  if (IsSupported(ARMv7)) {
+    extern CmpxchgFunc pCmpxchg __attribute__((weak));
+    pCmpxchg = V7CmpxchgFunc;
+  }
 #endif
 
   // Assert that VFP3 implies VFP2 and ARMv7.


Home | Main Index | Thread Index | Old Index