Index | Thread | Search

From:
Mark Kettenis <mark.kettenis@xs4all.nl>
Subject:
arm64 AI support
To:
jsg@openbsd.org, brad@comstyle.com
Cc:
tech@openbsd.org
Date:
Sun, 26 May 2024 14:35:58 +0200

Download raw body.

Thread
  • Mark Kettenis:

    arm64 AI support

Just kidding.

This adds support for recognizing a few more instruction set features,
including the BF16 and I8MM features that are useful for implementing
things like convolutional neural networks.

This also makes us export those features to userland through
sysctl(2).  It is entirely up to userland to use these features or
not.

ok?

Index: arch/arm64/include/armreg.h
===================================================================
RCS file: /cvs/src/sys/arch/arm64/include/armreg.h,v
retrieving revision 1.33
diff -u -p -r1.33 armreg.h
--- arch/arm64/include/armreg.h	18 Mar 2024 18:35:21 -0000	1.33
+++ arch/arm64/include/armreg.h	26 May 2024 12:28:17 -0000
@@ -337,7 +337,7 @@
 #define	 ID_AA64ISAR0_RNDR_IMPL		(0x1ULL << ID_AA64ISAR0_RNDR_SHIFT)
 
 /* ID_AA64ISAR1_EL1 */
-#define	ID_AA64ISAR1_MASK		0x00000fffffffffffULL
+#define	ID_AA64ISAR1_MASK		0xffffffffffffffffULL
 #define	ID_AA64ISAR1_DPB_SHIFT		0
 #define	ID_AA64ISAR1_DPB_MASK		(0xfULL << ID_AA64ISAR1_DPB_SHIFT)
 #define	ID_AA64ISAR1_DPB(x)		((x) & ID_AA64ISAR1_DPB_MASK)
@@ -396,6 +396,34 @@
 #define	ID_AA64ISAR1_SPECRES(x)		((x) & ID_AA64ISAR1_SPECRES_MASK)
 #define	 ID_AA64ISAR1_SPECRES_NONE	(0x0ULL << ID_AA64ISAR1_SPECRES_SHIFT)
 #define	 ID_AA64ISAR1_SPECRES_IMPL	(0x1ULL << ID_AA64ISAR1_SPECRES_SHIFT)
+#define	ID_AA64ISAR1_BF16_SHIFT		44
+#define	ID_AA64ISAR1_BF16_MASK		(0xfULL << ID_AA64ISAR1_BF16_SHIFT)
+#define	ID_AA64ISAR1_BF16(x)		((x) & ID_AA64ISAR1_BF16_MASK)
+#define	 ID_AA64ISAR1_BF16_NONE		(0x0ULL << ID_AA64ISAR1_BF16_SHIFT)
+#define	 ID_AA64ISAR1_BF16_BASE		(0x1ULL << ID_AA64ISAR1_BF16_SHIFT)
+#define	 ID_AA64ISAR1_BF16_EBF		(0x2ULL << ID_AA64ISAR1_BF16_SHIFT)
+#define	ID_AA64ISAR1_DGH_SHIFT		48
+#define	ID_AA64ISAR1_DGH_MASK		(0xfULL << ID_AA64ISAR1_DGH_SHIFT)
+#define	ID_AA64ISAR1_DGH(x)		((x) & ID_AA64ISAR1_DGH_MASK)
+#define	 ID_AA64ISAR1_DGH_NONE		(0x0ULL << ID_AA64ISAR1_DGH_SHIFT)
+#define	 ID_AA64ISAR1_DGH_IMPL		(0x1ULL << ID_AA64ISAR1_DGH_SHIFT)
+#define	ID_AA64ISAR1_I8MM_SHIFT		52
+#define	ID_AA64ISAR1_I8MM_MASK		(0xfULL << ID_AA64ISAR1_I8MM_SHIFT)
+#define	ID_AA64ISAR1_I8MM(x)		((x) & ID_AA64ISAR1_I8MM_MASK)
+#define	 ID_AA64ISAR1_I8MM_NONE		(0x0ULL << ID_AA64ISAR1_I8MM_SHIFT)
+#define	 ID_AA64ISAR1_I8MM_IMPL		(0x1ULL << ID_AA64ISAR1_I8MM_SHIFT)
+#define	ID_AA64ISAR1_XS_SHIFT		56
+#define	ID_AA64ISAR1_XS_MASK		(0xfULL << ID_AA64ISAR1_XS_SHIFT)
+#define	ID_AA64ISAR1_XS(x)		((x) & ID_AA64ISAR1_XS_MASK)
+#define	 ID_AA64ISAR1_XS_NONE		(0x0ULL << ID_AA64ISAR1_XS_SHIFT)
+#define	 ID_AA64ISAR1_XS_IMPL		(0x1ULL << ID_AA64ISAR1_XS_SHIFT)
+#define	ID_AA64ISAR1_LS64_SHIFT		60
+#define	ID_AA64ISAR1_LS64_MASK		(0xfULL << ID_AA64ISAR1_LS64_SHIFT)
+#define	ID_AA64ISAR1_LS64(x)		((x) & ID_AA64ISAR1_LS64_MASK)
+#define	 ID_AA64ISAR1_LS64_NONE		(0x0ULL << ID_AA64ISAR1_LS64_SHIFT)
+#define	 ID_AA64ISAR1_LS64_BASE		(0x1ULL << ID_AA64ISAR1_LS64_SHIFT)
+#define	 ID_AA64ISAR1_LS64_V		(0x2ULL << ID_AA64ISAR1_LS64_SHIFT)
+#define	 ID_AA64ISAR1_LS64_ACCDATA	(0x3ULL << ID_AA64ISAR1_LS64_SHIFT)
 
 /* ID_AA64ISAR2_EL1 */
 #define	ID_AA64ISAR2_MASK		0x00000000f0000000ULL
Index: arch/arm64/arm64/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/arm64/arm64/cpu.c,v
retrieving revision 1.114
diff -u -p -r1.114 cpu.c
--- arch/arm64/arm64/cpu.c	13 Apr 2024 14:19:39 -0000	1.114
+++ arch/arm64/arm64/cpu.c	26 May 2024 12:28:17 -0000
@@ -742,6 +742,37 @@ cpu_identify(struct cpu_info *ci)
 	 */
 	id = READ_SPECIALREG(id_aa64isar1_el1);
 
+	if (ID_AA64ISAR1_LS64(id) >= ID_AA64ISAR1_LS64_BASE) {
+		printf("%sLS64", sep);
+		sep = ",";
+	}
+	if (ID_AA64ISAR1_LS64(id) >= ID_AA64ISAR1_LS64_V)
+		printf("+V");
+	if (ID_AA64ISAR1_LS64(id) >= ID_AA64ISAR1_LS64_ACCDATA)
+		printf("+ACCDATA");
+
+	if (ID_AA64ISAR1_XS(id) >= ID_AA64ISAR1_XS_IMPL) {
+		printf("%sXS", sep);
+		sep = ",";
+	}
+
+	if (ID_AA64ISAR1_I8MM(id) >= ID_AA64ISAR1_I8MM_IMPL) {
+		printf("%sI8MM", sep);
+		sep = ",";
+	}
+
+	if (ID_AA64ISAR1_DGH(id) >= ID_AA64ISAR1_DGH_IMPL) {
+		printf("%sXS", sep);
+		sep = ",";
+	}
+
+	if (ID_AA64ISAR1_BF16(id) >= ID_AA64ISAR1_BF16_BASE) {
+		printf("%sBF16", sep);
+		sep = ",";
+	}
+	if (ID_AA64ISAR1_BF16(id) >= ID_AA64ISAR1_BF16_EBF)
+		printf("+EBF");
+
 	if (ID_AA64ISAR1_SPECRES(id) >= ID_AA64ISAR1_SPECRES_IMPL) {
 		printf("%sSPECRES", sep);
 		sep = ",";