2021-06-28 06:53:50 +00:00
|
|
|
// Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
|
|
|
|
|
|
|
|
package cpuid
|
|
|
|
|
2022-11-04 13:57:20 +00:00
|
|
|
import (
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"golang.org/x/sys/unix"
|
|
|
|
)
|
2021-06-28 06:53:50 +00:00
|
|
|
|
|
|
|
func detectOS(c *CPUInfo) bool {
|
2022-11-04 13:57:20 +00:00
|
|
|
if runtime.GOOS != "ios" {
|
|
|
|
tryToFillCPUInfoFomSysctl(c)
|
|
|
|
}
|
2021-06-28 06:53:50 +00:00
|
|
|
// 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.
|
|
|
|
// TODO: Add more if we know them.
|
|
|
|
c.featureSet.setIf(runtime.GOOS != "ios", AESARM, PMULL, SHA1, SHA2)
|
2022-11-04 13:57:20 +00:00
|
|
|
|
2021-06-28 06:53:50 +00:00
|
|
|
return true
|
|
|
|
}
|
2022-11-04 13:57:20 +00:00
|
|
|
|
|
|
|
func sysctlGetBool(name string) bool {
|
|
|
|
value, err := unix.SysctlUint32(name)
|
|
|
|
if err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return value != 0
|
|
|
|
}
|
|
|
|
|
|
|
|
func sysctlGetString(name string) string {
|
|
|
|
value, err := unix.Sysctl(name)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
return value
|
|
|
|
}
|
|
|
|
|
|
|
|
func sysctlGetInt(unknown int, names ...string) int {
|
|
|
|
for _, name := range names {
|
|
|
|
value, err := unix.SysctlUint32(name)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if value != 0 {
|
|
|
|
return int(value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
func sysctlGetInt64(unknown int, names ...string) int {
|
|
|
|
for _, name := range names {
|
|
|
|
value64, err := unix.SysctlUint64(name)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if int(value64) != unknown {
|
|
|
|
return int(value64)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return unknown
|
|
|
|
}
|
|
|
|
|
|
|
|
func setFeature(c *CPUInfo, name string, feature FeatureID) {
|
|
|
|
c.featureSet.setIf(sysctlGetBool(name), feature)
|
|
|
|
}
|
|
|
|
func tryToFillCPUInfoFomSysctl(c *CPUInfo) {
|
|
|
|
c.BrandName = sysctlGetString("machdep.cpu.brand_string")
|
|
|
|
|
|
|
|
if len(c.BrandName) != 0 {
|
|
|
|
c.VendorString = strings.Fields(c.BrandName)[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
c.PhysicalCores = sysctlGetInt(runtime.NumCPU(), "hw.physicalcpu")
|
|
|
|
c.ThreadsPerCore = sysctlGetInt(1, "machdep.cpu.thread_count", "kern.num_threads") /
|
|
|
|
sysctlGetInt(1, "hw.physicalcpu")
|
|
|
|
c.LogicalCores = sysctlGetInt(runtime.NumCPU(), "machdep.cpu.core_count")
|
|
|
|
c.Family = sysctlGetInt(0, "machdep.cpu.family", "hw.cpufamily")
|
|
|
|
c.Model = sysctlGetInt(0, "machdep.cpu.model")
|
|
|
|
c.CacheLine = sysctlGetInt64(0, "hw.cachelinesize")
|
|
|
|
c.Cache.L1I = sysctlGetInt64(-1, "hw.l1icachesize")
|
|
|
|
c.Cache.L1D = sysctlGetInt64(-1, "hw.l1icachesize")
|
|
|
|
c.Cache.L2 = sysctlGetInt64(-1, "hw.l2cachesize")
|
|
|
|
c.Cache.L3 = sysctlGetInt64(-1, "hw.l3cachesize")
|
|
|
|
|
|
|
|
// from https://developer.arm.com/downloads/-/exploration-tools/feature-names-for-a-profile
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_AES", AESARM)
|
|
|
|
setFeature(c, "hw.optional.AdvSIMD", ASIMD)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_DotProd", ASIMDDP)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_RDM", ASIMDRDM)
|
|
|
|
setFeature(c, "hw.optional.FEAT_CRC32", CRC32)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_DPB", DCPOP)
|
|
|
|
// setFeature(c, "", EVTSTRM)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_FCMA", FCMA)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_FP", FP)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_FP16", FPHP)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_PAuth", GPA)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_JSCVT", JSCVT)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_LRCPC", LRCPC)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_PMULL", PMULL)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_SHA1", SHA1)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_SHA256", SHA2)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_SHA3", SHA3)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_SHA512", SHA512)
|
|
|
|
// setFeature(c, "", SM3)
|
|
|
|
// setFeature(c, "", SM4)
|
|
|
|
setFeature(c, "hw.optional.arm.FEAT_SVE", SVE)
|
|
|
|
|
|
|
|
// from empirical observation
|
|
|
|
setFeature(c, "hw.optional.AdvSIMD_HPFPCvt", ASIMDHP)
|
|
|
|
setFeature(c, "hw.optional.armv8_1_atomics", ATOMICS)
|
|
|
|
setFeature(c, "hw.optional.floatingpoint", FP)
|
|
|
|
setFeature(c, "hw.optional.armv8_2_sha3", SHA3)
|
|
|
|
setFeature(c, "hw.optional.armv8_2_sha512", SHA512)
|
|
|
|
setFeature(c, "hw.optional.armv8_3_compnum", FCMA)
|
|
|
|
setFeature(c, "hw.optional.armv8_crc32", CRC32)
|
|
|
|
}
|