cpu_s390x.go (4993B)
1 // Copyright 2020 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 func initOptions() { 10 options = []option{ 11 {Name: "zarch", Feature: &S390X.HasZARCH, Required: true}, 12 {Name: "stfle", Feature: &S390X.HasSTFLE, Required: true}, 13 {Name: "ldisp", Feature: &S390X.HasLDISP, Required: true}, 14 {Name: "eimm", Feature: &S390X.HasEIMM, Required: true}, 15 {Name: "dfp", Feature: &S390X.HasDFP}, 16 {Name: "etf3eh", Feature: &S390X.HasETF3EH}, 17 {Name: "msa", Feature: &S390X.HasMSA}, 18 {Name: "aes", Feature: &S390X.HasAES}, 19 {Name: "aescbc", Feature: &S390X.HasAESCBC}, 20 {Name: "aesctr", Feature: &S390X.HasAESCTR}, 21 {Name: "aesgcm", Feature: &S390X.HasAESGCM}, 22 {Name: "ghash", Feature: &S390X.HasGHASH}, 23 {Name: "sha1", Feature: &S390X.HasSHA1}, 24 {Name: "sha256", Feature: &S390X.HasSHA256}, 25 {Name: "sha3", Feature: &S390X.HasSHA3}, 26 {Name: "sha512", Feature: &S390X.HasSHA512}, 27 {Name: "vx", Feature: &S390X.HasVX}, 28 {Name: "vxe", Feature: &S390X.HasVXE}, 29 } 30 } 31 32 // bitIsSet reports whether the bit at index is set. The bit index 33 // is in big endian order, so bit index 0 is the leftmost bit. 34 func bitIsSet(bits []uint64, index uint) bool { 35 return bits[index/64]&((1<<63)>>(index%64)) != 0 36 } 37 38 // facility is a bit index for the named facility. 39 type facility uint8 40 41 const ( 42 // mandatory facilities 43 zarch facility = 1 // z architecture mode is active 44 stflef facility = 7 // store-facility-list-extended 45 ldisp facility = 18 // long-displacement 46 eimm facility = 21 // extended-immediate 47 48 // miscellaneous facilities 49 dfp facility = 42 // decimal-floating-point 50 etf3eh facility = 30 // extended-translation 3 enhancement 51 52 // cryptography facilities 53 msa facility = 17 // message-security-assist 54 msa3 facility = 76 // message-security-assist extension 3 55 msa4 facility = 77 // message-security-assist extension 4 56 msa5 facility = 57 // message-security-assist extension 5 57 msa8 facility = 146 // message-security-assist extension 8 58 msa9 facility = 155 // message-security-assist extension 9 59 60 // vector facilities 61 vx facility = 129 // vector facility 62 vxe facility = 135 // vector-enhancements 1 63 vxe2 facility = 148 // vector-enhancements 2 64 ) 65 66 // facilityList contains the result of an STFLE call. 67 // Bits are numbered in big endian order so the 68 // leftmost bit (the MSB) is at index 0. 69 type facilityList struct { 70 bits [4]uint64 71 } 72 73 // Has reports whether the given facilities are present. 74 func (s *facilityList) Has(fs ...facility) bool { 75 if len(fs) == 0 { 76 panic("no facility bits provided") 77 } 78 for _, f := range fs { 79 if !bitIsSet(s.bits[:], uint(f)) { 80 return false 81 } 82 } 83 return true 84 } 85 86 // function is the code for the named cryptographic function. 87 type function uint8 88 89 const ( 90 // KM{,A,C,CTR} function codes 91 aes128 function = 18 // AES-128 92 aes192 function = 19 // AES-192 93 aes256 function = 20 // AES-256 94 95 // K{I,L}MD function codes 96 sha1 function = 1 // SHA-1 97 sha256 function = 2 // SHA-256 98 sha512 function = 3 // SHA-512 99 sha3_224 function = 32 // SHA3-224 100 sha3_256 function = 33 // SHA3-256 101 sha3_384 function = 34 // SHA3-384 102 sha3_512 function = 35 // SHA3-512 103 shake128 function = 36 // SHAKE-128 104 shake256 function = 37 // SHAKE-256 105 106 // KLMD function codes 107 ghash function = 65 // GHASH 108 ) 109 110 // queryResult contains the result of a Query function 111 // call. Bits are numbered in big endian order so the 112 // leftmost bit (the MSB) is at index 0. 113 type queryResult struct { 114 bits [2]uint64 115 } 116 117 // Has reports whether the given functions are present. 118 func (q *queryResult) Has(fns ...function) bool { 119 if len(fns) == 0 { 120 panic("no function codes provided") 121 } 122 for _, f := range fns { 123 if !bitIsSet(q.bits[:], uint(f)) { 124 return false 125 } 126 } 127 return true 128 } 129 130 func doinit() { 131 initS390Xbase() 132 133 // We need implementations of stfle, km and so on 134 // to detect cryptographic features. 135 if !haveAsmFunctions() { 136 return 137 } 138 139 // optional cryptographic functions 140 if S390X.HasMSA { 141 aes := []function{aes128, aes192, aes256} 142 143 // cipher message 144 km, kmc := kmQuery(), kmcQuery() 145 S390X.HasAES = km.Has(aes...) 146 S390X.HasAESCBC = kmc.Has(aes...) 147 if S390X.HasSTFLE { 148 facilities := stfle() 149 if facilities.Has(msa4) { 150 kmctr := kmctrQuery() 151 S390X.HasAESCTR = kmctr.Has(aes...) 152 } 153 if facilities.Has(msa8) { 154 kma := kmaQuery() 155 S390X.HasAESGCM = kma.Has(aes...) 156 } 157 } 158 159 // compute message digest 160 kimd := kimdQuery() // intermediate (no padding) 161 klmd := klmdQuery() // last (padding) 162 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 163 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 164 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 165 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 166 sha3 := []function{ 167 sha3_224, sha3_256, sha3_384, sha3_512, 168 shake128, shake256, 169 } 170 S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...) 171 } 172 }