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 : * cpuid.c
9 : * This module provides a simple abstraction for using the CPUID
10 : * instruction to determine instruction set extensions supported by
11 : * the current processor.
12 : */
13 : #ifndef NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_
14 : #define NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_
15 :
16 : #include "native_client/src/include/portability.h"
17 :
18 : /* The list of features we can get from the CPUID instruction.
19 : * Do not modify this enum without making similar modifications to
20 : * CPUFeatureDescriptions in nacl_cpuid.c.
21 : */
22 : typedef enum {
23 : NaClCPUFeature_x87 = 0,
24 : NaClCPUFeature_MMX,
25 : NaClCPUFeature_SSE,
26 : NaClCPUFeature_SSE2,
27 : NaClCPUFeature_SSE3,
28 : NaClCPUFeature_SSSE3,
29 : NaClCPUFeature_SSE41,
30 : NaClCPUFeature_SSE42,
31 : NaClCPUFeature_MOVBE,
32 : NaClCPUFeature_POPCNT,
33 : NaClCPUFeature_CX8,
34 : NaClCPUFeature_CX16,
35 : NaClCPUFeature_CMOV,
36 : NaClCPUFeature_MON,
37 : NaClCPUFeature_FXSR,
38 : NaClCPUFeature_CLFLUSH,
39 : NaClCPUFeature_MSR,
40 : NaClCPUFeature_TSC,
41 : NaClCPUFeature_VME,
42 : NaClCPUFeature_PSN,
43 : NaClCPUFeature_VMX,
44 : NaClCPUFeature_OSXSAVE,
45 : NaClCPUFeature_AVX,
46 : NaClCPUFeature_3DNOW, /* AMD-specific */
47 : NaClCPUFeature_EMMX, /* AMD-specific */
48 : NaClCPUFeature_E3DNOW, /* AMD-specific */
49 : NaClCPUFeature_LZCNT, /* AMD-specific */
50 : NaClCPUFeature_SSE4A, /* AMD-specific */
51 : NaClCPUFeature_LM,
52 : NaClCPUFeature_SVM, /* AMD-specific */
53 : NaClCPUFeature_Max
54 : } NaClCPUFeatureID;
55 :
56 : /* Features needed to show that the architecture is supported. */
57 : typedef struct nacl_arch_features {
58 : char f_cpuid_supported; /* CPUID is defined for the hardward. */
59 : char f_cpu_supported; /* CPU is one we support. */
60 : } nacl_arch_features;
61 :
62 : /* Features we can get about the x86 hardware. */
63 : typedef struct cpu_feature_struct {
64 : nacl_arch_features arch_features;
65 : char data[NaClCPUFeature_Max];
66 : } NaClCPUFeaturesX86;
67 :
68 : /* Define the maximum length of a CPUID string.
69 : *
70 : * Note: If you change this length, fix the static initialization of wlid
71 : * in nacl_cpuid.c to be initialized with an appropriate string.
72 : */
73 : #define /* static const int */ kCPUIDStringLength 21
74 :
75 : /* Defines the maximum number of feature registers used to hold CPUID.
76 : * Note: This value corresponds to the number of enumerated elements in
77 : * enum CPUFeatureReg defined in nacl_cpuid.c.
78 : */
79 : #define kMaxCPUFeatureReg 8
80 :
81 : /* Defines the maximum number of extended control registers.
82 : */
83 : #define kMaxCPUXCRReg 1
84 :
85 : /* Define a cache for collected CPU runtime information, from which
86 : * queries can answer questions.
87 : */
88 : typedef struct NaClCPUData {
89 : /* The following is used to cache whether CPUID is defined for the
90 : * architecture the code is running on.
91 : */
92 : int _has_CPUID;
93 : /* Version ID words used by CPUVersionID. */
94 : uint32_t _vidwords[4];
95 : /* Define the set of CPUID feature register values for the architecture.
96 : * Note: We have two sets (of 4 registers) so that AMD specific flags can be
97 : * picked up.
98 : */
99 : uint32_t _featurev[kMaxCPUFeatureReg];
100 : /* Define the set of extended control register (XCR) values.
101 : */
102 : uint64_t _xcrv[kMaxCPUXCRReg];
103 : /* Define a string to hold and cache the CPUID. In such cases, such races
104 : * will at worst cause the CPUID to not be recognized.
105 : */
106 : char _wlid[kCPUIDStringLength];
107 : } NaClCPUData;
108 :
109 : /* Collect CPU data about this CPU, and put into the given data structure.
110 : */
111 : void NaClCPUDataGet(NaClCPUData* data);
112 :
113 : /* GetCPUIDString creates an ASCII string that identifies this CPU's
114 : * vendor ID, family, model, and stepping, as per the CPUID instruction
115 : */
116 : char *GetCPUIDString(NaClCPUData* data);
117 :
118 : /* Set cpu check state fields to all true. */
119 : void NaClSetAllCPUFeatures(NaClCPUFeaturesX86 *features);
120 :
121 : /* Clear cpu check state fields (i.e. set all fields to false). */
122 : void NaClClearCPUFeatures(NaClCPUFeaturesX86 *features);
123 :
124 : /* Set a feature. */
125 : void NaClSetCPUFeature(NaClCPUFeaturesX86 *features, NaClCPUFeatureID id,
126 : int state);
127 :
128 : /* Query whether a feature is supported. */
129 : static INLINE int NaClGetCPUFeature(NaClCPUFeaturesX86 *features,
130 5122 : NaClCPUFeatureID id) {
131 5122 : return features->data[id];
132 : }
133 :
134 : /* Get a short, printable name for the feature. */
135 : const char* NaClGetCPUFeatureName(NaClCPUFeatureID id);
136 :
137 : /* Copy a set of cpu features. */
138 : void NaClCopyCPUFeatures(NaClCPUFeaturesX86* target,
139 : const NaClCPUFeaturesX86* source);
140 :
141 : /* Get the features for the CPU this code is running on. */
142 : void NaClGetCurrentCPUFeatures(NaClCPUFeaturesX86 *cpu_features);
143 :
144 : /* Returns true if CPUID is defined, and the CPU is supported. */
145 : int NaClArchSupported(NaClCPUFeaturesX86 *features);
146 :
147 : #endif /* NATIVE_CLIENT_SRC_TRUSTED_VALIDATOR_X86_NACL_CPUID_H_ */
|