cpu_linux_s390x.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. package cpu
  5. const cacheLineSize = 256
  6. const (
  7. // bit mask values from /usr/include/bits/hwcap.h
  8. hwcap_ZARCH = 2
  9. hwcap_STFLE = 4
  10. hwcap_MSA = 8
  11. hwcap_LDISP = 16
  12. hwcap_EIMM = 32
  13. hwcap_DFP = 64
  14. hwcap_ETF3EH = 256
  15. hwcap_VX = 2048
  16. hwcap_VXE = 8192
  17. )
  18. // bitIsSet reports whether the bit at index is set. The bit index
  19. // is in big endian order, so bit index 0 is the leftmost bit.
  20. func bitIsSet(bits []uint64, index uint) bool {
  21. return bits[index/64]&((1<<63)>>(index%64)) != 0
  22. }
  23. // function is the code for the named cryptographic function.
  24. type function uint8
  25. const (
  26. // KM{,A,C,CTR} function codes
  27. aes128 function = 18 // AES-128
  28. aes192 function = 19 // AES-192
  29. aes256 function = 20 // AES-256
  30. // K{I,L}MD function codes
  31. sha1 function = 1 // SHA-1
  32. sha256 function = 2 // SHA-256
  33. sha512 function = 3 // SHA-512
  34. sha3_224 function = 32 // SHA3-224
  35. sha3_256 function = 33 // SHA3-256
  36. sha3_384 function = 34 // SHA3-384
  37. sha3_512 function = 35 // SHA3-512
  38. shake128 function = 36 // SHAKE-128
  39. shake256 function = 37 // SHAKE-256
  40. // KLMD function codes
  41. ghash function = 65 // GHASH
  42. )
  43. // queryResult contains the result of a Query function
  44. // call. Bits are numbered in big endian order so the
  45. // leftmost bit (the MSB) is at index 0.
  46. type queryResult struct {
  47. bits [2]uint64
  48. }
  49. // Has reports whether the given functions are present.
  50. func (q *queryResult) Has(fns ...function) bool {
  51. if len(fns) == 0 {
  52. panic("no function codes provided")
  53. }
  54. for _, f := range fns {
  55. if !bitIsSet(q.bits[:], uint(f)) {
  56. return false
  57. }
  58. }
  59. return true
  60. }
  61. // facility is a bit index for the named facility.
  62. type facility uint8
  63. const (
  64. // cryptography facilities
  65. msa4 facility = 77 // message-security-assist extension 4
  66. msa8 facility = 146 // message-security-assist extension 8
  67. )
  68. // facilityList contains the result of an STFLE call.
  69. // Bits are numbered in big endian order so the
  70. // leftmost bit (the MSB) is at index 0.
  71. type facilityList struct {
  72. bits [4]uint64
  73. }
  74. // Has reports whether the given facilities are present.
  75. func (s *facilityList) Has(fs ...facility) bool {
  76. if len(fs) == 0 {
  77. panic("no facility bits provided")
  78. }
  79. for _, f := range fs {
  80. if !bitIsSet(s.bits[:], uint(f)) {
  81. return false
  82. }
  83. }
  84. return true
  85. }
  86. func doinit() {
  87. // test HWCAP bit vector
  88. has := func(featureMask uint) bool {
  89. return hwCap&featureMask == featureMask
  90. }
  91. // mandatory
  92. S390X.HasZARCH = has(hwcap_ZARCH)
  93. // optional
  94. S390X.HasSTFLE = has(hwcap_STFLE)
  95. S390X.HasLDISP = has(hwcap_LDISP)
  96. S390X.HasEIMM = has(hwcap_EIMM)
  97. S390X.HasETF3EH = has(hwcap_ETF3EH)
  98. S390X.HasDFP = has(hwcap_DFP)
  99. S390X.HasMSA = has(hwcap_MSA)
  100. S390X.HasVX = has(hwcap_VX)
  101. if S390X.HasVX {
  102. S390X.HasVXE = has(hwcap_VXE)
  103. }
  104. // We need implementations of stfle, km and so on
  105. // to detect cryptographic features.
  106. if !haveAsmFunctions() {
  107. return
  108. }
  109. // optional cryptographic functions
  110. if S390X.HasMSA {
  111. aes := []function{aes128, aes192, aes256}
  112. // cipher message
  113. km, kmc := kmQuery(), kmcQuery()
  114. S390X.HasAES = km.Has(aes...)
  115. S390X.HasAESCBC = kmc.Has(aes...)
  116. if S390X.HasSTFLE {
  117. facilities := stfle()
  118. if facilities.Has(msa4) {
  119. kmctr := kmctrQuery()
  120. S390X.HasAESCTR = kmctr.Has(aes...)
  121. }
  122. if facilities.Has(msa8) {
  123. kma := kmaQuery()
  124. S390X.HasAESGCM = kma.Has(aes...)
  125. }
  126. }
  127. // compute message digest
  128. kimd := kimdQuery() // intermediate (no padding)
  129. klmd := klmdQuery() // last (padding)
  130. S390X.HasSHA1 = kimd.Has(sha1) && klmd.Has(sha1)
  131. S390X.HasSHA256 = kimd.Has(sha256) && klmd.Has(sha256)
  132. S390X.HasSHA512 = kimd.Has(sha512) && klmd.Has(sha512)
  133. S390X.HasGHASH = kimd.Has(ghash) // KLMD-GHASH does not exist
  134. sha3 := []function{
  135. sha3_224, sha3_256, sha3_384, sha3_512,
  136. shake128, shake256,
  137. }
  138. S390X.HasSHA3 = kimd.Has(sha3...) && klmd.Has(sha3...)
  139. }
  140. }