gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

os_linux_arm64.go (3972B)


      1 // Copyright (c) 2020 Klaus Post, released under MIT License. See LICENSE file.
      2 
      3 // Copyright 2018 The Go Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style
      5 // license that can be found in the LICENSE file located
      6 // here https://github.com/golang/sys/blob/master/LICENSE
      7 
      8 package cpuid
      9 
     10 import (
     11 	"encoding/binary"
     12 	"io/ioutil"
     13 	"runtime"
     14 )
     15 
     16 // HWCAP bits.
     17 const (
     18 	hwcap_FP       = 1 << 0
     19 	hwcap_ASIMD    = 1 << 1
     20 	hwcap_EVTSTRM  = 1 << 2
     21 	hwcap_AES      = 1 << 3
     22 	hwcap_PMULL    = 1 << 4
     23 	hwcap_SHA1     = 1 << 5
     24 	hwcap_SHA2     = 1 << 6
     25 	hwcap_CRC32    = 1 << 7
     26 	hwcap_ATOMICS  = 1 << 8
     27 	hwcap_FPHP     = 1 << 9
     28 	hwcap_ASIMDHP  = 1 << 10
     29 	hwcap_CPUID    = 1 << 11
     30 	hwcap_ASIMDRDM = 1 << 12
     31 	hwcap_JSCVT    = 1 << 13
     32 	hwcap_FCMA     = 1 << 14
     33 	hwcap_LRCPC    = 1 << 15
     34 	hwcap_DCPOP    = 1 << 16
     35 	hwcap_SHA3     = 1 << 17
     36 	hwcap_SM3      = 1 << 18
     37 	hwcap_SM4      = 1 << 19
     38 	hwcap_ASIMDDP  = 1 << 20
     39 	hwcap_SHA512   = 1 << 21
     40 	hwcap_SVE      = 1 << 22
     41 	hwcap_ASIMDFHM = 1 << 23
     42 )
     43 
     44 func detectOS(c *CPUInfo) bool {
     45 	// For now assuming no hyperthreading is reasonable.
     46 	c.LogicalCores = runtime.NumCPU()
     47 	c.PhysicalCores = c.LogicalCores
     48 	c.ThreadsPerCore = 1
     49 	if hwcap == 0 {
     50 		// We did not get values from the runtime.
     51 		// Try reading /proc/self/auxv
     52 
     53 		// From https://github.com/golang/sys
     54 		const (
     55 			_AT_HWCAP  = 16
     56 			_AT_HWCAP2 = 26
     57 
     58 			uintSize = int(32 << (^uint(0) >> 63))
     59 		)
     60 
     61 		buf, err := ioutil.ReadFile("/proc/self/auxv")
     62 		if err != nil {
     63 			// e.g. on android /proc/self/auxv is not accessible, so silently
     64 			// ignore the error and leave Initialized = false. On some
     65 			// architectures (e.g. arm64) doinit() implements a fallback
     66 			// readout and will set Initialized = true again.
     67 			return false
     68 		}
     69 		bo := binary.LittleEndian
     70 		for len(buf) >= 2*(uintSize/8) {
     71 			var tag, val uint
     72 			switch uintSize {
     73 			case 32:
     74 				tag = uint(bo.Uint32(buf[0:]))
     75 				val = uint(bo.Uint32(buf[4:]))
     76 				buf = buf[8:]
     77 			case 64:
     78 				tag = uint(bo.Uint64(buf[0:]))
     79 				val = uint(bo.Uint64(buf[8:]))
     80 				buf = buf[16:]
     81 			}
     82 			switch tag {
     83 			case _AT_HWCAP:
     84 				hwcap = val
     85 			case _AT_HWCAP2:
     86 				// Not used
     87 			}
     88 		}
     89 		if hwcap == 0 {
     90 			return false
     91 		}
     92 	}
     93 
     94 	// HWCap was populated by the runtime from the auxiliary vector.
     95 	// Use HWCap information since reading aarch64 system registers
     96 	// is not supported in user space on older linux kernels.
     97 	c.featureSet.setIf(isSet(hwcap, hwcap_AES), AESARM)
     98 	c.featureSet.setIf(isSet(hwcap, hwcap_ASIMD), ASIMD)
     99 	c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDDP), ASIMDDP)
    100 	c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDHP), ASIMDHP)
    101 	c.featureSet.setIf(isSet(hwcap, hwcap_ASIMDRDM), ASIMDRDM)
    102 	c.featureSet.setIf(isSet(hwcap, hwcap_CPUID), ARMCPUID)
    103 	c.featureSet.setIf(isSet(hwcap, hwcap_CRC32), CRC32)
    104 	c.featureSet.setIf(isSet(hwcap, hwcap_DCPOP), DCPOP)
    105 	c.featureSet.setIf(isSet(hwcap, hwcap_EVTSTRM), EVTSTRM)
    106 	c.featureSet.setIf(isSet(hwcap, hwcap_FCMA), FCMA)
    107 	c.featureSet.setIf(isSet(hwcap, hwcap_FP), FP)
    108 	c.featureSet.setIf(isSet(hwcap, hwcap_FPHP), FPHP)
    109 	c.featureSet.setIf(isSet(hwcap, hwcap_JSCVT), JSCVT)
    110 	c.featureSet.setIf(isSet(hwcap, hwcap_LRCPC), LRCPC)
    111 	c.featureSet.setIf(isSet(hwcap, hwcap_PMULL), PMULL)
    112 	c.featureSet.setIf(isSet(hwcap, hwcap_SHA1), SHA1)
    113 	c.featureSet.setIf(isSet(hwcap, hwcap_SHA2), SHA2)
    114 	c.featureSet.setIf(isSet(hwcap, hwcap_SHA3), SHA3)
    115 	c.featureSet.setIf(isSet(hwcap, hwcap_SHA512), SHA512)
    116 	c.featureSet.setIf(isSet(hwcap, hwcap_SM3), SM3)
    117 	c.featureSet.setIf(isSet(hwcap, hwcap_SM4), SM4)
    118 	c.featureSet.setIf(isSet(hwcap, hwcap_SVE), SVE)
    119 
    120 	// The Samsung S9+ kernel reports support for atomics, but not all cores
    121 	// actually support them, resulting in SIGILL. See issue #28431.
    122 	// TODO(elias.naur): Only disable the optimization on bad chipsets on android.
    123 	c.featureSet.setIf(isSet(hwcap, hwcap_ATOMICS) && runtime.GOOS != "android", ATOMICS)
    124 
    125 	return true
    126 }
    127 
    128 func isSet(hwc uint, value uint) bool {
    129 	return hwc&value != 0
    130 }