Browse Source

Add LoongArch CPU support

* Add STRESSAPPTEST_CPU_LOONGARCH definition.
* Implement cpuid(), GetFeatures(), FastFlush() and GetTimestamp() or LoongArch.
* Eliminate "WARNING: Unsupported CPU ..." or similar warnings on LoongArch.
* update config.sub and config.guess for LoongArch

Signed-off-by: chenguoqi <chenguoqi@loongson.cn>
chenguoqi 2 years ago
parent
commit
3d3d1763fe
5 changed files with 63 additions and 24 deletions
  1. 10 6
      configure.ac
  2. 2 0
      src/os.cc
  3. 18 3
      src/os.h
  4. 2 0
      src/sattypes.h
  5. 31 15
      src/stressapptest_config.h.in

+ 10 - 6
configure.ac

@@ -25,28 +25,32 @@ AS_CASE(["$host_cpu"],
   [*x86_64*], [
     AC_DEFINE([STRESSAPPTEST_CPU_X86_64],[],
               [Defined if the target CPU is x86_64])
-    ], 
+    ],
   [*i686*], [
     AC_DEFINE([STRESSAPPTEST_CPU_I686],[],
               [Defined if the target CPU is i686])
-    ], 
+    ],
   [*mips*], [
     AC_DEFINE([STRESSAPPTEST_CPU_MIPS],[],
               [Defined if the target CPU is MIPS])
-    ], 
+    ],
   [*powerpc*], [
     AC_DEFINE([STRESSAPPTEST_CPU_PPC],[],
               [Defined if the target CPU is PowerPC])
-    ], 
+    ],
   [*armv7a*], [
     AC_DEFINE([STRESSAPPTEST_CPU_ARMV7A],[],
               [Defined if the target CPU is armv7a])
-    ], 
+    ],
   [*aarch64*], [
     AC_DEFINE([STRESSAPPTEST_CPU_AARCH64],[],
               [Defined if the target CPU is aarch64])
     ],
-[AC_MSG_WARN([Unsupported CPU: $host_cpu! Try x86_64, i686, mips, powerpc, armv7a, or aarch64])]
+  [*loongarch*], [
+    AC_DEFINE([STRESSAPPTEST_CPU_LOONGARCH],[],
+              [Defined if the target CPU is LOONGARCH])
+    ],
+[AC_MSG_WARN([Unsupported CPU: $host_cpu! Try x86_64, i686, mips, powerpc, armv7a, aarch64 or loongarch])]
 )
 
 ## The following allows like systems to share settings. This is not meant to

+ 2 - 0
src/os.cc

@@ -212,6 +212,8 @@ void OsLayer::GetFeatures() {
   // TODO(nsanders): add detect from /proc/cpuinfo or /proc/self/auxv.
   // For now assume neon and don't run -W if you don't have it.
   has_vector_ = true; // NEON.
+#elif defined(STRESSAPPTEST_CPU_LOONGARCH)
+  has_clflush_ = true;
 #else
 #warning "Unsupported CPU type: unable to determine feature set."
 #endif

+ 18 - 3
src/os.h

@@ -173,6 +173,9 @@ class OsLayer {
     asm volatile("ic ivau, %0" : : "r" (vaddr));
     asm volatile("dsb ish");
     asm volatile("isb");
+#elif defined(STRESSAPPTEST_CPU_LOONGARCH)
+    // Reference linux kernel: arch/loongarch/mm/cache.c
+    asm volatile("ibar 0");
 #else
   #warning "Unsupported CPU type: Unable to force cache flushes."
 #endif
@@ -203,7 +206,8 @@ class OsLayer {
       _mm_clflush(*vaddrs++);
     }
     _mm_mfence();
-#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || defined(STRESSAPPTEST_CPU_AARCH64)
+#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || \
+      defined(STRESSAPPTEST_CPU_AARCH64) || defined(STRESSAPPTEST_CPU_LOONGARCH)
     while (*vaddrs) {
       FastFlush(*vaddrs++);
     }
@@ -228,7 +232,8 @@ class OsLayer {
     // instruction. For example, software can use an MFENCE instruction to
     // insure that previous stores are included in the write-back.
     _mm_clflush(vaddr);
-#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || defined(STRESSAPPTEST_CPU_AARCH64)
+#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || \
+      defined(STRESSAPPTEST_CPU_AARCH64) || defined(STRESSAPPTEST_CPU_LOONGARCH)
     FastFlush(vaddr);
 #else
     #warning "Unsupported CPU type: Unable to force cache flushes."
@@ -253,7 +258,8 @@ class OsLayer {
     // instruction. For example, software can use an MFENCE instruction to
     // insure that previous stores are included in the write-back.
     _mm_mfence();
-#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || defined(STRESSAPPTEST_CPU_AARCH64)
+#elif defined(STRESSAPPTEST_CPU_MIPS) || defined(STRESSAPPTEST_CPU_ARMV7A) || \
+      defined(STRESSAPPTEST_CPU_AARCH64) || defined(STRESSAPPTEST_CPU_LOONGARCH)
     // This is a NOP, FastFlushHint() always does a full flush, so there's
     // nothing to do for FastFlushSync().
 #else
@@ -288,6 +294,15 @@ class OsLayer {
     tsc = 0;
 #elif defined(STRESSAPPTEST_CPU_AARCH64)
     __asm __volatile("mrs %0, CNTVCT_EL0" : "=r" (tsc) : : );
+#elif defined(STRESSAPPTEST_CPU_LOONGARCH)
+#if defined(__loongarch64)
+    __asm __volatile("rdtime.d %0, $r0\n" : "=r" (tsc));
+#else
+    uint64 ltsc, htsc;
+    __asm __volatile("rdtimel.w %0, $r0\n" : "=r" (ltsc));
+    __asm __volatile("rdtimeh.w %0, $r0\n" : "=r" (htsc));
+    tsc = ltsc | (htsc << 32);
+#endif
 #else
     #warning "Unsupported CPU type: your timer may not function correctly"
     tsc = 0;

+ 2 - 0
src/sattypes.h

@@ -233,6 +233,8 @@ inline void cpuid(
   return;
 #elif defined(STRESSAPPTEST_CPU_AARCH64)
   return;
+#elif defined(STRESSAPPTEST_CPU_LOONGARCH)
+  return;
 #else
 #warning "Unsupported CPU type."
 #endif

+ 31 - 15
src/stressapptest_config.h.in

@@ -1,6 +1,6 @@
 /* src/stressapptest_config.h.in.  Generated from configure.ac by autoheader.  */
 
-/* Define to 1 if the `closedir' function returns void instead of `int'. */
+/* Define to 1 if the `closedir' function returns void instead of int. */
 #undef CLOSEDIR_VOID
 
 /* Define to 1 if you have the <arpa/inet.h> header file. */
@@ -32,9 +32,6 @@
 /* Define to 1 if you have the <libaio.h> header file. */
 #undef HAVE_LIBAIO_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
 /* Define to 1 if you have the `memset' function. */
 #undef HAVE_MEMSET
 
@@ -59,6 +56,9 @@
 /* Define to 1 if you have the <pthread.h> header file. */
 #undef HAVE_PTHREAD_H
 
+/* Define to 1 if you have the `pthread_rwlockattr_setkind_np' function. */
+#undef HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP
+
 /* Define to 1 if you have the `rand_r' function. */
 #undef HAVE_RAND_R
 
@@ -77,10 +77,13 @@
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
-/* Define to 1 if you have the `strerror_r' function. */
+/* Define if you have `strerror_r'. */
 #undef HAVE_STRERROR_R
 
 /* Define to 1 if you have the <strings.h> header file. */
@@ -166,7 +169,9 @@
 /* Define to the type of arg 5 for `select'. */
 #undef SELECT_TYPE_ARG5
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
 /* Define to 1 if strerror_r returns char *. */
@@ -181,6 +186,9 @@
 /* Defined if the target CPU is i686 */
 #undef STRESSAPPTEST_CPU_I686
 
+/* Defined if the target CPU is LOONGARCH */
+#undef STRESSAPPTEST_CPU_LOONGARCH
+
 /* Defined if the target CPU is MIPS */
 #undef STRESSAPPTEST_CPU_MIPS
 
@@ -202,12 +210,19 @@
 /* Timestamp when ./configure was executed */
 #undef STRESSAPPTEST_TIMESTAMP
 
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. This
+   macro is obsolete. */
 #undef TIME_WITH_SYS_TIME
 
 /* Version number of package */
 #undef VERSION
 
+/* Number of bits in a file offset, on hosts where this is settable. */
+#undef _FILE_OFFSET_BITS
+
+/* Define for large files, on AIX-style hosts. */
+#undef _LARGE_FILES
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
@@ -217,19 +232,20 @@
 #undef inline
 #endif
 
-/* Define to `int' if <sys/types.h> does not define. */
+/* Define as a signed integer type capable of holding a process identifier. */
 #undef pid_t
 
 /* Define to the equivalent of the C99 'restrict' keyword, or to
    nothing if this is not supported.  Do not define if restrict is
-   supported directly.  */
+   supported only directly.  */
 #undef restrict
-/* Work around a bug in Sun C++: it does not support _Restrict or
-   __restrict__, even though the corresponding Sun C compiler ends up with
-   "#define restrict _Restrict" or "#define restrict __restrict__" in the
-   previous line.  Perhaps some future version of Sun C++ will work with
-   restrict; if so, hopefully it defines __RESTRICT like Sun C does.  */
-#if defined __SUNPRO_CC && !defined __RESTRICT
+/* Work around a bug in older versions of Sun C++, which did not
+   #define __restrict__ or support _Restrict or __restrict__
+   even though the corresponding Sun C compiler ended up with
+   "#define restrict _Restrict" or "#define restrict __restrict__"
+   in the previous line.  This workaround can be removed once
+   we assume Oracle Developer Studio 12.5 (2016) or later.  */
+#if defined __SUNPRO_CC && !defined __RESTRICT && !defined __restrict__
 # define _Restrict
 # define __restrict__
 #endif