Source-Changes-HG archive

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

[src/trunk]: src rewrite the CPU identification on arm64:



details:   https://anonhg.NetBSD.org/src/rev/c76ee614ecb6
branches:  trunk
changeset: 446008:c76ee614ecb6
user:      mrg <mrg%NetBSD.org@localhost>
date:      Tue Nov 20 01:59:51 2018 +0000

description:
rewrite the CPU identification on arm64:

- publish per-cpu data
- publish a whole bunch of info in struct aarch64_sysctl_cpu_id
  instead of various individual nodes (there are 16 total.)
- add MIDR extractor bits
- define ARMv8.2-A id_aa64mmfr2_el1 and id_aa64zfr0_el1 regs,
  but avoid using them until we make sure they exist.  (these
  members are added to aarch64_sysctl_cpu_id to avoid future
  compat issues.)

the arm32 and aarch32 version of these need to be adjusted as
well (and aarch32 data published at all.)  still trying to
work out how to make the same userland binary running on a
real arm32 or an aarch32 system can work sanely here.

ok ryo@.

diffstat:

 external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c |  205 +++++++++-
 external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c     |  205 +++++++++-
 sys/arch/aarch64/aarch64/aarch64_machdep.c                     |  140 +------
 sys/arch/aarch64/aarch64/cpu.c                                 |  136 ++++-
 sys/arch/aarch64/aarch64/genassym.cf                           |    6 +-
 sys/arch/aarch64/include/armreg.h                              |   39 +-
 sys/arch/aarch64/include/cpu.h                                 |    7 +-
 usr.sbin/cpuctl/arch/aarch64.c                                 |  118 +----
 8 files changed, 577 insertions(+), 279 deletions(-)

diffs (truncated from 1197 to 300 lines):

diff -r 7c7f43381e94 -r c76ee614ecb6 external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c
--- a/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c    Tue Nov 20 01:23:06 2018 +0000
+++ b/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c    Tue Nov 20 01:59:51 2018 +0000
@@ -22,6 +22,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic-core.h"
 
 /* Defined in common/config/aarch64/aarch64-common.c.  */
 std::string aarch64_get_extension_string_for_isa_flags (unsigned long,
@@ -145,6 +146,208 @@
    ARGC and ARGV are set depending on the actual arguments given
    in the spec.  */
 
+#ifdef __NetBSD__
+/* The NetBSD/arm64 platform does not export linux-style cpuinfo,
+   but the data is available via a sysctl(3) interface.  */
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <aarch64/armreg.h>
+
+const char *
+host_detect_local_cpu (int argc, const char **argv)
+{
+  const char *arch_id = NULL;
+  const char *res = NULL;
+  static const int num_exts = ARRAY_SIZE (aarch64_extensions);
+  char buf[128];
+  bool arch = false;
+  bool tune = false;
+  bool cpu = false;
+  unsigned int i, curcpu;
+  unsigned int core_idx = 0;
+  const char* imps[2] = { NULL, NULL };
+  const char* cores[2] = { NULL, NULL };
+  unsigned int n_cores = 0;
+  unsigned int n_imps = 0;
+  bool processed_exts = false;
+  const char *ext_string = "";
+  unsigned long extension_flags = 0;
+  unsigned long default_flags = 0;
+  size_t len;
+  char impl_buf[8];
+  char part_buf[8];
+  int mib[2], ncpu;
+
+  gcc_assert (argc);
+
+  if (!argv[0])
+    goto not_found;
+
+  /* Are we processing -march, mtune or mcpu?  */
+  arch = strcmp (argv[0], "arch") == 0;
+  if (!arch)
+    tune = strcmp (argv[0], "tune") == 0;
+
+  if (!arch && !tune)
+    cpu = strcmp (argv[0], "cpu") == 0;
+
+  if (!arch && !tune && !cpu)
+    goto not_found;
+
+  mib[0] = CTL_HW;
+  mib[1] = HW_NCPU; 
+  len = sizeof(ncpu);
+  if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
+    goto not_found;
+
+  for (curcpu = 0; curcpu < ncpu; curcpu++)
+    {
+      char path[128];
+      struct aarch64_sysctl_cpu_id id;
+
+      len = sizeof id;
+      snprintf(path, sizeof path, "machdep.cpu%d.cpu_id", curcpu);
+      if (sysctlbyname(path, &id, &len, NULL, 0) != 0)
+        goto not_found;
+
+      snprintf(impl_buf, sizeof impl_buf, "0x%02x",
+              (int)__SHIFTOUT(id.ac_midr, MIDR_EL1_IMPL));
+      snprintf(part_buf, sizeof part_buf, "0x%02x",
+              (int)__SHIFTOUT(id.ac_midr, MIDR_EL1_PARTNUM));
+
+      for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+        if (strstr (impl_buf, aarch64_cpu_data[i].implementer_id) != NULL
+            && !contains_string_p (imps, aarch64_cpu_data[i].implementer_id))
+          {
+            if (n_imps == 2)
+              goto not_found;
+
+            imps[n_imps++] = aarch64_cpu_data[i].implementer_id;
+
+            break;
+          }
+
+      for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+        if (strstr (part_buf, aarch64_cpu_data[i].part_no) != NULL
+            && !contains_string_p (cores, aarch64_cpu_data[i].part_no))
+          {
+            if (n_cores == 2)
+              goto not_found;
+
+            cores[n_cores++] = aarch64_cpu_data[i].part_no;
+            core_idx = i;
+            arch_id = aarch64_cpu_data[i].arch;
+            break;
+          }
+
+      if (!tune && !processed_exts)
+        {
+          for (i = 0; i < num_exts; i++)
+            {
+              bool enabled;
+
+              if (strcmp(aarch64_extensions[i].ext, "fp") == 0)
+                enabled = (__SHIFTOUT(id.ac_aa64pfr0, ID_AA64PFR0_EL1_FP)
+                          == ID_AA64PFR0_EL1_FP_IMPL);
+              else if (strcmp(aarch64_extensions[i].ext, "simd") == 0)
+                enabled = (__SHIFTOUT(id.ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)
+                          == ID_AA64PFR0_EL1_ADV_SIMD_IMPL);
+              else if (strcmp(aarch64_extensions[i].ext, "crypto") == 0)
+                enabled = (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_AES)
+                          & ID_AA64ISAR0_EL1_AES_AES) != 0;
+              else if (strcmp(aarch64_extensions[i].ext, "crc") == 0)
+                enabled = (__SHIFTOUT(id.ac_aa64isar0, ID_AA64ISAR0_EL1_CRC32)
+                          == ID_AA64ISAR0_EL1_CRC32_CRC32X);
+              else if (strcmp(aarch64_extensions[i].ext, "lse") == 0)
+                enabled = false;
+              else
+               {
+                  warning(0, "Unknown extension '%s'", aarch64_extensions[i].ext);
+                 goto not_found;
+               }
+
+              if (enabled)
+                extension_flags |= aarch64_extensions[i].flag;
+              else
+                extension_flags &= ~(aarch64_extensions[i].flag);
+            }
+
+          processed_exts = true;
+       }
+    }
+
+  /* Weird cpuinfo format that we don't know how to handle.  */
+  if (n_cores == 0 || n_cores > 2 || n_imps != 1)
+    goto not_found;
+
+  if (arch && !arch_id)
+    goto not_found;
+
+  if (arch)
+    {
+      struct aarch64_arch_driver_info* arch_info = get_arch_from_id (arch_id);
+
+      /* We got some arch indentifier that's not in aarch64-arches.def?  */
+      if (!arch_info)
+       goto not_found;
+
+      res = concat ("-march=", arch_info->name, NULL);
+      default_flags = arch_info->flags;
+    }
+  /* We have big.LITTLE.  */
+  else if (n_cores == 2)
+    {
+      for (i = 0; aarch64_cpu_data[i].name != NULL; i++)
+       {
+         if (strchr (aarch64_cpu_data[i].part_no, '.') != NULL
+             && strncmp (aarch64_cpu_data[i].implementer_id,
+                         imps[0],
+                         strlen (imps[0]) - 1) == 0
+             && valid_bL_string_p (cores, aarch64_cpu_data[i].part_no))
+           {
+             res = concat ("-m",
+                           cpu ? "cpu" : "tune", "=",
+                           aarch64_cpu_data[i].name,
+                           NULL);
+             default_flags = aarch64_cpu_data[i].flags;
+             break;
+           }
+       }
+      if (!res)
+       goto not_found;
+    }
+  /* The simple, non-big.LITTLE case.  */
+  else
+    {
+      if (strncmp (aarch64_cpu_data[core_idx].implementer_id, imps[0],
+                  strlen (imps[0]) - 1) != 0)
+       goto not_found;
+
+      res = concat ("-m", cpu ? "cpu" : "tune", "=",
+                   aarch64_cpu_data[core_idx].name, NULL);
+      default_flags = aarch64_cpu_data[core_idx].flags;
+    }
+
+  if (tune)
+    return res;
+
+  ext_string
+    = aarch64_get_extension_string_for_isa_flags (extension_flags,
+                                                 default_flags).c_str ();
+
+  res = concat (res, ext_string, NULL);
+
+  return res;
+
+not_found:
+  {
+   /* If detection fails we ignore the option.
+      Clean up and return empty string.  */
+
+    return "";
+  }
+}
+#else
 const char *
 host_detect_local_cpu (int argc, const char **argv)
 {
@@ -338,4 +541,4 @@
     return "";
   }
 }
-
+#endif
diff -r 7c7f43381e94 -r c76ee614ecb6 external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c
--- a/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c        Tue Nov 20 01:23:06 2018 +0000
+++ b/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c        Tue Nov 20 01:59:51 2018 +0000
@@ -22,6 +22,7 @@
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "diagnostic-core.h"
 
 /* Defined in common/config/aarch64/aarch64-common.c.  */
 std::string aarch64_get_extension_string_for_isa_flags (unsigned long,
@@ -145,6 +146,208 @@
    ARGC and ARGV are set depending on the actual arguments given
    in the spec.  */
 
+#ifdef __NetBSD__
+/* The NetBSD/arm64 platform does not export linux-style cpuinfo,
+   but the data is available via a sysctl(3) interface.  */
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <aarch64/armreg.h>
+
+const char *
+host_detect_local_cpu (int argc, const char **argv)
+{
+  const char *arch_id = NULL;
+  const char *res = NULL;
+  static const int num_exts = ARRAY_SIZE (aarch64_extensions);
+  char buf[128];
+  bool arch = false;
+  bool tune = false;
+  bool cpu = false;
+  unsigned int i, curcpu;
+  unsigned int core_idx = 0;
+  const char* imps[2] = { NULL, NULL };
+  const char* cores[2] = { NULL, NULL };
+  unsigned int n_cores = 0;
+  unsigned int n_imps = 0;
+  bool processed_exts = false;
+  const char *ext_string = "";
+  unsigned long extension_flags = 0;
+  unsigned long default_flags = 0;
+  size_t len;
+  char impl_buf[8];
+  char part_buf[8];
+  int mib[2], ncpu;
+
+  gcc_assert (argc);
+
+  if (!argv[0])
+    goto not_found;
+
+  /* Are we processing -march, mtune or mcpu?  */
+  arch = strcmp (argv[0], "arch") == 0;
+  if (!arch)
+    tune = strcmp (argv[0], "tune") == 0;
+
+  if (!arch && !tune)
+    cpu = strcmp (argv[0], "cpu") == 0;
+
+  if (!arch && !tune && !cpu)
+    goto not_found;
+
+  mib[0] = CTL_HW;
+  mib[1] = HW_NCPU; 
+  len = sizeof(ncpu);
+  if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
+    goto not_found;
+
+  for (curcpu = 0; curcpu < ncpu; curcpu++)
+    {
+      char path[128];
+      struct aarch64_sysctl_cpu_id id;
+



Home | Main Index | Thread Index | Old Index