Module Name:    src
Committed By:   mrg
Date:           Tue Nov 20 01:59:51 UTC 2018

Modified Files:
        src/external/gpl3/gcc.old/dist/gcc/config/aarch64: driver-aarch64.c
        src/external/gpl3/gcc/dist/gcc/config/aarch64: driver-aarch64.c
        src/sys/arch/aarch64/aarch64: aarch64_machdep.c cpu.c genassym.cf
        src/sys/arch/aarch64/include: armreg.h cpu.h
        src/usr.sbin/cpuctl/arch: aarch64.c

Log Message:
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@.


To generate a diff of this commit:
cvs rdiff -u -r1.1.1.1 -r1.2 \
    src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c
cvs rdiff -u -r1.1.1.1 -r1.2 \
    src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/aarch64/aarch64/aarch64_machdep.c
cvs rdiff -u -r1.12 -r1.13 src/sys/arch/aarch64/aarch64/cpu.c
cvs rdiff -u -r1.8 -r1.9 src/sys/arch/aarch64/aarch64/genassym.cf
cvs rdiff -u -r1.20 -r1.21 src/sys/arch/aarch64/include/armreg.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/aarch64/include/cpu.h
cvs rdiff -u -r1.2 -r1.3 src/usr.sbin/cpuctl/arch/aarch64.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c
diff -u src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c:1.1.1.1 src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c:1.2
--- src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c:1.1.1.1	Wed Aug  1 22:18:36 2018
+++ src/external/gpl3/gcc.old/dist/gcc/config/aarch64/driver-aarch64.c	Tue Nov 20 01:59:51 2018
@@ -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 @@ contains_string_p (const char** arr, con
    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 @@ not_found:
     return "";
   }
 }
-
+#endif

Index: src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c
diff -u src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c:1.1.1.1 src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c:1.2
--- src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c:1.1.1.1	Fri Feb  2 01:59:49 2018
+++ src/external/gpl3/gcc/dist/gcc/config/aarch64/driver-aarch64.c	Tue Nov 20 01:59:51 2018
@@ -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 @@ contains_string_p (const char** arr, con
    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 @@ not_found:
     return "";
   }
 }
-
+#endif

Index: src/sys/arch/aarch64/aarch64/aarch64_machdep.c
diff -u src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.21 src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.22
--- src/sys/arch/aarch64/aarch64/aarch64_machdep.c:1.21	Tue Nov 13 10:30:35 2018
+++ src/sys/arch/aarch64/aarch64/aarch64_machdep.c	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: aarch64_machdep.c,v 1.21 2018/11/13 10:30:35 jmcneill Exp $ */
+/* $NetBSD: aarch64_machdep.c,v 1.22 2018/11/20 01:59:51 mrg Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.21 2018/11/13 10:30:35 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: aarch64_machdep.c,v 1.22 2018/11/20 01:59:51 mrg Exp $");
 
 #include "opt_arm_debug.h"
 #include "opt_ddb.h"
@@ -45,7 +45,6 @@ __KERNEL_RCSID(1, "$NetBSD: aarch64_mach
 #include <sys/kauth.h>
 #include <sys/module.h>
 #include <sys/msgbuf.h>
-#include <sys/sysctl.h>
 #include <sys/reboot.h>
 #include <sys/kcore.h>
 #include <sys/core.h>
@@ -83,15 +82,6 @@ char cpu_model[32];
 char machine[] = MACHINE;
 char machine_arch[] = MACHINE_ARCH;
 
-/* sysctl node num */
-static int sysctlnode_machdep_cpu_id;
-static int sysctlnode_machdep_id_revidr;
-static int sysctlnode_machdep_id_mvfr;
-static int sysctlnode_machdep_id_mpidr;
-static int sysctlnode_machdep_id_aa64isar;
-static int sysctlnode_machdep_id_aa64mmfr;
-static int sysctlnode_machdep_id_aa64pfr;
-
 const pcu_ops_t * const pcu_ops_md_defs[PCU_UNIT_COUNT] = {
 	[PCU_FPU] = &pcu_fpu_ops
 };
@@ -394,132 +384,6 @@ initarm_common(vaddr_t kvm_base, vsize_t
 	return (vaddr_t)tf;
 }
 
-/*
- * machine dependent system variables.
- */
-static int
-aarch64_sysctl_machdep_sysreg_helper(SYSCTLFN_ARGS)
-{
-	struct sysctlnode node;
-#define MAX_SYSCTLREGS	8
-	uint64_t databuf[MAX_SYSCTLREGS];
-	void *data;
-
-	node = *rnode;
-	node.sysctl_data = data = (void *)databuf;
-
-	/*
-	 * Don't keep values in advance due to system registers may have
-	 * different values on each CPU cores. (e.g. big.LITTLE)
-	 */
-	if (rnode->sysctl_num == sysctlnode_machdep_cpu_id) {
-		((uint32_t *)data)[0] = reg_midr_el1_read();
-		node.sysctl_size = sizeof(uint32_t);
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_revidr) {
-		((uint32_t *)data)[0] = reg_revidr_el1_read();
-		node.sysctl_size = sizeof(uint32_t);
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_mvfr) {
-		((uint32_t *)data)[0] = reg_mvfr0_el1_read();
-		((uint32_t *)data)[1] = reg_mvfr1_el1_read();
-		((uint32_t *)data)[2] = reg_mvfr2_el1_read();
-		node.sysctl_size = sizeof(uint32_t) * 3;
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_mpidr) {
-		((uint64_t *)data)[0] = reg_mpidr_el1_read();
-		node.sysctl_size = sizeof(uint64_t);
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_aa64isar) {
-		((uint64_t *)data)[0] = reg_id_aa64isar0_el1_read();
-		((uint64_t *)data)[1] = reg_id_aa64isar1_el1_read();
-		node.sysctl_size = sizeof(uint64_t) * 2;
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_aa64mmfr) {
-		((uint64_t *)data)[0] = reg_id_aa64mmfr0_el1_read();
-		((uint64_t *)data)[1] = reg_id_aa64mmfr1_el1_read();
-		node.sysctl_size = sizeof(uint64_t) * 2;
-
-	} else if (rnode->sysctl_num == sysctlnode_machdep_id_aa64pfr) {
-		((uint64_t *)data)[0] = reg_id_aa64pfr0_el1_read();
-		((uint64_t *)data)[1] = reg_id_aa64pfr1_el1_read();
-		node.sysctl_size = sizeof(uint64_t) * 2;
-
-	} else {
-		return EOPNOTSUPP;
-	}
-
-	return sysctl_lookup(SYSCTLFN_CALL(&node));
-}
-
-SYSCTL_SETUP(sysctl_machdep_setup, "sysctl machdep subtree setup")
-{
-	const struct sysctlnode *node;
-
-	sysctl_createv(clog, 0, NULL, NULL,
-	    CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
-	    NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_INT,
-	    "cpu_id",
-	    SYSCTL_DESCR("MIDR_EL1, Main ID Register"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_cpu_id = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_INT,
-	    "id_revidr",
-	    SYSCTL_DESCR("REVIDR_EL1, Revision ID Register"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_revidr = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRUCT,
-	    "id_mvfr",
-	    SYSCTL_DESCR("MVFRn_EL1, Media and VFP Feature Registers"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_mvfr = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRUCT,
-	    "id_mpidr",
-	    SYSCTL_DESCR("MPIDR_EL1, Multiprocessor Affinity Register"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_mpidr = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRUCT,
-	    "id_aa64isar",
-	    SYSCTL_DESCR("ID_AA64ISARn_EL1, "
-	    "AArch64 Instruction Set Attribute Registers"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_aa64isar = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRUCT,
-	    "id_aa64mmfr",
-	    SYSCTL_DESCR("ID_AA64MMFRn_EL1, "
-	    "AArch64 Memory Model Feature Registers"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_aa64mmfr = node->sysctl_num;
-
-	sysctl_createv(clog, 0, NULL, &node,
-	    CTLFLAG_PERMANENT|CTLFLAG_READONLY, CTLTYPE_STRUCT,
-	    "id_aa64pfr",
-	    SYSCTL_DESCR("ID_AA64PFRn_EL1, "
-	    "AArch64 Processor Feature Registers"),
-	    aarch64_sysctl_machdep_sysreg_helper, 0, NULL, 0,
-	    CTL_MACHDEP, CTL_CREATE, CTL_EOL);
-	sysctlnode_machdep_id_aa64pfr = node->sysctl_num;
-}
-
 void
 parse_mi_bootargs(char *args)
 {

Index: src/sys/arch/aarch64/aarch64/cpu.c
diff -u src/sys/arch/aarch64/aarch64/cpu.c:1.12 src/sys/arch/aarch64/aarch64/cpu.c:1.13
--- src/sys/arch/aarch64/aarch64/cpu.c:1.12	Sun Oct 14 14:31:05 2018
+++ src/sys/arch/aarch64/aarch64/cpu.c	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.12 2018/10/14 14:31:05 skrll Exp $ */
+/* $NetBSD: cpu.c,v 1.13 2018/11/20 01:59:51 mrg Exp $ */
 
 /*
  * Copyright (c) 2017 Ryo Shimizu <r...@nerv.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.12 2018/10/14 14:31:05 skrll Exp $");
+__KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.13 2018/11/20 01:59:51 mrg Exp $");
 
 #include "locators.h"
 #include "opt_arm_debug.h"
@@ -40,6 +40,7 @@ __KERNEL_RCSID(1, "$NetBSD: cpu.c,v 1.12
 #include <sys/device.h>
 #include <sys/cpu.h>
 #include <sys/kmem.h>
+#include <sys/sysctl.h>
 
 #include <aarch64/armreg.h>
 #include <aarch64/cpu.h>
@@ -61,6 +62,8 @@ static void identify_aarch64_model(uint3
 static void cpu_identify(device_t self, struct cpu_info *);
 static void cpu_identify1(device_t self, struct cpu_info *);
 static void cpu_identify2(device_t self, struct cpu_info *);
+static void cpu_setup_id(struct cpu_info *);
+static void cpu_setup_sysctl(device_t, struct cpu_info *);
 
 #ifdef MULTIPROCESSOR
 uint64_t cpu_mpidr[MAXCPUS];
@@ -103,8 +106,7 @@ cpu_attach(device_t dv, cpuid_t id)
 	if (unit == 0) {
 		ci = curcpu();
 		ci->ci_cpuid = id;
-		cpu_info_store[unit].ci_midr = reg_midr_el1_read();
-		cpu_info_store[unit].ci_mpidr = reg_mpidr_el1_read();
+		cpu_setup_id(ci);
 	} else {
 #ifdef MULTIPROCESSOR
 		KASSERT(unit < MAXCPUS);
@@ -112,8 +114,9 @@ cpu_attach(device_t dv, cpuid_t id)
 
 		ci->ci_cpl = IPL_HIGH;
 		ci->ci_cpuid = id;
+		// XXX big.LITTLE
 		ci->ci_data.cpu_cc_freq = cpu_info_store[0].ci_data.cpu_cc_freq;
-		/* ci_{midr,mpidr} are stored by own cpus when hatching */
+		/* ci_id is stored by own cpus when hatching */
 
 		cpu_info[ncpu] = ci;
 		if ((arm_cpu_hatched & __BIT(unit)) == 0) {
@@ -132,7 +135,7 @@ cpu_attach(device_t dv, cpuid_t id)
 #endif /* MULTIPROCESSOR */
 	}
 
-	mpidr = ci->ci_mpidr;
+	mpidr = ci->ci_id.ac_mpidr;
 	if (mpidr & MPIDR_MT) {
 		ci->ci_data.cpu_smt_id = __SHIFTOUT(mpidr, MPIDR_AFF0);
 		ci->ci_data.cpu_core_id = __SHIFTOUT(mpidr, MPIDR_AFF1);
@@ -159,6 +162,8 @@ cpu_attach(device_t dv, cpuid_t id)
 	aarch64_getcacheinfo();
 	aarch64_printcacheinfo(dv);
 	cpu_identify2(dv, ci);
+
+	cpu_setup_sysctl(dv, ci);
 }
 
 struct cpuidtab {
@@ -211,7 +216,7 @@ cpu_identify(device_t self, struct cpu_i
 {
 	char model[128];
 
-	identify_aarch64_model(ci->ci_midr, model, sizeof(model));
+	identify_aarch64_model(ci->ci_id.ac_midr, model, sizeof(model));
 	if (ci->ci_index == 0)
 		cpu_setmodel("%s", model);
 
@@ -279,23 +284,17 @@ cpu_identify1(device_t self, struct cpu_
 static void
 cpu_identify2(device_t self, struct cpu_info *ci)
 {
-	uint64_t aidr, revidr;
-	uint64_t dfr0, mmfr0;
-	uint64_t isar0, pfr0, mvfr0, mvfr1;
+	struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
+	uint64_t dfr0;
 
-	aidr = reg_id_aa64isar0_el1_read();
-	revidr = reg_revidr_el1_read();
+	if (!CPU_IS_PRIMARY(ci)) {
+		cpu_setup_id(ci);
+		cpu_setup_sysctl(self, ci);
+	}
 
 	dfr0 = reg_id_aa64dfr0_el1_read();
-	mmfr0 = reg_id_aa64mmfr0_el1_read();
-
-	isar0 = reg_id_aa64isar0_el1_read();
-	pfr0 = reg_id_aa64pfr0_el1_read();
-	mvfr0 = reg_mvfr0_el1_read();
-	mvfr1 = reg_mvfr1_el1_read();
-
 
-	aprint_normal_dev(self, "revID=0x%" PRIx64, revidr);
+	aprint_normal_dev(self, "revID=0x%" PRIx64, id->ac_revidr);
 
 	/* ID_AA64DFR0_EL1 */
 	switch (__SHIFTOUT(dfr0, ID_AA64DFR0_EL1_PMUVER)) {
@@ -308,23 +307,23 @@ cpu_identify2(device_t self, struct cpu_
 	}
 
 	/* ID_AA64MMFR0_EL1 */
-	switch (__SHIFTOUT(mmfr0, ID_AA64MMFR0_EL1_TGRAN4)) {
+	switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN4)) {
 	case ID_AA64MMFR0_EL1_TGRAN4_4KB:
 		aprint_normal(", 4k table");
 		break;
 	}
-	switch (__SHIFTOUT(mmfr0, ID_AA64MMFR0_EL1_TGRAN16)) {
+	switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN16)) {
 	case ID_AA64MMFR0_EL1_TGRAN16_16KB:
 		aprint_normal(", 16k table");
 		break;
 	}
-	switch (__SHIFTOUT(mmfr0, ID_AA64MMFR0_EL1_TGRAN64)) {
+	switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_TGRAN64)) {
 	case ID_AA64MMFR0_EL1_TGRAN64_64KB:
 		aprint_normal(", 64k table");
 		break;
 	}
 
-	switch (__SHIFTOUT(mmfr0, ID_AA64MMFR0_EL1_ASIDBITS)) {
+	switch (__SHIFTOUT(id->ac_aa64mmfr0, ID_AA64MMFR0_EL1_ASIDBITS)) {
 	case ID_AA64MMFR0_EL1_ASIDBITS_8BIT:
 		aprint_normal(", 8bit ASID");
 		break;
@@ -336,37 +335,37 @@ cpu_identify2(device_t self, struct cpu_
 
 
 
-	aprint_normal_dev(self, "auxID=0x%" PRIx64, aidr);
+	aprint_normal_dev(self, "auxID=0x%" PRIx64, ci->ci_id.ac_aa64isar0);
 
 	/* PFR0 */
-	switch (__SHIFTOUT(pfr0, ID_AA64PFR0_EL1_GIC)) {
+	switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_GIC)) {
 	case ID_AA64PFR0_EL1_GIC_CPUIF_EN:
 		aprint_normal(", GICv3");
 		break;
 	}
-	switch (__SHIFTOUT(pfr0, ID_AA64PFR0_EL1_FP)) {
+	switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_FP)) {
 	case ID_AA64PFR0_EL1_FP_IMPL:
 		aprint_normal(", FP");
 		break;
 	}
 
 	/* ISAR0 */
-	switch (__SHIFTOUT(isar0, ID_AA64ISAR0_EL1_CRC32)) {
+	switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_CRC32)) {
 	case ID_AA64ISAR0_EL1_CRC32_CRC32X:
 		aprint_normal(", CRC32");
 		break;
 	}
-	switch (__SHIFTOUT(isar0, ID_AA64ISAR0_EL1_SHA1)) {
+	switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA1)) {
 	case ID_AA64ISAR0_EL1_SHA1_SHA1CPMHSU:
 		aprint_normal(", SHA1");
 		break;
 	}
-	switch (__SHIFTOUT(isar0, ID_AA64ISAR0_EL1_SHA2)) {
+	switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_SHA2)) {
 	case ID_AA64ISAR0_EL1_SHA2_SHA256HSU:
 		aprint_normal(", SHA256");
 		break;
 	}
-	switch (__SHIFTOUT(isar0, ID_AA64ISAR0_EL1_AES)) {
+	switch (__SHIFTOUT(id->ac_aa64isar0, ID_AA64ISAR0_EL1_AES)) {
 	case ID_AA64ISAR0_EL1_AES_AES:
 		aprint_normal(", AES");
 		break;
@@ -377,34 +376,34 @@ cpu_identify2(device_t self, struct cpu_
 
 
 	/* PFR0:AdvSIMD */
-	switch (__SHIFTOUT(pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
+	switch (__SHIFTOUT(id->ac_aa64pfr0, ID_AA64PFR0_EL1_ADVSIMD)) {
 	case ID_AA64PFR0_EL1_ADV_SIMD_IMPL:
 		aprint_normal(", NEON");
 		break;
 	}
 
 	/* MVFR0/MVFR1 */
-	switch (__SHIFTOUT(mvfr0, MVFR0_FPROUND)) {
+	switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPROUND)) {
 	case MVFR0_FPROUND_ALL:
 		aprint_normal(", rounding");
 		break;
 	}
-	switch (__SHIFTOUT(mvfr0, MVFR0_FPTRAP)) {
+	switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_FPTRAP)) {
 	case MVFR0_FPTRAP_TRAP:
 		aprint_normal(", exceptions");
 		break;
 	}
-	switch (__SHIFTOUT(mvfr1, MVFR1_FPDNAN)) {
+	switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPDNAN)) {
 	case MVFR1_FPDNAN_NAN:
 		aprint_normal(", NaN propagation");
 		break;
 	}
-	switch (__SHIFTOUT(mvfr1, MVFR1_FPFTZ)) {
+	switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_FPFTZ)) {
 	case MVFR1_FPFTZ_DENORMAL:
 		aprint_normal(", denormals");
 		break;
 	}
-	switch (__SHIFTOUT(mvfr0, MVFR0_SIMDREG)) {
+	switch (__SHIFTOUT(id->ac_mvfr0, MVFR0_SIMDREG)) {
 	case MVFR0_SIMDREG_16x64:
 		aprint_normal(", 16x64bitRegs");
 		break;
@@ -412,7 +411,7 @@ cpu_identify2(device_t self, struct cpu_
 		aprint_normal(", 32x64bitRegs");
 		break;
 	}
-	switch (__SHIFTOUT(mvfr1, MVFR1_SIMDFMAC)) {
+	switch (__SHIFTOUT(id->ac_mvfr1, MVFR1_SIMDFMAC)) {
 	case MVFR1_SIMDFMAC_FMAC:
 		aprint_normal(", Fused Multiply-Add");
 		break;
@@ -421,6 +420,67 @@ cpu_identify2(device_t self, struct cpu_
 	aprint_normal("\n");
 }
 
+/*
+ * Fill in this CPUs id data.  Must be called from hatched cpus.
+ */
+static void
+cpu_setup_id(struct cpu_info *ci)
+{
+	struct aarch64_sysctl_cpu_id *id = &ci->ci_id;
+
+	memset(id, 0, sizeof *id);
+
+	id->ac_midr      = reg_midr_el1_read();
+	id->ac_revidr    = reg_revidr_el1_read();
+	id->ac_mpidr     = reg_mpidr_el1_read();
+
+	id->ac_aa64dfr0  = reg_id_aa64dfr0_el1_read();
+	id->ac_aa64dfr1  = reg_id_aa64dfr1_el1_read();
+
+	id->ac_aa64isar0 = reg_id_aa64isar0_el1_read();
+	id->ac_aa64isar1 = reg_id_aa64isar1_el1_read();
+
+	id->ac_aa64mmfr0 = reg_id_aa64mmfr0_el1_read();
+	id->ac_aa64mmfr1 = reg_id_aa64mmfr1_el1_read();
+	/* Only in ARMv8.2. */
+	id->ac_aa64mmfr2 = 0 /* reg_id_aa64mmfr2_el1_read() */;
+
+	id->ac_mvfr0     = reg_mvfr0_el1_read();
+	id->ac_mvfr1     = reg_mvfr1_el1_read();
+	id->ac_mvfr2     = reg_mvfr2_el1_read();
+
+	/* Only in ARMv8.2. */
+	id->ac_aa64zfr0  = 0 /* reg_id_aa64zfr0_el1_read() */;
+
+	id->ac_aa64pfr0  = reg_id_aa64pfr0_el1_read();
+	id->ac_aa64pfr1  = reg_id_aa64pfr1_el1_read();
+}
+
+/*
+ * setup the per-cpu sysctl tree.
+ */
+static void
+cpu_setup_sysctl(device_t dv, struct cpu_info *ci)
+{
+	const struct sysctlnode *cpunode = NULL;
+
+	sysctl_createv(NULL, 0, NULL, &cpunode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, device_xname(dv), NULL,
+		       NULL, 0, NULL, 0,
+		       CTL_MACHDEP,
+		       CTL_CREATE, CTL_EOL);
+
+	if (cpunode == NULL)
+		return;
+
+	sysctl_createv(NULL, 0, &cpunode, NULL,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_STRUCT, "cpu_id", NULL,
+		       NULL, 0, &ci->ci_id, sizeof(ci->ci_id),
+		       CTL_CREATE, CTL_EOL);
+}
+
 #ifdef MULTIPROCESSOR
 void
 cpu_boot_secondary_processors(void)

Index: src/sys/arch/aarch64/aarch64/genassym.cf
diff -u src/sys/arch/aarch64/aarch64/genassym.cf:1.8 src/sys/arch/aarch64/aarch64/genassym.cf:1.9
--- src/sys/arch/aarch64/aarch64/genassym.cf:1.8	Thu Oct  4 09:09:29 2018
+++ src/sys/arch/aarch64/aarch64/genassym.cf	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.8 2018/10/04 09:09:29 ryo Exp $
+# $NetBSD: genassym.cf,v 1.9 2018/11/20 01:59:51 mrg Exp $
 #-
 # Copyright (c) 2014 The NetBSD Foundation, Inc.
 # All rights reserved.
@@ -305,8 +305,8 @@ define	CI_CURPRIORITY		offsetof(struct c
 define	CI_CURLWP		offsetof(struct cpu_info, ci_curlwp)
 define	CI_CPL			offsetof(struct cpu_info, ci_cpl)
 define	CI_CPUID		offsetof(struct cpu_info, ci_cpuid)
-define	CI_MIDR			offsetof(struct cpu_info, ci_midr)
-define	CI_MPIDR		offsetof(struct cpu_info, ci_mpidr)
+define	CI_MIDR			offsetof(struct cpu_info, ci_id.ac_midr)
+define	CI_MPIDR		offsetof(struct cpu_info, ci_id.ac_mpidr)
 define	CI_ASTPENDING		offsetof(struct cpu_info, ci_astpending)
 define	CI_WANT_RESCHED		offsetof(struct cpu_info, ci_want_resched)
 define	CI_INTR_DEPTH		offsetof(struct cpu_info, ci_intr_depth)

Index: src/sys/arch/aarch64/include/armreg.h
diff -u src/sys/arch/aarch64/include/armreg.h:1.20 src/sys/arch/aarch64/include/armreg.h:1.21
--- src/sys/arch/aarch64/include/armreg.h:1.20	Wed Nov  7 06:47:38 2018
+++ src/sys/arch/aarch64/include/armreg.h	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: armreg.h,v 1.20 2018/11/07 06:47:38 riastradh Exp $ */
+/* $NetBSD: armreg.h,v 1.21 2018/11/20 01:59:51 mrg Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -251,13 +251,21 @@ AARCH64REG_READ_INLINE(id_aa64mmfr0_el1)
 #define	 ID_AA64MMFR0_EL1_PARANGE_256T	 5
 
 AARCH64REG_READ_INLINE(id_aa64mmfr1_el1)
+AARCH64REG_READ_INLINE(id_aa64mmfr2_el1)
 AARCH64REG_READ_INLINE(id_aa64pfr0_el1)
 AARCH64REG_READ_INLINE(id_aa64pfr1_el1)
+AARCH64REG_READ_INLINE(id_aa64zfr0_el1)
 AARCH64REG_READ_INLINE(id_pfr1_el1)
 AARCH64REG_READ_INLINE(isr_el1)
 AARCH64REG_READ_INLINE(midr_el1)
 AARCH64REG_READ_INLINE(mpidr_el1)
 
+#define	MIDR_EL1_IMPL		__BITS(31,24)		// Implementor
+#define	MIDR_EL1_VARIANT	__BITS(23,20)		// CPU Variant
+#define	MIDR_EL1_ARCH		__BITS(19,16)		// Architecture
+#define	MIDR_EL1_PARTNUM	__BITS(15,4)		// PartNum
+#define	MIDR_EL1_REVISION	__BITS(3,0)		// Revision
+
 #define	MPIDR_AFF3		__BITS(32,39)
 #define	MPIDR_U	 		__BIT(30)		// 1 = Uni-Processor System
 #define	MPIDR_MT		__BIT(24)		// 1 = SMT(AFF0 is logical)
@@ -1136,4 +1144,33 @@ gtmr_cntv_cval_read(void)
 }
 #endif /* _KERNEL */
 
+/*
+ * Structure attached to machdep.cpuN.cpu_id sysctl node.
+ * Always add new members to the end, and avoid arrays.
+ */
+struct aarch64_sysctl_cpu_id {
+	uint64_t ac_midr;	/* Main ID Register */
+	uint64_t ac_revidr;	/* Revision ID Register */
+	uint64_t ac_mpidr;	/* Multiprocessor Affinity Register */
+
+	uint64_t ac_aa64dfr0;	/* A64 Debug Feature Register 0 */
+	uint64_t ac_aa64dfr1;	/* A64 Debug Feature Register 1 */
+
+	uint64_t ac_aa64isar0;	/* A64 Instruction Set Attribute Register 0 */
+	uint64_t ac_aa64isar1;	/* A64 Instruction Set Attribute Register 1 */
+
+	uint64_t ac_aa64mmfr0;	/* A64 Memroy Model Feature Register 0 */
+	uint64_t ac_aa64mmfr1;	/* A64 Memroy Model Feature Register 1 */
+	uint64_t ac_aa64mmfr2;	/* A64 Memroy Model Feature Register 2 */
+
+	uint64_t ac_aa64pfr0;	/* A64 Processor Feature Register 0 */
+	uint64_t ac_aa64pfr1;	/* A64 Processor Feature Register 1 */
+
+	uint64_t ac_aa64zfr0;	/* A64 SVE Feature ID Register 0 */
+
+	uint32_t ac_mvfr0;	/* Media and VFP Feature Register 0 */
+	uint32_t ac_mvfr1;	/* Media and VFP Feature Register 1 */
+	uint32_t ac_mvfr2;	/* Media and VFP Feature Register 2 */
+};
+
 #endif /* _AARCH64_ARMREG_H_ */

Index: src/sys/arch/aarch64/include/cpu.h
diff -u src/sys/arch/aarch64/include/cpu.h:1.10 src/sys/arch/aarch64/include/cpu.h:1.11
--- src/sys/arch/aarch64/include/cpu.h:1.10	Thu Oct 18 09:01:51 2018
+++ src/sys/arch/aarch64/include/cpu.h	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.10 2018/10/18 09:01:51 skrll Exp $ */
+/* $NetBSD: cpu.h,v 1.11 2018/11/20 01:59:51 mrg Exp $ */
 
 /*-
  * Copyright (c) 2014 The NetBSD Foundation, Inc.
@@ -42,7 +42,9 @@
 
 #if defined(_KERNEL) || defined(_KMEMUSER)
 #include <sys/evcnt.h>
+
 #include <aarch64/frame.h>
+#include <aarch64/armreg.h>
 
 struct clockframe {
 	struct trapframe cf_tf;
@@ -88,8 +90,7 @@ struct cpu_info {
 	/* ACPI */
 	uint64_t ci_acpiid;	/* ACPI Processor Unique ID */
 
-	uint64_t ci_midr;	/* MIDR_EL1 */
-	uint64_t ci_mpidr;	/* MPIDR_EL1 */
+	struct aarch64_sysctl_cpu_id ci_id;
 
 	struct aarch64_cache_info *ci_cacheinfo;
 

Index: src/usr.sbin/cpuctl/arch/aarch64.c
diff -u src/usr.sbin/cpuctl/arch/aarch64.c:1.2 src/usr.sbin/cpuctl/arch/aarch64.c:1.3
--- src/usr.sbin/cpuctl/arch/aarch64.c:1.2	Tue May  8 11:42:43 2018
+++ src/usr.sbin/cpuctl/arch/aarch64.c	Tue Nov 20 01:59:51 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: aarch64.c,v 1.2 2018/05/08 11:42:43 ryo Exp $	*/
+/*	$NetBSD: aarch64.c,v 1.3 2018/11/20 01:59:51 mrg Exp $	*/
 
 /*
  * Copyright (c) 2018 Ryo Shimizu <r...@nerv.org>
@@ -29,7 +29,7 @@
 #include <sys/cdefs.h>
 
 #ifndef lint
-__RCSID("$NetBSD: aarch64.c,v 1.2 2018/05/08 11:42:43 ryo Exp $");
+__RCSID("$NetBSD: aarch64.c,v 1.3 2018/11/20 01:59:51 mrg Exp $");
 #endif /* no lint */
 
 #include <sys/types.h>
@@ -506,110 +506,40 @@ identify_mpidr(const char *cpuname, uint
 
 }
 
-static void *
-sysctlfetch(const char *sname, size_t *lenp)
-{
-	size_t len;
-	void *data;
-
-	if (sysctlbyname(sname, NULL, &len, NULL, 0) != 0) {
-		warn("sysctlbyname: %s", sname);
-		return NULL;
-	}
-
-	data = malloc(len);
-	if (data == NULL) {
-		warn("malloc");
-		return NULL;
-	}
-
-	if (sysctlbyname(sname, data, &len, NULL, 0) != 0) {
-		warn("sysctlbyname: %s", sname);
-		free(data);
-		return NULL;
-	}
-
-	*lenp = len;
-	return data;
-}
-
 void
 identifycpu(int fd, const char *cpuname)
 {
-	void *regs;
+	char path[128];
 	size_t len;
+	struct aarch64_sysctl_cpu_id id;
 
-	/* MIDR_EL1 */
-	regs = sysctlfetch("machdep.cpu_id", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint32_t))
-			identify_midr(cpuname, ((uint32_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* REVIDR_EL1 */
-	regs = sysctlfetch("machdep.id_revidr", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint32_t))
-			identify_revidr(cpuname, ((uint32_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* MPIDR_EL1 */
-	regs = sysctlfetch("machdep.id_mpidr", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint64_t))
-			identify_mpidr(cpuname, ((uint64_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* ID_AA64ISAR0_EL1 */
-	regs = sysctlfetch("machdep.id_aa64isar", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint64_t))
-			print_fieldinfo(cpuname, "isa features 0",
-			    id_aa64isar0_fieldinfo, ((uint64_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* ID_AA64MMFR0_EL1 */
-	regs = sysctlfetch("machdep.id_aa64mmfr", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint64_t))
-			print_fieldinfo(cpuname, "memory model 0",
-			    id_aa64mmfr0_fieldinfo, ((uint64_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* ID_AA64PFR0_EL1 */
-	regs = sysctlfetch("machdep.id_aa64pfr", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint64_t))
-			print_fieldinfo(cpuname, "processor feature 0",
-			    id_aa64pfr0_fieldinfo, ((uint64_t *)regs)[0]);
-		free(regs);
-	}
-
-	/* MVFR[012]_EL1 */
-	regs = sysctlfetch("machdep.id_mvfr", &len);
-	if (regs != NULL) {
-		if (len >= sizeof(uint32_t))
-			print_fieldinfo(cpuname, "media and VFP features 0",
-			    mvfr0_fieldinfo, ((uint32_t *)regs)[0]);
-		if (len >= sizeof(uint32_t) * 2)
-			print_fieldinfo(cpuname, "media and VFP features 1",
-			    mvfr1_fieldinfo, ((uint32_t *)regs)[1]);
-		if (len >= sizeof(uint32_t) * 3)
-			print_fieldinfo(cpuname, "media and VFP features 2",
-			    mvfr2_fieldinfo, ((uint32_t *)regs)[2]);
-		free(regs);
-	}
+	snprintf(path, sizeof path, "machdep.%s.cpu_id", cpuname);
+	len = sizeof(id);
+	if (sysctlbyname(path, &id, &len, 0, 0) == -1)
+		err(1, "couldn't get %s", path);
+
+	identify_midr(cpuname, id.ac_midr);
+	identify_revidr(cpuname, id.ac_revidr);
+	identify_mpidr(cpuname, id.ac_mpidr);
+	print_fieldinfo(cpuname, "isa features 0",
+	    id_aa64isar0_fieldinfo, id.ac_aa64isar0);
+	print_fieldinfo(cpuname, "memory model 0",
+	    id_aa64mmfr0_fieldinfo, id.ac_aa64mmfr0);
+	print_fieldinfo(cpuname, "processor feature 0",
+	    id_aa64pfr0_fieldinfo, id.ac_aa64pfr0);
+
+	print_fieldinfo(cpuname, "media and VFP features 0",
+	    mvfr0_fieldinfo, id.ac_mvfr0);
+	print_fieldinfo(cpuname, "media and VFP features 1",
+	    mvfr1_fieldinfo, id.ac_mvfr1);
+	print_fieldinfo(cpuname, "media and VFP features 2",
+	    mvfr2_fieldinfo, id.ac_mvfr2);
 }
 
 bool
 identifycpu_bind(void)
 {
-	return true;
+	return false;
 }
 
 int

Reply via email to