github.com/sandwichdev/go-internals@v0.0.0-20210605002614-12311ac6b2c5/cpu/cpu_arm64_hwcap.go (about) 1 // Copyright 2020 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 // +build arm64 6 // +build linux 7 8 package cpu 9 10 // HWCap may be initialized by archauxv and 11 // should not be changed after it was initialized. 12 var HWCap uint 13 14 // HWCAP bits. These are exposed by Linux. 15 const ( 16 hwcap_AES = 1 << 3 17 hwcap_PMULL = 1 << 4 18 hwcap_SHA1 = 1 << 5 19 hwcap_SHA2 = 1 << 6 20 hwcap_CRC32 = 1 << 7 21 hwcap_ATOMICS = 1 << 8 22 hwcap_CPUID = 1 << 11 23 ) 24 25 func hwcapInit(os string) { 26 // HWCap was populated by the runtime from the auxiliary vector. 27 // Use HWCap information since reading aarch64 system registers 28 // is not supported in user space on older linux kernels. 29 ARM64.HasAES = isSet(HWCap, hwcap_AES) 30 ARM64.HasPMULL = isSet(HWCap, hwcap_PMULL) 31 ARM64.HasSHA1 = isSet(HWCap, hwcap_SHA1) 32 ARM64.HasSHA2 = isSet(HWCap, hwcap_SHA2) 33 ARM64.HasCRC32 = isSet(HWCap, hwcap_CRC32) 34 ARM64.HasCPUID = isSet(HWCap, hwcap_CPUID) 35 36 // The Samsung S9+ kernel reports support for atomics, but not all cores 37 // actually support them, resulting in SIGILL. See issue #28431. 38 // TODO(elias.naur): Only disable the optimization on bad chipsets on android. 39 ARM64.HasATOMICS = isSet(HWCap, hwcap_ATOMICS) && os != "android" 40 41 // Check to see if executing on a NeoverseN1 and in order to do that, 42 // check the AUXV for the CPUID bit. The getMIDR function executes an 43 // instruction which would normally be an illegal instruction, but it's 44 // trapped by the kernel, the value sanitized and then returned. Without 45 // the CPUID bit the kernel will not trap the instruction and the process 46 // will be terminated with SIGILL. 47 if ARM64.HasCPUID { 48 midr := getMIDR() 49 part_num := uint16((midr >> 4) & 0xfff) 50 implementor := byte((midr >> 24) & 0xff) 51 52 if implementor == 'A' && part_num == 0xd0c { 53 ARM64.IsNeoverseN1 = true 54 } 55 if implementor == 'A' && part_num == 0xd40 { 56 ARM64.IsZeus = true 57 } 58 } 59 } 60 61 func isSet(hwc uint, value uint) bool { 62 return hwc&value != 0 63 }