From: j@bitminer.ca Subject: Re: arm64: patch for midr_el1 access To: tech@openbsd.org,j@bitminer.ca Date: Sat, 9 Mar 2024 13:03:02 -0800 This is a correction (adds missing changes to other files.) Checked against -current as of today. To reiterate: This adds a new sysctl.machdep.id_midr which is used by some software such as the BLIS alternative to BLAS to determine the aarch64 vendor and part and thus be able to tailor instructions to the actual hardware. (BLIS already has extensive amd64 support. This patch allows BLIS to work on aarch64 more effectively.) Comments? Corrections? Approvals? thanks --J Index: arm64/arm64/cpu.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v diff -u -r1.108 cpu.c --- arm64/arm64/cpu.c 5 Mar 2024 18:42:20 -0000 1.108 +++ arm64/arm64/cpu.c 9 Mar 2024 19:11:23 -0000 @@ -223,6 +223,7 @@ uint64_t cpu_id_aa64isar2; uint64_t cpu_id_aa64pfr0; uint64_t cpu_id_aa64pfr1; +uint64_t cpu_id_midr; #ifdef CRYPTO int arm64_has_aes; @@ -518,6 +519,10 @@ printf("\n%s: mismatched ID_AA64ISAR2_EL1", ci->ci_dev->dv_xname); } + if (READ_SPECIALREG(midr_el1) != cpu_id_midr) { + printf("\n%s: mismatched MIDR_EL1", + ci->ci_dev->dv_xname); + } id = READ_SPECIALREG(id_aa64pfr0_el1); /* Allow CSV2/CVS3 to be different. */ id &= ~ID_AA64PFR0_CSV2_MASK; @@ -947,6 +952,7 @@ cpu_id_aa64isar2 = READ_SPECIALREG(id_aa64isar2_el1); cpu_id_aa64pfr0 = READ_SPECIALREG(id_aa64pfr0_el1); cpu_id_aa64pfr1 = READ_SPECIALREG(id_aa64pfr1_el1); + cpu_id_midr = READ_SPECIALREG(midr_el1); /* * The CSV2/CSV3 "features" are handled on a Index: arm64/arm64/machdep.c =================================================================== RCS file: /cvs/src/sys/arch/arm64/arm64/machdep.c,v diff -u -r1.86 machdep.c --- arm64/arm64/machdep.c 21 Feb 2024 01:45:14 -0000 1.86 +++ arm64/arm64/machdep.c 9 Mar 2024 19:11:23 -0000 @@ -375,6 +375,13 @@ case CPU_ID_AA64SMFR0: case CPU_ID_AA64ZFR0: return sysctl_rdquad(oldp, oldlenp, newp, 0); + case CPU_ID_MIDR: + value = 0; + value |= cpu_id_midr & ID_MIDR_IMPL_MASK; + value |= cpu_id_midr & ID_MIDR_PART_MASK; + value |= cpu_id_midr & ID_MIDR_VAR_MASK; + value |= cpu_id_midr & ID_MIDR_REV_MASK; + return sysctl_rdquad(oldp, oldlenp, newp, value); default: return (sysctl_bounded_arr(cpuctl_vars, nitems(cpuctl_vars), name, namelen, oldp, oldlenp, newp, newlen)); Index: arm64/include/armreg.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/armreg.h,v diff -u -r1.31 armreg.h --- arm64/include/armreg.h 5 Mar 2024 18:42:20 -0000 1.31 +++ arm64/include/armreg.h 9 Mar 2024 19:11:23 -0000 @@ -393,6 +393,17 @@ #define ID_AA64ISAR2_CLRBHB_NONE (0x0ULL << ID_AA64ISAR2_CLRBHB_SHIFT) #define ID_AA64ISAR2_CLRBHB_IMPL (0x1ULL << ID_AA64ISAR2_CLRBHB_SHIFT) +/* ID_MIDR_EL1 */ +#define ID_MIDR_MASK 0x00000000ffffffffULL +#define ID_MIDR_IMPL_SHIFT 24 +#define ID_MIDR_IMPL_MASK (0xffULL << ID_MIDR_IMPL_SHIFT) +#define ID_MIDR_PART_SHIFT 4 +#define ID_MIDR_PART_MASK (0xfffULL << ID_MIDR_PART_SHIFT) +#define ID_MIDR_VAR_SHIFT 20 +#define ID_MIDR_VAR_MASK (0xfULL << ID_MIDR_VAR_SHIFT) +#define ID_MIDR_REV_SHIFT 0 +#define ID_MIDR_REV_MASK (0xfULL << ID_MIDR_REV_SHIFT) + /* ID_AA64MMFR0_EL1 */ #define ID_AA64MMFR0_MASK 0x00000000ffffffffULL #define ID_AA64MMFR0_PA_RANGE_SHIFT 0 Index: arm64/include/cpu.h =================================================================== RCS file: /cvs/src/sys/arch/arm64/include/cpu.h,v diff -u -r1.43 cpu.h --- arm64/include/cpu.h 25 Feb 2024 19:15:50 -0000 1.43 +++ arm64/include/cpu.h 9 Mar 2024 19:11:23 -0000 @@ -37,7 +37,8 @@ #define CPU_ID_AA64SMFR0 10 #define CPU_ID_AA64ZFR0 11 #define CPU_LIDACTION 12 -#define CPU_MAXID 13 /* number of valid machdep ids */ +#define CPU_ID_MIDR 13 +#define CPU_MAXID 14 /* number of valid machdep ids */ #define CTL_MACHDEP_NAMES { \ { 0, 0 }, \ @@ -53,6 +54,7 @@ { "id_aa64smfr0", CTLTYPE_QUAD }, \ { "id_aa64zfr0", CTLTYPE_QUAD }, \ { "lidaction", CTLTYPE_INT }, \ + { "id_midr", CTLTYPE_QUAD }, \ } #ifdef _KERNEL @@ -65,6 +67,7 @@ extern uint64_t cpu_id_aa64isar1; extern uint64_t cpu_id_aa64pfr0; extern uint64_t cpu_id_aa64pfr1; +extern uint64_t cpu_id_midr; #include #include