Skip to content

Commit

Permalink
internal/cpu: implement CPU feature detection for openbsd/arm64
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
4a6f656c authored and gopherbot committed Aug 8, 2022
1 parent fefac44 commit cd54ef1
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 1 deletion.
60 changes: 60 additions & 0 deletions src/internal/cpu/cpu_arm64_openbsd.go
Original file line number Diff line number Diff line change
@@ -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
}
}
2 changes: 1 addition & 1 deletion src/internal/cpu/cpu_arm64_other.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
15 changes: 15 additions & 0 deletions src/runtime/os_openbsd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit cd54ef1

Please sign in to comment.