1
0
mirror of https://github.com/golang/go synced 2024-11-23 09:50:03 -07:00

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 <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>
This commit is contained in:
Joel Sing 2022-08-05 23:39:55 +10:00 committed by Gopher Robot
parent fefac44a62
commit cd54ef1f61
3 changed files with 76 additions and 1 deletions

View File

@ -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
}
}

View 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

View 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