...

Source file src/pkg/vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go

     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	}
   162	

View as plain text