cpu_features.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. /*
  2. * Copyright (C) 2011-2018 Intel Corporation. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in
  12. * the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Intel Corporation nor the names of its
  15. * contributors may be used to endorse or promote products derived
  16. * from this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. *
  30. */
  31. #include "se_cpu_feature_defs.h"
  32. #include "se_types.h"
  33. #include "cpu_features.h"
  34. // Initialize cpuid leaves for FIPS capable OpenSSL
  35. //-------------------------------------------------
  36. extern void init_cpuinfo(uint32_t *cpuinfo_table)
  37. {
  38. // Leaf 0
  39. sgx_cpuid(0,
  40. cpuinfo_table,
  41. cpuinfo_table + 1,
  42. cpuinfo_table + 2,
  43. cpuinfo_table + 3);
  44. // Leaf 1
  45. sgx_cpuid(1,
  46. cpuinfo_table + 4,
  47. cpuinfo_table + 4 + 1,
  48. cpuinfo_table + 4 + 2,
  49. cpuinfo_table + 4 + 3);
  50. // Leaf 4
  51. sgx_cpuid(4,
  52. cpuinfo_table + 4*4,
  53. cpuinfo_table + 4*4 + 1,
  54. cpuinfo_table + 4*4 + 2,
  55. cpuinfo_table + 4*4 + 3);
  56. // Leaf 7
  57. sgx_cpuid(7,
  58. cpuinfo_table + 4*7,
  59. cpuinfo_table + 4*7 + 1,
  60. cpuinfo_table + 4*7 + 2,
  61. cpuinfo_table + 4*7 + 3);
  62. return;
  63. }
  64. void get_cpu_features(uint64_t *__intel_cpu_feature_indicator, uint32_t *cpuinfo_table)
  65. {
  66. unsigned int cpuid0_eax, cpuid0_ebx, cpuid0_ecx, cpuid0_edx;
  67. unsigned int cpuid1_eax, cpuid1_ebx, cpuid1_ecx, cpuid1_edx;
  68. unsigned int cpuid7_eax, cpuid7_ebx, cpuid7_ecx, cpuid7_edx;
  69. unsigned int ecpuid1_eax, ecpuid1_ebx, ecpuid1_ecx, ecpuid1_edx;
  70. uint64_t cpu_feature_indicator = CPU_FEATURE_GENERIC_IA32;
  71. sgx_cpuid(0, &cpuid0_eax, &cpuid0_ebx, &cpuid0_ecx, &cpuid0_edx);
  72. if(cpuid0_eax == 0 ||
  73. !(cpuid0_ebx == CPU_GENU_VAL &&
  74. cpuid0_edx == CPU_INEI_VAL &&
  75. cpuid0_ecx == CPU_NTEL_VAL))
  76. {
  77. *__intel_cpu_feature_indicator = cpu_feature_indicator;
  78. // sgxssl cpuid initiation
  79. init_cpuinfo(cpuinfo_table);
  80. return;
  81. }
  82. sgx_cpuid(1, &cpuid1_eax, &cpuid1_ebx, &cpuid1_ecx, &cpuid1_edx);
  83. if (CPU_MODEL(cpuid1_eax) == CPU_ATOM1 ||
  84. CPU_MODEL(cpuid1_eax) == CPU_ATOM2 ||
  85. CPU_MODEL(cpuid1_eax) == CPU_ATOM3) {
  86. cpu_feature_indicator |= CPU_FEATURE_FULL_INORDER;
  87. }
  88. // Walk through supported features
  89. if (CPU_HAS_FPU(cpuid1_edx)) {
  90. cpu_feature_indicator |= CPU_FEATURE_FPU;
  91. }
  92. if (CPU_HAS_CMOV(cpuid1_edx)) {
  93. cpu_feature_indicator |= CPU_FEATURE_CMOV;
  94. }
  95. if (CPU_HAS_MMX(cpuid1_edx)) {
  96. cpu_feature_indicator |= CPU_FEATURE_MMX;
  97. }
  98. if (CPU_HAS_FXSAVE(cpuid1_edx)) {
  99. cpu_feature_indicator |= CPU_FEATURE_FXSAVE;
  100. if (CPU_HAS_SSE(cpuid1_edx)) {
  101. cpu_feature_indicator |= CPU_FEATURE_SSE;
  102. }
  103. if (CPU_HAS_SSE2(cpuid1_edx)) {
  104. cpu_feature_indicator |= CPU_FEATURE_SSE2;
  105. }
  106. if (CPU_HAS_SSE3(cpuid1_ecx)) {
  107. cpu_feature_indicator |= CPU_FEATURE_SSE3;
  108. }
  109. if (CPU_HAS_SSSE3(cpuid1_ecx)) {
  110. cpu_feature_indicator |= CPU_FEATURE_SSSE3;
  111. }
  112. if (CPU_HAS_MOVBE(cpuid1_ecx)) {
  113. cpu_feature_indicator |= CPU_FEATURE_MOVBE;
  114. }
  115. //
  116. // Penryn is a P6 with SNI support.
  117. //
  118. if (CPU_HAS_SSE4_1(cpuid1_ecx)) {
  119. cpu_feature_indicator |= CPU_FEATURE_SSE4_1;
  120. }
  121. if (CPU_HAS_SSE4_2(cpuid1_ecx)) {
  122. cpu_feature_indicator |= CPU_FEATURE_SSE4_2;
  123. }
  124. if (CPU_HAS_POPCNT(cpuid1_ecx)) {
  125. cpu_feature_indicator |= CPU_FEATURE_POPCNT;
  126. }
  127. if (CPU_HAS_PCLMULQDQ(cpuid1_ecx)) {
  128. cpu_feature_indicator |= CPU_FEATURE_PCLMULQDQ;
  129. }
  130. if (CPU_HAS_AES(cpuid1_ecx)) {
  131. cpu_feature_indicator |= CPU_FEATURE_AES;
  132. }
  133. }
  134. // IvyBridge
  135. if (CPU_HAS_RDRAND(cpuid1_ecx)) {
  136. cpu_feature_indicator |= CPU_FEATURE_RDRND;
  137. }
  138. sgx_cpuidex(7, 0, &cpuid7_eax, &cpuid7_ebx, &cpuid7_ecx, &cpuid7_edx);
  139. sgx_cpuid(0x80000001, &ecpuid1_eax, &ecpuid1_ebx, &ecpuid1_ecx, &ecpuid1_edx);
  140. // Haswell
  141. // BMI checks for both ebx[3] and ebx[8] (VEX-encoded instructions)
  142. if (CPU_HAS_BMI(cpuid7_ebx)) {
  143. cpu_feature_indicator |= CPU_FEATURE_BMI;
  144. }
  145. if (CPU_HAS_LZCNT(ecpuid1_ecx)) {
  146. cpu_feature_indicator |= CPU_FEATURE_LZCNT;
  147. }
  148. if (CPU_HAS_PREFETCHW(ecpuid1_ecx)) {
  149. cpu_feature_indicator |= CPU_FEATURE_PREFETCHW;
  150. }
  151. if (CPU_HAS_HLE(cpuid7_ebx)) {
  152. cpu_feature_indicator |= CPU_FEATURE_HLE;
  153. }
  154. if (CPU_HAS_RTM(cpuid7_ebx)) {
  155. cpu_feature_indicator |= CPU_FEATURE_RTM;
  156. }
  157. if (CPU_HAS_RDSEED(cpuid7_ebx)) {
  158. cpu_feature_indicator |= CPU_FEATURE_RDSEED;
  159. }
  160. if (CPU_HAS_ADCOX(cpuid7_ebx)) {
  161. cpu_feature_indicator |= CPU_FEATURE_ADCOX;
  162. }
  163. if (CPU_HAS_XSAVE(cpuid1_ecx))
  164. {
  165. //don't get xcr0_features, tRTS will do it.
  166. if (CPU_HAS_AVX(cpuid1_ecx)) {
  167. cpu_feature_indicator |= CPU_FEATURE_AVX;
  168. }
  169. // IvyBridge
  170. if (CPU_HAS_F16C(cpuid1_ecx)) {
  171. cpu_feature_indicator |= CPU_FEATURE_F16C;
  172. }
  173. // Haswell
  174. if (CPU_HAS_AVX2(cpuid7_ebx)) {
  175. cpu_feature_indicator |= CPU_FEATURE_AVX2;
  176. }
  177. if (CPU_HAS_FMA(cpuid1_ecx)) {
  178. cpu_feature_indicator |= CPU_FEATURE_FMA;
  179. }
  180. }
  181. *__intel_cpu_feature_indicator = cpu_feature_indicator;
  182. // sgxssl cpuid initiation
  183. init_cpuinfo(cpuinfo_table);
  184. }