...
Run Format

Source file src/internal/cpu/cpu_s390x.go

Documentation: internal/cpu

     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 CacheLineSize = 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          = 19 // AES-192
    22  	aes256          = 20 // AES-256
    23  
    24  	// K{I,L}MD function codes
    25  	sha1   = 1 // SHA-1
    26  	sha256 = 2 // SHA-256
    27  	sha512 = 3 // SHA-512
    28  
    29  	// KLMD function codes
    30  	ghash = 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          = 7  // store-facility-list-extended
    60  	ldisp           = 18 // long-displacement
    61  	eimm            = 21 // extended-immediate
    62  
    63  	// miscellaneous facilities
    64  	dfp    = 42 // decimal-floating-point
    65  	etf3eh = 30 // extended-translation 3 enhancement
    66  
    67  	// cryptography facilities
    68  	msa  = 17  // message-security-assist
    69  	msa3 = 76  // message-security-assist extension 3
    70  	msa4 = 77  // message-security-assist extension 4
    71  	msa5 = 57  // message-security-assist extension 5
    72  	msa8 = 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  		{"zarch", &S390X.HasZArch},
   111  		{"stfle", &S390X.HasSTFLE},
   112  		{"ldisp", &S390X.HasLDisp},
   113  		{"msa", &S390X.HasMSA},
   114  		{"eimm", &S390X.HasEImm},
   115  		{"dfp", &S390X.HasDFP},
   116  		{"etf3eh", &S390X.HasETF3Enhanced},
   117  		{"vx", &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  }
   154  

View as plain text