Skip to content

Commit cd54ef1

Browse files
4a6f656cgopherbot
authored andcommitted
internal/cpu: implement CPU feature detection for openbsd/arm64
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 <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Tobias Klauser <[email protected]> Auto-Submit: Ian Lance Taylor <[email protected]> Run-TryBot: Joel Sing <[email protected]> Run-TryBot: Ian Lance Taylor <[email protected]>
1 parent fefac44 commit cd54ef1

File tree

3 files changed

+76
-1
lines changed

3 files changed

+76
-1
lines changed

src/internal/cpu/cpu_arm64_openbsd.go

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2022 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build arm64
6+
7+
package cpu
8+
9+
const (
10+
// From OpenBSD's sys/sysctl.h.
11+
_CTL_MACHDEP = 7
12+
13+
// From OpenBSD's machine/cpu.h.
14+
_CPU_ID_AA64ISAR0 = 2
15+
_CPU_ID_AA64ISAR1 = 3
16+
)
17+
18+
func extractBits(data uint64, start, end uint) uint {
19+
return (uint)(data>>start) & ((1 << (end - start + 1)) - 1)
20+
}
21+
22+
//go:noescape
23+
func sysctlUint64(mib []uint32) (uint64, bool)
24+
25+
func osInit() {
26+
// Get ID_AA64ISAR0 from sysctl.
27+
isar0, ok := sysctlUint64([]uint32{_CTL_MACHDEP, _CPU_ID_AA64ISAR0})
28+
if !ok {
29+
return
30+
}
31+
32+
// ID_AA64ISAR0_EL1
33+
switch extractBits(isar0, 4, 7) {
34+
case 1:
35+
ARM64.HasAES = true
36+
case 2:
37+
ARM64.HasAES = true
38+
ARM64.HasPMULL = true
39+
}
40+
41+
switch extractBits(isar0, 8, 11) {
42+
case 1:
43+
ARM64.HasSHA1 = true
44+
}
45+
46+
switch extractBits(isar0, 12, 15) {
47+
case 1, 2:
48+
ARM64.HasSHA2 = true
49+
}
50+
51+
switch extractBits(isar0, 16, 19) {
52+
case 1:
53+
ARM64.HasCRC32 = true
54+
}
55+
56+
switch extractBits(isar0, 20, 23) {
57+
case 2:
58+
ARM64.HasATOMICS = true
59+
}
60+
}

src/internal/cpu/cpu_arm64_other.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios)
5+
//go:build arm64 && !linux && !freebsd && !android && (!darwin || ios) && !openbsd
66

77
package cpu
88

src/runtime/os_openbsd.go

+15
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,21 @@ func sysctlInt(mib []uint32) (int32, bool) {
5151
return out, true
5252
}
5353

54+
func sysctlUint64(mib []uint32) (uint64, bool) {
55+
var out uint64
56+
nout := unsafe.Sizeof(out)
57+
ret := sysctl(&mib[0], uint32(len(mib)), (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
58+
if ret < 0 {
59+
return 0, false
60+
}
61+
return out, true
62+
}
63+
64+
//go:linkname internal_cpu_sysctlUint64 internal/cpu.sysctlUint64
65+
func internal_cpu_sysctlUint64(mib []uint32) (uint64, bool) {
66+
return sysctlUint64(mib)
67+
}
68+
5469
func getncpu() int32 {
5570
// Try hw.ncpuonline first because hw.ncpu would report a number twice as
5671
// high as the actual CPUs running on OpenBSD 6.4 with hyperthreading

0 commit comments

Comments
 (0)