-
Notifications
You must be signed in to change notification settings - Fork 17.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
internal/cpu: add darwin/arm64 CPU feature detection support
Fixes #42747 Change-Id: I6b1679348c77161f075f0678818bb003fc0e8c86 Reviewed-on: https://go-review.googlesource.com/c/go/+/271989 Trust: Martin Möhrmann <[email protected]> Run-TryBot: Martin Möhrmann <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: Cherry Zhang <[email protected]>
- Loading branch information
Showing
14 changed files
with
223 additions
and
128 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// Copyright 2020 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. | ||
|
||
// +build arm64 | ||
// +build darwin | ||
// +build !ios | ||
|
||
package cpu | ||
|
||
func osInit() { | ||
ARM64.HasATOMICS = sysctlEnabled([]byte("hw.optional.armv8_1_atomics\x00")) | ||
ARM64.HasCRC32 = sysctlEnabled([]byte("hw.optional.armv8_crc32\x00")) | ||
|
||
// There are no hw.optional sysctl values for the below features on Mac OS 11.0 | ||
// to detect their supported state dynamically. Assume the CPU features that | ||
// Apple Silicon M1 supports to be available as a minimal set of features | ||
// to all Go programs running on darwin/arm64. | ||
ARM64.HasAES = true | ||
ARM64.HasPMULL = true | ||
ARM64.HasSHA1 = true | ||
ARM64.HasSHA2 = true | ||
} | ||
|
||
//go:noescape | ||
func getsysctlbyname(name []byte) (int32, int32) | ||
|
||
func sysctlEnabled(name []byte) bool { | ||
ret, value := getsysctlbyname(name) | ||
if ret < 0 { | ||
return false | ||
} | ||
return value > 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright 2020 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. | ||
|
||
// +build arm64 | ||
|
||
package cpu | ||
|
||
func osInit() { | ||
// Retrieve info from system register ID_AA64ISAR0_EL1. | ||
isar0 := getisar0() | ||
|
||
// 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 | ||
} | ||
} | ||
|
||
func extractBits(data uint64, start, end uint) uint { | ||
return (uint)(data>>start) & ((1 << (end - start + 1)) - 1) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2020 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. | ||
|
||
// +build arm64 | ||
// +build linux | ||
|
||
package cpu | ||
|
||
// HWCap may be initialized by archauxv and | ||
// should not be changed after it was initialized. | ||
var HWCap uint | ||
|
||
// HWCAP bits. These are exposed by Linux. | ||
const ( | ||
hwcap_AES = 1 << 3 | ||
hwcap_PMULL = 1 << 4 | ||
hwcap_SHA1 = 1 << 5 | ||
hwcap_SHA2 = 1 << 6 | ||
hwcap_CRC32 = 1 << 7 | ||
hwcap_ATOMICS = 1 << 8 | ||
hwcap_CPUID = 1 << 11 | ||
) | ||
|
||
func hwcapInit(os string) { | ||
// HWCap was populated by the runtime from the auxiliary vector. | ||
// Use HWCap information since reading aarch64 system registers | ||
// is not supported in user space on older linux kernels. | ||
ARM64.HasAES = isSet(HWCap, hwcap_AES) | ||
ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) | ||
ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) | ||
ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) | ||
ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) | ||
ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) | ||
|
||
// The Samsung S9+ kernel reports support for atomics, but not all cores | ||
// actually support them, resulting in SIGILL. See issue #28431. | ||
// TODO(elias.naur): Only disable the optimization on bad chipsets on android. | ||
ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android" | ||
|
||
// Check to see if executing on a NeoverseN1 and in order to do that, | ||
// check the AUXV for the CPUID bit. The getMIDR function executes an | ||
// instruction which would normally be an illegal instruction, but it's | ||
// trapped by the kernel, the value sanitized and then returned. Without | ||
// the CPUID bit the kernel will not trap the instruction and the process | ||
// will be terminated with SIGILL. | ||
if ARM64.HasCPUID { | ||
midr := getMIDR() | ||
part_num := uint16((midr >> 4) & 0xfff) | ||
implementor := byte((midr >> 24) & 0xff) | ||
|
||
if implementor == 'A' && part_num == 0xd0c { | ||
ARM64.IsNeoverseN1 = true | ||
} | ||
if implementor == 'A' && part_num == 0xd40 { | ||
ARM64.IsZeus = true | ||
} | ||
} | ||
} | ||
|
||
func isSet(hwc uint, value uint) bool { | ||
return hwc&value != 0 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
// Copyright 2020 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. | ||
|
||
// +build arm64 | ||
// +build !linux | ||
// +build !freebsd | ||
// +build !android | ||
// +build !darwin ios | ||
|
||
package cpu | ||
|
||
func osInit() { | ||
// Other operating systems do not support reading HWCap from auxiliary vector, | ||
// reading privileged aarch64 system registers or sysctl in user space to detect | ||
// CPU features at runtime. | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.