github.com/Andyfoo/golang/x/sys@v0.0.0-20190901054642-57c1bf301704/cpu/cpu_linux_s390x.go (about) 1 // Copyright 2019 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 package cpu 6 7 const cacheLineSize = 256 8 9 const ( 10 // bit mask values from /usr/include/bits/hwcap.h 11 hwcap_ZARCH = 2 12 hwcap_STFLE = 4 13 hwcap_MSA = 8 14 hwcap_LDISP = 16 15 hwcap_EIMM = 32 16 hwcap_DFP = 64 17 hwcap_ETF3EH = 256 18 hwcap_VX = 2048 19 hwcap_VXE = 8192 20 ) 21 22 // bitIsSet reports whether the bit at index is set. The bit index 23 // is in big endian order, so bit index 0 is the leftmost bit. 24 func bitIsSet(bits []uint64, index uint) bool { 25 return bits[index/64]&((1<<63)>>(index%64)) != 0 26 } 27 28 // function is the code for the named cryptographic function. 29 type function uint8 30 31 const ( 32 // KM{,A,C,CTR} function codes 33 aes128 function = 18 // AES-128 34 aes192 function = 19 // AES-192 35 aes256 function = 20 // AES-256 36 37 // K{I,L}MD function codes 38 sha1 function = 1 // SHA-1 39 sha256 function = 2 // SHA-256 40 sha512 function = 3 // SHA-512 41 sha3_224 function = 32 // SHA3-224 42 sha3_256 function = 33 // SHA3-256 43 sha3_384 function = 34 // SHA3-384 44 sha3_512 function = 35 // SHA3-512 45 shake128 function = 36 // SHAKE-128 46 shake256 function = 37 // SHAKE-256 47 48 // KLMD function codes 49 ghash function = 65 // GHASH 50 ) 51 52 // queryResult contains the result of a Query function 53 // call. Bits are numbered in big endian order so the 54 // leftmost bit (the MSB) is at index 0. 55 type queryResult struct { 56 bits [2]uint64 57 } 58 59 // Has reports whether the given functions are present. 60 func (q *queryResult) Has(fns ...function) bool { 61 if len(fns) == 0 { 62 panic("no function codes provided") 63 } 64 for _, f := range fns { 65 if !bitIsSet(q.bits[:], uint(f)) { 66 return false 67 } 68 } 69 return true 70 } 71 72 // facility is a bit index for the named facility. 73 type facility uint8 74 75 const ( 76 // cryptography facilities 77 msa4 facility = 77 // message-security-assist extension 4 78 msa8 facility = 146 // message-security-assist extension 8 79 ) 80 81 // facilityList contains the result of an STFLE call. 82 // Bits are numbered in big endian order so the 83 // leftmost bit (the MSB) is at index 0. 84 type facilityList struct { 85 bits [4]uint64 86 } 87 88 // Has reports whether the given facilities are present. 89 func (s *facilityList) Has(fs ...facility) bool { 90 if len(fs) == 0 { 91 panic("no facility bits provided") 92 } 93 for _, f := range fs { 94 if !bitIsSet(s.bits[:], uint(f)) { 95 return false 96 } 97 } 98 return true 99 } 100 101 func doinit() { 102 // test HWCAP bit vector 103 has := func(featureMask uint) bool { 104 return hwCap&featureMask == featureMask 105 } 106 107 // mandatory 108 S390X.HasZARCH = has(hwcap_ZARCH) 109 110 // optional 111 S390X.HasSTFLE = has(hwcap_STFLE) 112 S390X.HasLDISP = has(hwcap_LDISP) 113 S390X.HasEIMM = has(hwcap_EIMM) 114 S390X.HasETF3EH = has(hwcap_ETF3EH) 115 S390X.HasDFP = has(hwcap_DFP) 116 S390X.HasMSA = has(hwcap_MSA) 117 S390X.HasVX = has(hwcap_VX) 118 if S390X.HasVX { 119 S390X.HasVXE = has(hwcap_VXE) 120 } 121 122 // We need implementations of stfle, km and so on 123 // to detect cryptographic features. 124 if !haveAsmFunctions() { 125 return 126 } 127 128 // optional cryptographic functions 129 if S390X.HasMSA { 130 aes := []function{aes128, aes192, aes256} 131 132 // cipher message 133 km, kmc := kmQuery(), kmcQuery() 134 S390X.HasAES = km.Has(aes...) 135 S390X.HasAESCBC = kmc.Has(aes...) 136 if S390X.HasSTFLE { 137 facilities := stfle() 138 if facilities.Has(msa4) { 139 kmctr := kmctrQuery() 140 S390X.HasAESCTR = kmctr.Has(aes...) 141 } 142 if facilities.Has(msa8) { 143 kma := kmaQuery() 144 S390X.HasAESGCM = kma.Has(aes...) 145 } 146 } 147 148 // compute message digest 149 kimd := kimdQuery() // intermediate (no padding) 150 klmd := klmdQuery() // last (padding) 151 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 152 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 153 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 154 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 155 sha3 := []function{ 156 sha3_224, sha3_256, sha3_384, sha3_512, 157 shake128, shake256, 158 } 159 S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) 160 } 161 }