github.com/hikaru7719/go@v0.0.0-20181025140707-c8b2ac68906a/src/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 // bitIsSet reports whether the bit at index is set. The bit index 10 // is in big endian order, so bit index 0 is the leftmost bit. 11 func bitIsSet(bits []uint64, index uint) bool { 12 return bits[index/64]&((1<<63)>>(index%64)) != 0 13 } 14 15 // function is the function code for the named function. 16 type function uint8 17 18 const ( 19 // KM{,A,C,CTR} function codes 20 aes128 function = 18 // AES-128 21 aes192 function = 19 // AES-192 22 aes256 function = 20 // AES-256 23 24 // K{I,L}MD function codes 25 sha1 function = 1 // SHA-1 26 sha256 function = 2 // SHA-256 27 sha512 function = 3 // SHA-512 28 29 // KLMD function codes 30 ghash function = 65 // GHASH 31 ) 32 33 // queryResult contains the result of a Query function 34 // call. Bits are numbered in big endian order so the 35 // leftmost bit (the MSB) is at index 0. 36 type queryResult struct { 37 bits [2]uint64 38 } 39 40 // Has reports whether the given functions are present. 41 func (q *queryResult) Has(fns ...function) bool { 42 if len(fns) == 0 { 43 panic("no function codes provided") 44 } 45 for _, f := range fns { 46 if !bitIsSet(q.bits[:], uint(f)) { 47 return false 48 } 49 } 50 return true 51 } 52 53 // facility is a bit index for the named facility. 54 type facility uint8 55 56 const ( 57 // mandatory facilities 58 zarch facility = 1 // z architecture mode is active 59 stflef facility = 7 // store-facility-list-extended 60 ldisp facility = 18 // long-displacement 61 eimm facility = 21 // extended-immediate 62 63 // miscellaneous facilities 64 dfp facility = 42 // decimal-floating-point 65 etf3eh facility = 30 // extended-translation 3 enhancement 66 67 // cryptography facilities 68 msa facility = 17 // message-security-assist 69 msa3 facility = 76 // message-security-assist extension 3 70 msa4 facility = 77 // message-security-assist extension 4 71 msa5 facility = 57 // message-security-assist extension 5 72 msa8 facility = 146 // message-security-assist extension 8 73 74 // Note: vx and highgprs are excluded because they require 75 // kernel support and so must be fetched from HWCAP. 76 ) 77 78 // facilityList contains the result of an STFLE call. 79 // Bits are numbered in big endian order so the 80 // leftmost bit (the MSB) is at index 0. 81 type facilityList struct { 82 bits [4]uint64 83 } 84 85 // Has reports whether the given facilities are present. 86 func (s *facilityList) Has(fs ...facility) bool { 87 if len(fs) == 0 { 88 panic("no facility bits provided") 89 } 90 for _, f := range fs { 91 if !bitIsSet(s.bits[:], uint(f)) { 92 return false 93 } 94 } 95 return true 96 } 97 98 // The following feature detection functions are defined in cpu_s390x.s. 99 // They are likely to be expensive to call so the results should be cached. 100 func stfle() facilityList 101 func kmQuery() queryResult 102 func kmcQuery() queryResult 103 func kmctrQuery() queryResult 104 func kmaQuery() queryResult 105 func kimdQuery() queryResult 106 func klmdQuery() queryResult 107 108 func doinit() { 109 options = []option{ 110 {Name: "zarch", Feature: &S390X.HasZArch}, 111 {Name: "stfle", Feature: &S390X.HasSTFLE}, 112 {Name: "ldisp", Feature: &S390X.HasLDisp}, 113 {Name: "msa", Feature: &S390X.HasMSA}, 114 {Name: "eimm", Feature: &S390X.HasEImm}, 115 {Name: "dfp", Feature: &S390X.HasDFP}, 116 {Name: "etf3eh", Feature: &S390X.HasETF3Enhanced}, 117 {Name: "vx", Feature: &S390X.HasVX}, 118 } 119 120 aes := []function{aes128, aes192, aes256} 121 facilities := stfle() 122 123 S390X.HasZArch = facilities.Has(zarch) 124 S390X.HasSTFLE = facilities.Has(stflef) 125 S390X.HasLDisp = facilities.Has(ldisp) 126 S390X.HasEImm = facilities.Has(eimm) 127 S390X.HasDFP = facilities.Has(dfp) 128 S390X.HasETF3Enhanced = facilities.Has(etf3eh) 129 S390X.HasMSA = facilities.Has(msa) 130 131 if S390X.HasMSA { 132 // cipher message 133 km, kmc := kmQuery(), kmcQuery() 134 S390X.HasAES = km.Has(aes...) 135 S390X.HasAESCBC = kmc.Has(aes...) 136 if facilities.Has(msa4) { 137 kmctr := kmctrQuery() 138 S390X.HasAESCTR = kmctr.Has(aes...) 139 } 140 if facilities.Has(msa8) { 141 kma := kmaQuery() 142 S390X.HasAESGCM = kma.Has(aes...) 143 } 144 145 // compute message digest 146 kimd := kimdQuery() // intermediate (no padding) 147 klmd := klmdQuery() // last (padding) 148 S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1) 149 S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256) 150 S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512) 151 S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist 152 } 153 }