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