]> Cypherpunks repositories - gostls13.git/commitdiff
internal/cpu: implement CPU feature detection for openbsd/arm64
authorJoel Sing <joel@sing.id.au>
Fri, 5 Aug 2022 13:39:55 +0000 (23:39 +1000)
committerGopher Robot <gobot@golang.org>
Mon, 8 Aug 2022 15:07:46 +0000 (15:07 +0000)
OpenBSD 7.1 onwards expose the aarch64 ISAR0 and ISAR1 registers via sysctl:

  $ sysctl machdep
  machdep.compatible=apple,j274
  machdep.id_aa64isar0=153421459058925856
  machdep.id_aa64isar1=1172796674562

Implement CPU feature detection for openbsd/arm64 based on this information.

Fixes #31746

Change-Id: If8a9b2b8fc557e1aaefbcb52f4d1bd9efc43856d
Reviewed-on: https://go-review.googlesource.com/c/go/+/421875
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Tobias Klauser <tobias.klauser@gmail.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Run-TryBot: Joel Sing <joel@sing.id.au>
Run-TryBot: Ian Lance Taylor <iant@google.com>

src/internal/cpu/cpu_arm64_openbsd.go [new file with mode: 0644]
src/internal/cpu/cpu_arm64_other.go
src/runtime/os_openbsd.go

diff --git a/src/internal/cpu/cpu_arm64_openbsd.go b/src/internal/cpu/cpu_arm64_openbsd.go
new file mode 100644 (file)
index 0000000..2b284eb
--- /dev/null
@@ -0,0 +1,60 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build arm64
+
+package cpu
+
+const (
+       // From OpenBSD's sys/sysctl.h.
+       _CTL_MACHDEP = 7
+
+       // From OpenBSD's machine/cpu.h.
+       _CPU_ID_AA64ISAR0 = 2
+       _CPU_ID_AA64ISAR1 = 3
+)
+
+func extractBits(data uint64, start, end uint) uint {
+       return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
+}
+
+//go:noescape
+func sysctlUint64(mib []uint32) (uint64, bool)
+
+func osInit() {
+       // Get ID_AA64ISAR0 from sysctl.
+       isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
+       if !ok {
+               return
+       }
+
+       // ID_AA64ISAR0_EL1
+       switch extractBits(isar0, 4, 7) {
+       case 1:
+               ARM64.HasAES = true
+       case 2:
+               ARM64.HasAES = true
+               ARM64.HasPMULL = true
+       }
+
+       switch extractBits(isar0, 8, 11) {
+       case 1:
+               ARM64.HasSHA1 = true
+       }
+
+       switch extractBits(isar0, 12, 15) {
+       case 1, 2:
+               ARM64.HasSHA2 = true
+       }
+
+       switch extractBits(isar0, 16, 19) {
+       case 1:
+               ARM64.HasCRC32 = true
+       }
+
+       switch extractBits(isar0, 20, 23) {
+       case 2:
+               ARM64.HasATOMICS = true
+       }
+}
index d313648cb7c4544f6c1d3a0ab66cdd488124f674..44592cfcede8e19d9c9645246a21a48e9596f26e 100644 (file)
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios)
+//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios) && !openbsd
 
 package cpu
 
index d43414459d2caafff5cc2aa0518b1e235ab9bd6f..7af6c4afe746c1ed59ceddc8452f26357516cfb9 100644 (file)
@@ -51,6 +51,21 @@ func sysctlInt(mib []uint32) (int32, bool) {
        return out, true
 }
 
+func sysctlUint64(mib []uint32) (uint64, bool) {
+       var out uint64
+       nout := unsafe.Sizeof(out)
+       ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
+       if ret < 0 {
+               return 0, false
+       }
+       return out, true
+}
+
+//go:linkname internal_cpu_sysctlUint64 internal/cpu.sysctlUint64
+func internal_cpu_sysctlUint64(mib []uint32) (uint64, bool) {
+       return sysctlUint64(mib)
+}
+
 func getncpu() int32 {
        // Try hw.ncpuonline first because hw.ncpu would report a number twice as
        // high as the actual CPUs running on OpenBSD 6.4 with hyperthreading