summaryrefslogtreecommitdiff
path: root/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go')
-rw-r--r--vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go130
1 files changed, 130 insertions, 0 deletions
diff --git a/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go b/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go
new file mode 100644
index 000000000..ee278b9e4
--- /dev/null
+++ b/vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go
@@ -0,0 +1,130 @@
+// Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
+
+// Copyright 2018 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 located
+// here https://github.com/golang/sys/blob/master/LICENSE
+
+package cpuid
+
+import (
+ "encoding/binary"
+ "io/ioutil"
+ "runtime"
+)
+
+// HWCAP bits.
+const (
+ hwcap_FP = 1 << 0
+ hwcap_ASIMD = 1 << 1
+ hwcap_EVTSTRM = 1 << 2
+ 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_FPHP = 1 << 9
+ hwcap_ASIMDHP = 1 << 10
+ hwcap_CPUID = 1 << 11
+ hwcap_ASIMDRDM = 1 << 12
+ hwcap_JSCVT = 1 << 13
+ hwcap_FCMA = 1 << 14
+ hwcap_LRCPC = 1 << 15
+ hwcap_DCPOP = 1 << 16
+ hwcap_SHA3 = 1 << 17
+ hwcap_SM3 = 1 << 18
+ hwcap_SM4 = 1 << 19
+ hwcap_ASIMDDP = 1 << 20
+ hwcap_SHA512 = 1 << 21
+ hwcap_SVE = 1 << 22
+ hwcap_ASIMDFHM = 1 << 23
+)
+
+func detectOS(c *CPUInfo) bool {
+ // For now assuming no hyperthreading is reasonable.
+ c.LogicalCores = runtime.NumCPU()
+ c.PhysicalCores = c.LogicalCores
+ c.ThreadsPerCore = 1
+ if hwcap == 0 {
+ // We did not get values from the runtime.
+ // Try reading /proc/self/auxv
+
+ // From https://github.com/golang/sys
+ const (
+ _AT_HWCAP = 16
+ _AT_HWCAP2 = 26
+
+ uintSize = int(32 << (^uint(0) >> 63))
+ )
+
+ buf, err := ioutil.ReadFile("/proc/self/auxv")
+ if err != nil {
+ // e.g. on android /proc/self/auxv is not accessible, so silently
+ // ignore the error and leave Initialized = false. On some
+ // architectures (e.g. arm64) doinit() implements a fallback
+ // readout and will set Initialized = true again.
+ return false
+ }
+ bo := binary.LittleEndian
+ for len(buf) >= 2*(uintSize/8) {
+ var tag, val uint
+ switch uintSize {
+ case 32:
+ tag = uint(bo.Uint32(buf[0:]))
+ val = uint(bo.Uint32(buf[4:]))
+ buf = buf[8:]
+ case 64:
+ tag = uint(bo.Uint64(buf[0:]))
+ val = uint(bo.Uint64(buf[8:]))
+ buf = buf[16:]
+ }
+ switch tag {
+ case _AT_HWCAP:
+ hwcap = val
+ case _AT_HWCAP2:
+ // Not used
+ }
+ }
+ if hwcap == 0 {
+ return false
+ }
+ }
+
+ // 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.
+ c.featureSet.setIf(isSet(hwcap, hwcap_AES), AESARM)
+ c.featureSet.setIf(isSet(hwcap, hwcap_ASIMD), ASIMD)
+ c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDDP), ASIMDDP)
+ c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDHP), ASIMDHP)
+ c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDRDM), ASIMDRDM)
+ c.featureSet.setIf(isSet(hwcap, hwcap_CPUID), ARMCPUID)
+ c.featureSet.setIf(isSet(hwcap, hwcap_CRC32), CRC32)
+ c.featureSet.setIf(isSet(hwcap, hwcap_DCPOP), DCPOP)
+ c.featureSet.setIf(isSet(hwcap, hwcap_EVTSTRM), EVTSTRM)
+ c.featureSet.setIf(isSet(hwcap, hwcap_FCMA), FCMA)
+ c.featureSet.setIf(isSet(hwcap, hwcap_FP), FP)
+ c.featureSet.setIf(isSet(hwcap, hwcap_FPHP), FPHP)
+ c.featureSet.setIf(isSet(hwcap, hwcap_JSCVT), JSCVT)
+ c.featureSet.setIf(isSet(hwcap, hwcap_LRCPC), LRCPC)
+ c.featureSet.setIf(isSet(hwcap, hwcap_PMULL), PMULL)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SHA1), SHA1)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SHA2), SHA2)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SHA3), SHA3)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SHA512), SHA512)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SM3), SM3)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SM4), SM4)
+ c.featureSet.setIf(isSet(hwcap, hwcap_SVE), SVE)
+
+ // 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.
+ c.featureSet.setIf(isSet(hwcap, hwcap_ATOMICS) && runtime.GOOS != "android", ATOMICS)
+
+ return true
+}
+
+func isSet(hwc uint, value uint) bool {
+ return hwc&value != 0
+}