From: kettenis Date: Thu, 24 Nov 2022 14:43:16 +0000 (+0000) Subject: Expose the complete set of ID registers as defined in the current version X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=c7654cd65262d532212f65123ee3905ba200365c;p=openbsd Expose the complete set of ID registers as defined in the current version of ARMv8/ARMv9. Make sure we only expose the features that we know about and support in our kernel. This matches what Linux does. For now, mostly restrict ourselves to features defined in ARMv8.5 which means that we only actually implement support for ID_AA64ISAR0_EL1, ID_AA64ISAR1_EL1, ID_AA64PFR0_EL1 and ID_AA64PFR1_EL1. For the other registers we simply always return 0. ok deraadt@ --- diff --git a/sys/arch/arm64/arm64/cpu.c b/sys/arch/arm64/arm64/cpu.c index 04dde3f99f9..2104d06ae4d 100644 --- a/sys/arch/arm64/arm64/cpu.c +++ b/sys/arch/arm64/arm64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.72 2022/11/08 16:53:40 kettenis Exp $ */ +/* $OpenBSD: cpu.c,v 1.73 2022/11/24 14:43:16 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn @@ -200,6 +200,8 @@ int cpu_node; uint64_t cpu_id_aa64isar0; uint64_t cpu_id_aa64isar1; +uint64_t cpu_id_aa64pfr0; +uint64_t cpu_id_aa64pfr1; #ifdef CRYPTO int arm64_has_aes; @@ -380,6 +382,14 @@ cpu_identify(struct cpu_info *ci) printf("\n%s: mismatched ID_AA64ISAR1_EL1", ci->ci_dev->dv_xname); } + if (READ_SPECIALREG(id_aa64pfr0_el1) != cpu_id_aa64pfr0) { + printf("\n%s: mismatched ID_AA64PFR0_EL1", + ci->ci_dev->dv_xname); + } + if (READ_SPECIALREG(id_aa64pfr1_el1) != cpu_id_aa64pfr1) { + printf("\n%s: mismatched ID_AA64PFR1_EL1", + ci->ci_dev->dv_xname); + } printf("\n%s: ", ci->ci_dev->dv_xname); @@ -732,6 +742,8 @@ cpu_attach(struct device *parent, struct device *dev, void *aux) #endif cpu_id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1); cpu_id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1); + cpu_id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1); + cpu_id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1); cpu_identify(ci); diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c index 36d5070b0a2..311d8bb9460 100644 --- a/sys/arch/arm64/arm64/machdep.c +++ b/sys/arch/arm64/arm64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.76 2022/11/21 20:19:21 kettenis Exp $ */ +/* $OpenBSD: machdep.c,v 1.77 2022/11/24 14:43:16 kettenis Exp $ */ /* * Copyright (c) 2014 Patrick Wildt * Copyright (c) 2021 Mark Kettenis @@ -315,6 +315,8 @@ cpu_switchto(struct proc *old, struct proc *new) extern uint64_t cpu_id_aa64isar0; extern uint64_t cpu_id_aa64isar1; +extern uint64_t cpu_id_aa64pfr0; +extern uint64_t cpu_id_aa64pfr1; /* * machine dependent system variables. @@ -326,6 +328,7 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, { char *compatible; int node, len, error; + uint64_t value; /* all sysctl names at this level are terminal */ if (namelen != 1) @@ -344,9 +347,30 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, free(compatible, M_TEMP, len); return error; case CPU_ID_AA64ISAR0: - return sysctl_rdquad(oldp, oldlenp, newp, cpu_id_aa64isar0); + value = cpu_id_aa64isar0 & ID_AA64ISAR0_MASK; + value &= ~ID_AA64ISAR0_TLB_MASK; + return sysctl_rdquad(oldp, oldlenp, newp, value); case CPU_ID_AA64ISAR1: - return sysctl_rdquad(oldp, oldlenp, newp, cpu_id_aa64isar1); + value = cpu_id_aa64isar1 & ID_AA64ISAR1_MASK; + value &= ~ID_AA64ISAR1_SPECRES_MASK; + return sysctl_rdquad(oldp, oldlenp, newp, value); + case CPU_ID_AA64PFR0: + value = 0; + value |= cpu_id_aa64pfr0 & ID_AA64PFR0_FP_MASK; + value |= cpu_id_aa64pfr0 & ID_AA64PFR0_ADV_SIMD_MASK; + value |= cpu_id_aa64pfr0 & ID_AA64PFR0_DIT_MASK; + return sysctl_rdquad(oldp, oldlenp, newp, value); + case CPU_ID_AA64PFR1: + value = 0; + value |= cpu_id_aa64pfr1 & ID_AA64PFR1_SBSS_MASK; + return sysctl_rdquad(oldp, oldlenp, newp, value); + case CPU_ID_AA64ISAR2: + case CPU_ID_AA64MMFR0: + case CPU_ID_AA64MMFR1: + case CPU_ID_AA64MMFR2: + case CPU_ID_AA64SMFR0: + case CPU_ID_AA64ZFR0: + return sysctl_rdquad(oldp, oldlenp, newp, 0); default: return (EOPNOTSUPP); } diff --git a/sys/arch/arm64/include/cpu.h b/sys/arch/arm64/include/cpu.h index f1eea12bb84..30154c3ad41 100644 --- a/sys/arch/arm64/include/cpu.h +++ b/sys/arch/arm64/include/cpu.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.h,v 1.30 2022/11/08 20:41:36 mlarkin Exp $ */ +/* $OpenBSD: cpu.h,v 1.31 2022/11/24 14:43:16 kettenis Exp $ */ /* * Copyright (c) 2016 Dale Rahn * @@ -28,13 +28,29 @@ #define CPU_COMPATIBLE 1 /* compatible property */ #define CPU_ID_AA64ISAR0 2 #define CPU_ID_AA64ISAR1 3 -#define CPU_MAXID 4 /* number of valid machdep ids */ +#define CPU_ID_AA64ISAR2 4 +#define CPU_ID_AA64MMFR0 5 +#define CPU_ID_AA64MMFR1 6 +#define CPU_ID_AA64MMFR2 7 +#define CPU_ID_AA64PFR0 8 +#define CPU_ID_AA64PFR1 9 +#define CPU_ID_AA64SMFR0 10 +#define CPU_ID_AA64ZFR0 11 +#define CPU_MAXID 12 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ { "compatible", CTLTYPE_STRING }, \ { "id_aa64isar0", CTLTYPE_QUAD }, \ { "id_aa64isar1", CTLTYPE_QUAD }, \ + { "id_aa64isar2", CTLTYPE_QUAD }, \ + { "id_aa64mmfr0", CTLTYPE_QUAD }, \ + { "id_aa64mmfr1", CTLTYPE_QUAD }, \ + { "id_aa64mmfr2", CTLTYPE_QUAD }, \ + { "id_aa64pfr0", CTLTYPE_QUAD }, \ + { "id_aa64pfr1", CTLTYPE_QUAD }, \ + { "id_aa64smfr0", CTLTYPE_QUAD }, \ + { "id_aa64zfr0", CTLTYPE_QUAD }, \ } #ifdef _KERNEL