github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/internal/cpu/cpu_s390x.go (about) 1 // Copyright 2017 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 CacheLinePadSize = 256 8 9 var HWCap uint 10 11 // bitIsSet reports whether the bit at index is set. The bit index 12 // is in big endian order, so bit index 0 is the leftmost bit. 13 func bitIsSet(bits []uint64, index uint) bool { 14 return bits[index/64]&((1<<63)>>(index%64)) != 0 15 } 16 17 // function is the function code for the named function. 18 type function uint8 19 20 const ( 21 // KM{,A,C,CTR} function codes 22 aes128 function = 18 // AES-128 23 aes192 function = 19 // AES-192 24 aes256 function = 20 // AES-256 25 26 // K{I,L}MD function codes 27 sha1 function = 1 // SHA-1 28 sha256 function = 2 // SHA-256 29 sha512 function = 3 // SHA-512 30 sha3_224 function = 32 // SHA3-224 31 sha3_256 function = 33 // SHA3-256 32 sha3_384 function = 34 // SHA3-384 33 sha3_512 function = 35 // SHA3-512 34 shake128 function = 36 // SHAKE-128 35 shake256 function = 37 // SHAKE-256 36 37 // KLMD function codes 38 ghash function = 65 // GHASH 39 ) 40 41 const ( 42 // KDSA function codes 43 ecdsaVerifyP256 function = 1 // NIST P256 44 ecdsaVerifyP384 function = 2 // NIST P384 45 ecdsaVerifyP521 function = 3 // NIST P521 46 ecdsaSignP256 function = 9 // NIST P256 47 ecdsaSignP384 function = 10 // NIST P384 48 ecdsaSignP521 function = 11 // NIST P521 49 eddsaVerifyEd25519 function = 32 // Curve25519 50 eddsaVerifyEd448 function = 36 // Curve448 51 eddsaSignEd25519 function = 40 // Curve25519 52 eddsaSignEd448 function = 44 // Curve448 53 ) 54 55 // queryResult contains the result of a Query function 56 // call. Bits are numbered in big endian order so the 57 // leftmost bit (the MSB) is at index 0. 58 type queryResult struct { 59 bits [2]uint64 60 } 61 62 // Has reports whether the given functions are present. 63 func (q *queryResult) Has(fns ...function) bool { 64 if len(fns) == 0 { 65 panic("no function codes provided") 66 } 67 for _, f := range fns { 68 if !bitIsSet(q.bits[:], uint(f)) { 69 return false 70 } 71 } 72 return true 73 } 74 75 // facility is a bit index for the named facility. 76 type facility uint8 77 78 const ( 79 // mandatory facilities 80 zarch facility = 1 // z architecture mode is active 81 stflef facility = 7 // store-facility-list-extended 82 ldisp facility = 18 // long-displacement 83 eimm facility = 21 // extended-immediate 84 85 // miscellaneous facilities 86 dfp facility = 42 // decimal-floating-point 87 etf3eh facility = 30 // extended-translation 3 enhancement 88 89 // cryptography facilities 90 msa facility = 17 // message-security-assist 91 msa3 facility = 76 // message-security-assist extension 3 92 msa4 facility = 77 // message-security-assist extension 4 93 msa5 facility = 57 // message-security-assist extension 5 94 msa8 facility = 146 // message-security-assist extension 8 95 msa9 facility = 155 // message-security-assist extension 9 96 97 // vector facilities 98 vxe facility = 135 // vector-enhancements 1 99 100 // Note: vx requires kernel support 101 // and so must be fetched from HWCAP. 102 103 hwcap_VX = 1 << 11 // vector facility 104 ) 105 106 // facilityList contains the result of an STFLE call. 107 // Bits are numbered in big endian order so the 108 // leftmost bit (the MSB) is at index 0. 109 type facilityList struct { 110 bits [4]uint64 111 } 112 113 // Has reports whether the given facilities are present. 114 func (s *facilityList) Has(fs ...facility) bool { 115 if len(fs) == 0 { 116 panic("no facility bits provided") 117 } 118 for _, f := range fs { 119 if !bitIsSet(s.bits[:], uint(f)) { 120 return false 121 } 122 } 123 return true 124 } 125 126 // The following feature detection functions are defined in cpu_s390x.s. 127 // They are likely to be expensive to call so the results should be cached. 128 func stfle() facilityList 129 func kmQuery() queryResult 130 func kmcQuery() queryResult 131 func kmctrQuery() queryResult 132 func kmaQuery() queryResult 133 func kimdQuery() queryResult 134 func klmdQuery() queryResult 135 func kdsaQuery() queryResult 136 137 func doinit() { 138 options = []option{ 139 {Name: "zarch", Feature: &S390X.HasZARCH}, 140 {Name: "stfle", Feature: &S390X.HasSTFLE}, 141 {Name: "ldisp", Feature: &S390X.HasLDISP}, 142 {Name: "msa", Feature: &S390X.HasMSA}, 143 {Name: "eimm", Feature: &S390X.HasEIMM}, 144 {Name: "dfp", Feature: &S390X.HasDFP}, 145 {Name: "etf3eh", Feature: &S390X.HasETF3EH}, 146 {Name: "vx", Feature: &S390X.HasVX}, 147 {Name: "vxe", Feature: &S390X.HasVXE}, 148 {Name: "kdsa", Feature: &S390X.HasKDSA}, 149 } 150 151 aes := []function{aes128, aes192, aes256} 152 facilities := stfle() 153 154 S390X.HasZARCH = facilities.Has(zarch) 155 S390X.HasSTFLE = facilities.Has(stflef) 156 S390X.HasLDISP = facilities.Has(ldisp) 157 S390X.HasEIMM = facilities.Has(eimm) 158 S390X.HasDFP = facilities.Has(dfp) 159 S390X.HasETF3EH = facilities.Has(etf3eh) 160 S390X.HasMSA = facilities.Has(msa) 161 162 if S390X.HasMSA { 163 // cipher message 164 km, kmc := kmQuery(), kmcQuery() 165 S390X.HasAES = km.Has(aes...) 166 S390X.HasAESCBC = kmc.Has(aes...) 167 if facilities.Has(msa4) { 168 kmctr := kmctrQuery() 169 S390X.HasAESCTR = kmctr.Has(aes...) 170 } 171 if facilities.Has(msa8) { 172 kma := kmaQuery() 173 S390X.HasAESGCM = kma.Has(aes...) 174 } 175 176 // compute message digest 177 kimd := kimdQuery() // intermediate (no padding) 178 klmd := klmdQuery() // last (padding) 179 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 180 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 181 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 182 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 183 sha3 := []function{ 184 sha3_224, sha3_256, sha3_384, sha3_512, 185 shake128, shake256, 186 } 187 S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) 188 S390X.HasKDSA = facilities.Has(msa9) // elliptic curves 189 if S390X.HasKDSA { 190 kdsa := kdsaQuery() 191 S390X.HasECDSA = kdsa.Has(ecdsaVerifyP256, ecdsaSignP256, ecdsaVerifyP384, ecdsaSignP384, ecdsaVerifyP521, ecdsaSignP521) 192 S390X.HasEDDSA = kdsa.Has(eddsaVerifyEd25519, eddsaSignEd25519, eddsaVerifyEd448, eddsaSignEd448) 193 } 194 } 195 196 S390X.HasVX = isSet(HWCap, hwcap_VX) 197 198 if S390X.HasVX { 199 S390X.HasVXE = facilities.Has(vxe) 200 } 201 } 202 203 func isSet(hwc uint, value uint) bool { 204 return hwc&value != 0 205 }