Source-Changes-HG archive

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

[src/trunk]: src/sys/arch/aarch64/aarch64 add linux compatible /proc/cpuinfo



details:   https://anonhg.NetBSD.org/src/rev/8ff45bf1ee98
branches:  trunk
changeset: 940015:8ff45bf1ee98
user:      ryo <ryo%NetBSD.org@localhost>
date:      Wed Sep 30 08:43:47 2020 +0000

description:
add linux compatible /proc/cpuinfo

diffstat:

 sys/arch/aarch64/aarch64/procfs_machdep.c |  218 ++++++++++++++++++++++++++---
 1 files changed, 189 insertions(+), 29 deletions(-)

diffs (245 lines):

diff -r 553cd8a3db47 -r 8ff45bf1ee98 sys/arch/aarch64/aarch64/procfs_machdep.c
--- a/sys/arch/aarch64/aarch64/procfs_machdep.c Wed Sep 30 08:40:49 2020 +0000
+++ b/sys/arch/aarch64/aarch64/procfs_machdep.c Wed Sep 30 08:43:47 2020 +0000
@@ -1,12 +1,9 @@
-/* $NetBSD: procfs_machdep.c,v 1.1 2014/08/10 05:47:37 matt Exp $ */
+/* $NetBSD: procfs_machdep.c,v 1.2 2020/09/30 08:43:47 ryo Exp $ */
 
 /*-
- * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * Copyright (c) 2020 Ryo Shimizu <ryo%nerv.org@localhost>
  * All rights reserved.
  *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Matt Thomas of 3am Software Foundry.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -16,39 +13,202 @@
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
- * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
- * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.1 2014/08/10 05:47:37 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: procfs_machdep.c,v 1.2 2020/09/30 08:43:47 ryo Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/mount.h>
-#include <sys/stat.h>
-#include <sys/vnode.h>
-#include <sys/proc.h>
+#include <miscfs/procfs/procfs.h>
+#include <aarch64/armreg.h>
+
+
+/* use variables named 'buf', 'left', 'total' */
+#define FORWARD_BUF(_len)                                      \
+       do {                                                    \
+               total += _len;                                  \
+               if (_len < left) {                              \
+                       buf += _len;                            \
+                       left -= _len;                           \
+               } else {                                        \
+                       buf += left;                            \
+                       left = 0;                               \
+               }                                               \
+       } while (0 /*CONSTCOND*/)
 
-#include <miscfs/procfs/procfs.h>
+#define OUTPUT_BUF(fmt, args...)                               \
+       do {                                                    \
+               size_t l = snprintf(buf, left, fmt, ## args);   \
+               FORWARD_BUF(l);                                 \
+       } while (0/*CONSTCOND*/)
+
+static int
+procfs_cpuinfo_features(struct cpu_info *ci, char *buf, int buflen)
+{
+       uint64_t isar0, isar1, mmfr2, pfr0, pfr1;
+       size_t left, total;
+
+       isar0 = ci->ci_id.ac_aa64isar0;
+       isar1 = ci->ci_id.ac_aa64isar1;
+       mmfr2 = ci->ci_id.ac_aa64mmfr2;
+       pfr0 = ci->ci_id.ac_aa64pfr0;
+       pfr1 = ci->ci_id.ac_aa64pfr1;
+
+       left = buflen;
+       total = 0;
 
-/*
- * Linux-style /proc/cpuinfo.
- * Only used when procfs is mounted with -o linux.
- */
+       /*
+        * I don't know if we need to mimic the order of HWCAP in linux
+        */
+       OUTPUT_BUF("Features\t:");
+#define SO_EQ(reg, mask, val)  (__SHIFTOUT((reg), (mask)) == (val))
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_FP, ID_AA64PFR0_EL1_FP_IMPL))
+               OUTPUT_BUF(" fp");
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_ADVSIMD, ID_AA64PFR0_EL1_ADV_SIMD_IMPL))
+               OUTPUT_BUF(" asimd");
+       /* notyet: " evtstrm" */
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_AES, ID_AA64ISAR0_EL1_AES_AES))
+               OUTPUT_BUF(" aes");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_AES, ID_AA64ISAR0_EL1_AES_PMUL))
+               OUTPUT_BUF(" pmull");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SHA1,
+           ID_AA64ISAR0_EL1_SHA1_SHA1CPMHSU))
+               OUTPUT_BUF(" sha1");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SHA2,
+           ID_AA64ISAR0_EL1_SHA2_SHA256HSU))
+               OUTPUT_BUF(" sha2");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_CRC32, ID_AA64ISAR0_EL1_CRC32_CRC32X))
+               OUTPUT_BUF(" crc32");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_ATOMIC, ID_AA64ISAR0_EL1_ATOMIC_SWP))
+               OUTPUT_BUF(" atomics");
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_FP, ID_AA64PFR0_EL1_FP_HP))
+               OUTPUT_BUF(" fphp");
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_ADVSIMD, ID_AA64PFR0_EL1_ADV_SIMD_HP))
+               OUTPUT_BUF(" asimdhp");
+       /* notyet: " cpuid" */
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_RDM, ID_AA64ISAR0_EL1_RDM_SQRDML))
+               OUTPUT_BUF(" asimdrdm");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_JSCVT,
+           ID_AA64ISAR1_EL1_JSCVT_SUPPORTED))
+               OUTPUT_BUF(" jscvt");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_FCMA,
+           ID_AA64ISAR1_EL1_FCMA_SUPPORTED))
+               OUTPUT_BUF(" fcma");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_LRCPC, ID_AA64ISAR1_EL1_LRCPC_PR))
+               OUTPUT_BUF(" lrcpc");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_DPB, ID_AA64ISAR1_EL1_DPB_CVAP))
+               OUTPUT_BUF(" dcpop");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SHA3, ID_AA64ISAR0_EL1_SHA3_EOR3))
+               OUTPUT_BUF(" sha3");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SM3, ID_AA64ISAR0_EL1_SM3_SM3))
+               OUTPUT_BUF(" sm3");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SM4, ID_AA64ISAR0_EL1_SM4_SM4))
+               OUTPUT_BUF(" sm4");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_DP,  ID_AA64ISAR0_EL1_DP_UDOT))
+               OUTPUT_BUF(" asimddp");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_SHA2,
+           ID_AA64ISAR0_EL1_SHA2_SHA512HSU))
+               OUTPUT_BUF(" sha512");
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_SVE, ID_AA64PFR0_EL1_SVE_IMPL))
+               OUTPUT_BUF(" sve");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_FHM, ID_AA64ISAR0_EL1_FHM_FMLAL))
+               OUTPUT_BUF(" asimdfhm");
+       if (SO_EQ(pfr0, ID_AA64PFR0_EL1_DIT, ID_AA64PFR0_EL1_DIT_IMPL))
+               OUTPUT_BUF(" dit");
+       if (SO_EQ(mmfr2, ID_AA64MMFR2_EL1_AT, ID_AA64MMFR2_EL1_AT_16BIT))
+               OUTPUT_BUF(" uscat");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_LRCPC, ID_AA64ISAR1_EL1_LRCPC_PR_UR))
+               OUTPUT_BUF(" ilrcpc");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_TS, ID_AA64ISAR0_EL1_TS_CFINV))
+               OUTPUT_BUF(" flagm");
+       if (SO_EQ(pfr1, ID_AA64PFR1_EL1_SSBS, ID_AA64PFR1_EL1_SSBS_MSR_MRS))
+               OUTPUT_BUF(" ssbs");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_SB, ID_AA64ISAR1_EL1_SB_SUPPORTED))
+               OUTPUT_BUF(" sb");
+#ifdef ARMV83_PAC
+       if (aarch64_pac_enabled)
+               OUTPUT_BUF(" paca pacg");
+#endif
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_DPB, ID_AA64ISAR1_EL1_DPB_CVAP_CVADP))
+               OUTPUT_BUF(" dcpodp");
+       /* notyet: " sve2" */
+       /* notyet: " sveaes" */
+       /* notyet: " svepmull" */
+       /* notyet: " svebitperm" */
+       /* notyet: " svesha3" */
+       /* notyet: " svesm4" */
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_TS, ID_AA64ISAR0_EL1_TS_AXFLAG))
+               OUTPUT_BUF(" flagm2");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_FRINTTS,
+           ID_AA64ISAR1_EL1_FRINTTS_SUPPORTED))
+               OUTPUT_BUF(" frint");
+       /* notyet: " svei8mm" */
+       /* notyet: " svef32mm" */
+       /* notyet: " svef64mm" */
+       /* notyet: " svebf16" */
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_I8MM,
+           ID_AA64ISAR1_EL1_I8MM_SUPPORTED))
+               OUTPUT_BUF(" i8mm");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_BF16, ID_AA64ISAR1_EL1_BF16_BFDOT))
+               OUTPUT_BUF(" bf16");
+       if (SO_EQ(isar1, ID_AA64ISAR1_EL1_DGH, ID_AA64ISAR1_EL1_DGH_SUPPORTED))
+               OUTPUT_BUF(" dgh");
+       if (SO_EQ(isar0, ID_AA64ISAR0_EL1_RNDR, ID_AA64ISAR0_EL1_RNDR_RNDRRS))
+               OUTPUT_BUF(" rng");
+#ifdef ARMV85_BTI
+       if (aarch64_bti_enabled)
+               OUTPUT_BUF(" bti");
+#endif
+       OUTPUT_BUF("\n");
+#undef SO_EQ
+
+       return total;
+}
+
 int
-procfs_getcpuinfstr(char *buf, size_t *len)
+procfs_getcpuinfstr(char *buf, size_t *lenp)
 {
-       *len = 0;
+       struct cpu_info *ci;
+       CPU_INFO_ITERATOR cii;
+       size_t left, len, total;
+       int ret = 0;
+
+       left = *lenp;
+       total = 0;
+
+       for (CPU_INFO_FOREACH(cii, ci)) {
+               OUTPUT_BUF("processor\t: %lu\n", cii);
+
+               len = procfs_cpuinfo_features(ci, buf, left);
+               FORWARD_BUF(len);
 
-       return 0;
+               OUTPUT_BUF("CPU implementer\t: 0x%02lx\n",
+                   __SHIFTOUT(ci->ci_id.ac_midr, CPU_ID_IMPLEMENTOR_MASK));
+               OUTPUT_BUF("CPU architecture: 8\n");    /* ARMv8 */
+               OUTPUT_BUF("CPU variant\t: 0x%lx\n",
+                   __SHIFTOUT(ci->ci_id.ac_midr, CPU_ID_VARIANT_MASK));
+               OUTPUT_BUF("CPU part\t: 0x%03lx\n",
+                   __SHIFTOUT(ci->ci_id.ac_midr, CPU_ID_PARTNO_MASK));
+               OUTPUT_BUF("CPU revision\t: %lu\n",
+                   __SHIFTOUT(ci->ci_id.ac_midr, CPU_ID_REVISION_MASK));
+               OUTPUT_BUF("\n");
+       }
+
+       /* not enough buffer? */
+       if (total >= *lenp)
+               ret = -1;
+
+       *lenp = total + 1;      /* total output + '\0' */
+       return ret;
 }



Home | Main Index | Thread Index | Old Index