OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | |
3 * Use of this source code is governed by a BSD-style license that can be | |
4 * found in the LICENSE file. | |
5 */ | |
6 | |
7 /* | |
8 * This module provides a simple abstraction for using the CPUID | |
9 * instruction to determine instruction set extensions supported by | |
10 * the current processor. | |
11 */ | |
12 #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_ | |
13 #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_ | |
14 | |
15 #include "native_client/src/include/portability.h" | |
16 #include "native_client/src/trusted/validator/ncvalidate.h" | |
17 | |
18 | |
19 EXTERN_C_BEGIN | |
20 | |
21 /* The list of features we can get from the CPUID instruction. | |
22 * Do not modify this enum without making similar modifications to | |
23 * CPUFeatureDescriptions in nacl_cpuid.c. | |
24 */ | |
25 typedef enum { | |
26 NaClCPUFeatureX86_CPUIDSupported, | |
27 NaClCPUFeatureX86_CPUSupported, /* CPU is one we support. */ | |
28 NaClCPUFeatureX86_3DNOW, /* AMD-specific */ | |
29 NaClCPUFeatureX86_AES, | |
30 NaClCPUFeatureX86_AVX, | |
31 NaClCPUFeatureX86_BMI1, | |
32 NaClCPUFeatureX86_CLFLUSH, | |
33 NaClCPUFeatureX86_CLMUL, | |
34 NaClCPUFeatureX86_CMOV, | |
35 NaClCPUFeatureX86_CX16, | |
36 NaClCPUFeatureX86_CX8, | |
37 NaClCPUFeatureX86_E3DNOW, /* AMD-specific */ | |
38 NaClCPUFeatureX86_EMMX, /* AMD-specific */ | |
39 NaClCPUFeatureX86_F16C, | |
40 NaClCPUFeatureX86_FMA, | |
41 NaClCPUFeatureX86_FMA4, /* AMD-specific */ | |
42 NaClCPUFeatureX86_FXSR, | |
43 NaClCPUFeatureX86_LAHF, | |
44 NaClCPUFeatureX86_LM, | |
45 NaClCPUFeatureX86_LWP, /* AMD-specific */ | |
46 NaClCPUFeatureX86_LZCNT, /* AMD-specific */ | |
47 NaClCPUFeatureX86_MMX, | |
48 NaClCPUFeatureX86_MON, | |
49 NaClCPUFeatureX86_MOVBE, | |
50 NaClCPUFeatureX86_OSXSAVE, | |
51 NaClCPUFeatureX86_POPCNT, | |
52 NaClCPUFeatureX86_PRE, /* AMD-specific */ | |
53 NaClCPUFeatureX86_SSE, | |
54 NaClCPUFeatureX86_SSE2, | |
55 NaClCPUFeatureX86_SSE3, | |
56 NaClCPUFeatureX86_SSE41, | |
57 NaClCPUFeatureX86_SSE42, | |
58 NaClCPUFeatureX86_SSE4A, /* AMD-specific */ | |
59 NaClCPUFeatureX86_SSSE3, | |
60 NaClCPUFeatureX86_TBM, /* AMD-specific */ | |
61 NaClCPUFeatureX86_TSC, | |
62 NaClCPUFeatureX86_x87, | |
63 NaClCPUFeatureX86_XOP, /* AMD-specific */ | |
64 NaClCPUFeatureX86_Max | |
65 } NaClCPUFeatureX86ID; | |
66 | |
67 /* Features we can get about the x86 hardware. */ | |
68 typedef struct cpu_feature_struct_X86 { | |
69 char data[NaClCPUFeatureX86_Max]; | |
70 } NaClCPUFeaturesX86; | |
71 | |
72 /* Define the maximum length of a CPUID string. | |
73 * | |
74 * Note: If you change this length, fix the static initialization of wlid | |
75 * in nacl_cpuid.c to be initialized with an appropriate string. | |
76 */ | |
77 #define /* static const int */ kCPUIDStringLength 21 | |
78 | |
79 /* Defines the maximum number of feature registers used to hold CPUID. | |
80 * Note: This value corresponds to the number of enumerated elements in | |
81 * enum CPUFeatureReg defined in nacl_cpuid.c. | |
82 */ | |
83 #define kMaxCPUFeatureReg 12 | |
84 | |
85 /* Defines the maximum number of extended control registers. | |
86 */ | |
87 #define kMaxCPUXCRReg 1 | |
88 | |
89 /* Define a cache for collected CPU runtime information, from which | |
90 * queries can answer questions. | |
91 */ | |
92 typedef struct NaClCPUData { | |
93 /* The following is used to cache whether CPUID is defined for the | |
94 * architecture the code is running on. | |
95 */ | |
96 int _has_CPUID; | |
97 /* Version ID words used by CPUVersionID. */ | |
98 uint32_t _vidwords[4]; | |
99 /* Define the set of CPUID feature register values for the architecture. | |
100 * Note: We have two sets (of 4 registers) so that AMD specific flags can be | |
101 * picked up. | |
102 */ | |
103 uint32_t _featurev[kMaxCPUFeatureReg]; | |
104 /* Define the set of extended control register (XCR) values. | |
105 */ | |
106 uint64_t _xcrv[kMaxCPUXCRReg]; | |
107 /* Define a string to hold and cache the CPUID. In such cases, such races | |
108 * will at worst cause the CPUID to not be recognized. | |
109 */ | |
110 char _wlid[kCPUIDStringLength]; | |
111 } NaClCPUData; | |
112 | |
113 /* Collect CPU data about this CPU, and put into the given data structure. | |
114 */ | |
115 void NaClCPUDataGet(NaClCPUData* data); | |
116 | |
117 /* GetCPUIDString creates an ASCII string that identifies this CPU's | |
118 * vendor ID, family, model, and stepping, as per the CPUID instruction | |
119 */ | |
120 char *GetCPUIDString(NaClCPUData* data); | |
121 | |
122 /* | |
123 * Platform-independent NaClValidatorInterface functions. | |
124 */ | |
125 void NaClSetAllCPUFeaturesX86(NaClCPUFeatures *features); | |
126 void NaClGetCurrentCPUFeaturesX86(NaClCPUFeatures *cpu_features); | |
127 int NaClFixCPUFeaturesX86(NaClCPUFeatures *cpu_features); | |
128 | |
129 /* | |
130 * Platform-dependent getter/setter. | |
131 */ | |
132 static INLINE int NaClGetCPUFeatureX86(const NaClCPUFeaturesX86 *features, | |
133 NaClCPUFeatureX86ID id) { | |
134 return features->data[id]; | |
135 } | |
136 | |
137 void NaClSetCPUFeatureX86(NaClCPUFeaturesX86 *features, NaClCPUFeatureX86ID id, | |
138 int state); | |
139 const char *NaClGetCPUFeatureX86Name(NaClCPUFeatureX86ID id); | |
140 | |
141 /* | |
142 * Platform-independent functions which are only used in platform-dependent | |
143 * code. | |
144 * TODO(jfb) The ARM and MIPS CPU feature do not offer NaClCopyCPUFeaturesX86 | |
145 * and NaClArchSupportedX86, should they be removed? | |
146 */ | |
147 void NaClClearCPUFeaturesX86(NaClCPUFeaturesX86 *features); | |
148 void NaClCopyCPUFeaturesX86(NaClCPUFeaturesX86 *target, | |
149 const NaClCPUFeaturesX86 *source); | |
150 int NaClArchSupportedX86(const NaClCPUFeaturesX86 *features); | |
151 | |
152 EXTERN_C_END | |
153 | |
154 #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_ */ | |
OLD | NEW |