1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker
5*6777b538SAndroid Build Coastguard Worker #include "base/cpu.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
8*6777b538SAndroid Build Coastguard Worker #include <string.h>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/protected_memory.h"
15*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARM_FAMILY) && \
18*6777b538SAndroid Build Coastguard Worker (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
19*6777b538SAndroid Build Coastguard Worker #include <asm/hwcap.h>
20*6777b538SAndroid Build Coastguard Worker #include <sys/auxv.h>
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/numerics/checked_math.h"
24*6777b538SAndroid Build Coastguard Worker #include "base/ranges/algorithm.h"
25*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_number_conversions.h"
26*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_split.h"
27*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
28*6777b538SAndroid Build Coastguard Worker
29*6777b538SAndroid Build Coastguard Worker // Temporary definitions until a new hwcap.h is pulled in everywhere.
30*6777b538SAndroid Build Coastguard Worker // https://crbug.com/1265965
31*6777b538SAndroid Build Coastguard Worker #ifndef HWCAP2_MTE
32*6777b538SAndroid Build Coastguard Worker #define HWCAP2_MTE (1 << 18)
33*6777b538SAndroid Build Coastguard Worker #define HWCAP2_BTI (1 << 17)
34*6777b538SAndroid Build Coastguard Worker #endif
35*6777b538SAndroid Build Coastguard Worker
36*6777b538SAndroid Build Coastguard Worker struct ProcCpuInfo {
37*6777b538SAndroid Build Coastguard Worker std::string brand;
38*6777b538SAndroid Build Coastguard Worker uint8_t implementer = 0;
39*6777b538SAndroid Build Coastguard Worker uint32_t part_number = 0;
40*6777b538SAndroid Build Coastguard Worker };
41*6777b538SAndroid Build Coastguard Worker #endif
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
44*6777b538SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
45*6777b538SAndroid Build Coastguard Worker #include <intrin.h>
46*6777b538SAndroid Build Coastguard Worker #include <immintrin.h> // For _xgetbv()
47*6777b538SAndroid Build Coastguard Worker #endif
48*6777b538SAndroid Build Coastguard Worker #endif
49*6777b538SAndroid Build Coastguard Worker
50*6777b538SAndroid Build Coastguard Worker namespace base {
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
53*6777b538SAndroid Build Coastguard Worker namespace internal {
54*6777b538SAndroid Build Coastguard Worker
ComputeX86FamilyAndModel(const std::string & vendor,int signature)55*6777b538SAndroid Build Coastguard Worker X86ModelInfo ComputeX86FamilyAndModel(const std::string& vendor,
56*6777b538SAndroid Build Coastguard Worker int signature) {
57*6777b538SAndroid Build Coastguard Worker X86ModelInfo results;
58*6777b538SAndroid Build Coastguard Worker results.family = (signature >> 8) & 0xf;
59*6777b538SAndroid Build Coastguard Worker results.model = (signature >> 4) & 0xf;
60*6777b538SAndroid Build Coastguard Worker results.ext_family = 0;
61*6777b538SAndroid Build Coastguard Worker results.ext_model = 0;
62*6777b538SAndroid Build Coastguard Worker
63*6777b538SAndroid Build Coastguard Worker // The "Intel 64 and IA-32 Architectures Developer's Manual: Vol. 2A"
64*6777b538SAndroid Build Coastguard Worker // specifies the Extended Model is defined only when the Base Family is
65*6777b538SAndroid Build Coastguard Worker // 06h or 0Fh.
66*6777b538SAndroid Build Coastguard Worker // The "AMD CPUID Specification" specifies that the Extended Model is
67*6777b538SAndroid Build Coastguard Worker // defined only when Base Family is 0Fh.
68*6777b538SAndroid Build Coastguard Worker // Both manuals define the display model as
69*6777b538SAndroid Build Coastguard Worker // {ExtendedModel[3:0],BaseModel[3:0]} in that case.
70*6777b538SAndroid Build Coastguard Worker if (results.family == 0xf ||
71*6777b538SAndroid Build Coastguard Worker (results.family == 0x6 && vendor == "GenuineIntel")) {
72*6777b538SAndroid Build Coastguard Worker results.ext_model = (signature >> 16) & 0xf;
73*6777b538SAndroid Build Coastguard Worker results.model += results.ext_model << 4;
74*6777b538SAndroid Build Coastguard Worker }
75*6777b538SAndroid Build Coastguard Worker // Both the "Intel 64 and IA-32 Architectures Developer's Manual: Vol. 2A"
76*6777b538SAndroid Build Coastguard Worker // and the "AMD CPUID Specification" specify that the Extended Family is
77*6777b538SAndroid Build Coastguard Worker // defined only when the Base Family is 0Fh.
78*6777b538SAndroid Build Coastguard Worker // Both manuals define the display family as {0000b,BaseFamily[3:0]} +
79*6777b538SAndroid Build Coastguard Worker // ExtendedFamily[7:0] in that case.
80*6777b538SAndroid Build Coastguard Worker if (results.family == 0xf) {
81*6777b538SAndroid Build Coastguard Worker results.ext_family = (signature >> 20) & 0xff;
82*6777b538SAndroid Build Coastguard Worker results.family += results.ext_family;
83*6777b538SAndroid Build Coastguard Worker }
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker return results;
86*6777b538SAndroid Build Coastguard Worker }
87*6777b538SAndroid Build Coastguard Worker
88*6777b538SAndroid Build Coastguard Worker } // namespace internal
89*6777b538SAndroid Build Coastguard Worker #endif // defined(ARCH_CPU_X86_FAMILY)
90*6777b538SAndroid Build Coastguard Worker
CPU(bool require_branding)91*6777b538SAndroid Build Coastguard Worker CPU::CPU(bool require_branding) {
92*6777b538SAndroid Build Coastguard Worker Initialize(require_branding);
93*6777b538SAndroid Build Coastguard Worker }
CPU()94*6777b538SAndroid Build Coastguard Worker CPU::CPU() : CPU(true) {}
95*6777b538SAndroid Build Coastguard Worker CPU::CPU(CPU&&) = default;
96*6777b538SAndroid Build Coastguard Worker
97*6777b538SAndroid Build Coastguard Worker namespace {
98*6777b538SAndroid Build Coastguard Worker
99*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
100*6777b538SAndroid Build Coastguard Worker #if !defined(COMPILER_MSVC)
101*6777b538SAndroid Build Coastguard Worker
102*6777b538SAndroid Build Coastguard Worker #if defined(__pic__) && defined(__i386__)
103*6777b538SAndroid Build Coastguard Worker
__cpuid(int cpu_info[4],int info_type)104*6777b538SAndroid Build Coastguard Worker void __cpuid(int cpu_info[4], int info_type) {
105*6777b538SAndroid Build Coastguard Worker __asm__ volatile(
106*6777b538SAndroid Build Coastguard Worker "mov %%ebx, %%edi\n"
107*6777b538SAndroid Build Coastguard Worker "cpuid\n"
108*6777b538SAndroid Build Coastguard Worker "xchg %%edi, %%ebx\n"
109*6777b538SAndroid Build Coastguard Worker : "=a"(cpu_info[0]), "=D"(cpu_info[1]), "=c"(cpu_info[2]),
110*6777b538SAndroid Build Coastguard Worker "=d"(cpu_info[3])
111*6777b538SAndroid Build Coastguard Worker : "a"(info_type), "c"(0));
112*6777b538SAndroid Build Coastguard Worker }
113*6777b538SAndroid Build Coastguard Worker
114*6777b538SAndroid Build Coastguard Worker #else
115*6777b538SAndroid Build Coastguard Worker
116*6777b538SAndroid Build Coastguard Worker void __cpuid(int cpu_info[4], int info_type) {
117*6777b538SAndroid Build Coastguard Worker __asm__ volatile("cpuid\n"
118*6777b538SAndroid Build Coastguard Worker : "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]),
119*6777b538SAndroid Build Coastguard Worker "=d"(cpu_info[3])
120*6777b538SAndroid Build Coastguard Worker : "a"(info_type), "c"(0));
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker
123*6777b538SAndroid Build Coastguard Worker #endif
124*6777b538SAndroid Build Coastguard Worker #endif // !defined(COMPILER_MSVC)
125*6777b538SAndroid Build Coastguard Worker
126*6777b538SAndroid Build Coastguard Worker // xgetbv returns the value of an Intel Extended Control Register (XCR).
127*6777b538SAndroid Build Coastguard Worker // Currently only XCR0 is defined by Intel so |xcr| should always be zero.
xgetbv(uint32_t xcr)128*6777b538SAndroid Build Coastguard Worker uint64_t xgetbv(uint32_t xcr) {
129*6777b538SAndroid Build Coastguard Worker #if defined(COMPILER_MSVC)
130*6777b538SAndroid Build Coastguard Worker return _xgetbv(xcr);
131*6777b538SAndroid Build Coastguard Worker #else
132*6777b538SAndroid Build Coastguard Worker uint32_t eax, edx;
133*6777b538SAndroid Build Coastguard Worker
134*6777b538SAndroid Build Coastguard Worker __asm__ volatile (
135*6777b538SAndroid Build Coastguard Worker "xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr));
136*6777b538SAndroid Build Coastguard Worker return (static_cast<uint64_t>(edx) << 32) | eax;
137*6777b538SAndroid Build Coastguard Worker #endif // defined(COMPILER_MSVC)
138*6777b538SAndroid Build Coastguard Worker }
139*6777b538SAndroid Build Coastguard Worker
140*6777b538SAndroid Build Coastguard Worker #endif // ARCH_CPU_X86_FAMILY
141*6777b538SAndroid Build Coastguard Worker
142*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARM_FAMILY) && \
143*6777b538SAndroid Build Coastguard Worker (BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
FindFirstProcCpuKey(const StringPairs & pairs,std::string_view key)144*6777b538SAndroid Build Coastguard Worker StringPairs::const_iterator FindFirstProcCpuKey(const StringPairs& pairs,
145*6777b538SAndroid Build Coastguard Worker std::string_view key) {
146*6777b538SAndroid Build Coastguard Worker return ranges::find_if(pairs, [key](const StringPairs::value_type& pair) {
147*6777b538SAndroid Build Coastguard Worker return TrimWhitespaceASCII(pair.first, base::TRIM_ALL) == key;
148*6777b538SAndroid Build Coastguard Worker });
149*6777b538SAndroid Build Coastguard Worker }
150*6777b538SAndroid Build Coastguard Worker
151*6777b538SAndroid Build Coastguard Worker // Parses information about the ARM processor. Note that depending on the CPU
152*6777b538SAndroid Build Coastguard Worker // package, processor configuration, and/or kernel version, this may only
153*6777b538SAndroid Build Coastguard Worker // report information about the processor on which this thread is running. This
154*6777b538SAndroid Build Coastguard Worker // can happen on heterogeneous-processor SoCs like Snapdragon 808, which has 4
155*6777b538SAndroid Build Coastguard Worker // Cortex-A53 and 2 Cortex-A57. Unfortunately there is not a universally
156*6777b538SAndroid Build Coastguard Worker // reliable way to examine the CPU part information for all cores.
ParseProcCpu()157*6777b538SAndroid Build Coastguard Worker const ProcCpuInfo& ParseProcCpu() {
158*6777b538SAndroid Build Coastguard Worker static const NoDestructor<ProcCpuInfo> info([]() {
159*6777b538SAndroid Build Coastguard Worker // This function finds the value from /proc/cpuinfo under the key "model
160*6777b538SAndroid Build Coastguard Worker // name" or "Processor". "model name" is used in Linux 3.8 and later (3.7
161*6777b538SAndroid Build Coastguard Worker // and later for arm64) and is shown once per CPU. "Processor" is used in
162*6777b538SAndroid Build Coastguard Worker // earler versions and is shown only once at the top of /proc/cpuinfo
163*6777b538SAndroid Build Coastguard Worker // regardless of the number CPUs.
164*6777b538SAndroid Build Coastguard Worker const char kModelNamePrefix[] = "model name";
165*6777b538SAndroid Build Coastguard Worker const char kProcessorPrefix[] = "Processor";
166*6777b538SAndroid Build Coastguard Worker
167*6777b538SAndroid Build Coastguard Worker std::string cpuinfo;
168*6777b538SAndroid Build Coastguard Worker ReadFileToString(FilePath("/proc/cpuinfo"), &cpuinfo);
169*6777b538SAndroid Build Coastguard Worker DCHECK(!cpuinfo.empty());
170*6777b538SAndroid Build Coastguard Worker
171*6777b538SAndroid Build Coastguard Worker ProcCpuInfo info;
172*6777b538SAndroid Build Coastguard Worker
173*6777b538SAndroid Build Coastguard Worker StringPairs pairs;
174*6777b538SAndroid Build Coastguard Worker if (!SplitStringIntoKeyValuePairs(cpuinfo, ':', '\n', &pairs)) {
175*6777b538SAndroid Build Coastguard Worker NOTREACHED();
176*6777b538SAndroid Build Coastguard Worker return info;
177*6777b538SAndroid Build Coastguard Worker }
178*6777b538SAndroid Build Coastguard Worker
179*6777b538SAndroid Build Coastguard Worker auto model_name = FindFirstProcCpuKey(pairs, kModelNamePrefix);
180*6777b538SAndroid Build Coastguard Worker if (model_name == pairs.end())
181*6777b538SAndroid Build Coastguard Worker model_name = FindFirstProcCpuKey(pairs, kProcessorPrefix);
182*6777b538SAndroid Build Coastguard Worker if (model_name != pairs.end()) {
183*6777b538SAndroid Build Coastguard Worker TrimWhitespaceASCII(model_name->second, TRIM_ALL, &info.brand);
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker
186*6777b538SAndroid Build Coastguard Worker auto implementer_string = FindFirstProcCpuKey(pairs, "CPU implementer");
187*6777b538SAndroid Build Coastguard Worker if (implementer_string != pairs.end()) {
188*6777b538SAndroid Build Coastguard Worker // HexStringToUInt() handles the leading whitespace on the value.
189*6777b538SAndroid Build Coastguard Worker uint32_t implementer;
190*6777b538SAndroid Build Coastguard Worker HexStringToUInt(implementer_string->second, &implementer);
191*6777b538SAndroid Build Coastguard Worker if (!CheckedNumeric<uint32_t>(implementer)
192*6777b538SAndroid Build Coastguard Worker .AssignIfValid(&info.implementer)) {
193*6777b538SAndroid Build Coastguard Worker info.implementer = 0;
194*6777b538SAndroid Build Coastguard Worker }
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker
197*6777b538SAndroid Build Coastguard Worker auto part_number_string = FindFirstProcCpuKey(pairs, "CPU part");
198*6777b538SAndroid Build Coastguard Worker if (part_number_string != pairs.end())
199*6777b538SAndroid Build Coastguard Worker HexStringToUInt(part_number_string->second, &info.part_number);
200*6777b538SAndroid Build Coastguard Worker
201*6777b538SAndroid Build Coastguard Worker return info;
202*6777b538SAndroid Build Coastguard Worker }());
203*6777b538SAndroid Build Coastguard Worker
204*6777b538SAndroid Build Coastguard Worker return *info;
205*6777b538SAndroid Build Coastguard Worker }
206*6777b538SAndroid Build Coastguard Worker #endif // defined(ARCH_CPU_ARM_FAMILY) && (BUILDFLAG(IS_ANDROID) ||
207*6777b538SAndroid Build Coastguard Worker // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS))
208*6777b538SAndroid Build Coastguard Worker
209*6777b538SAndroid Build Coastguard Worker DEFINE_PROTECTED_DATA base::ProtectedMemory<CPU, true> g_cpu_instance;
210*6777b538SAndroid Build Coastguard Worker
211*6777b538SAndroid Build Coastguard Worker } // namespace
212*6777b538SAndroid Build Coastguard Worker
Initialize(bool require_branding)213*6777b538SAndroid Build Coastguard Worker void CPU::Initialize(bool require_branding) {
214*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
215*6777b538SAndroid Build Coastguard Worker int cpu_info[4] = {-1};
216*6777b538SAndroid Build Coastguard Worker
217*6777b538SAndroid Build Coastguard Worker // __cpuid with an InfoType argument of 0 returns the number of
218*6777b538SAndroid Build Coastguard Worker // valid Ids in CPUInfo[0] and the CPU identification string in
219*6777b538SAndroid Build Coastguard Worker // the other three array elements. The CPU identification string is
220*6777b538SAndroid Build Coastguard Worker // not in linear order. The code below arranges the information
221*6777b538SAndroid Build Coastguard Worker // in a human readable form. The human readable order is CPUInfo[1] |
222*6777b538SAndroid Build Coastguard Worker // CPUInfo[3] | CPUInfo[2]. CPUInfo[2] and CPUInfo[3] are swapped
223*6777b538SAndroid Build Coastguard Worker // before using memcpy() to copy these three array elements to |cpu_string|.
224*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info, 0);
225*6777b538SAndroid Build Coastguard Worker int num_ids = cpu_info[0];
226*6777b538SAndroid Build Coastguard Worker std::swap(cpu_info[2], cpu_info[3]);
227*6777b538SAndroid Build Coastguard Worker memcpy(cpu_vendor_, &cpu_info[1], kVendorNameSize);
228*6777b538SAndroid Build Coastguard Worker cpu_vendor_[kVendorNameSize] = '\0';
229*6777b538SAndroid Build Coastguard Worker
230*6777b538SAndroid Build Coastguard Worker // Interpret CPU feature information.
231*6777b538SAndroid Build Coastguard Worker if (num_ids > 0) {
232*6777b538SAndroid Build Coastguard Worker int cpu_info7[4] = {0};
233*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info, 1);
234*6777b538SAndroid Build Coastguard Worker if (num_ids >= 7) {
235*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info7, 7);
236*6777b538SAndroid Build Coastguard Worker }
237*6777b538SAndroid Build Coastguard Worker signature_ = cpu_info[0];
238*6777b538SAndroid Build Coastguard Worker stepping_ = cpu_info[0] & 0xf;
239*6777b538SAndroid Build Coastguard Worker type_ = (cpu_info[0] >> 12) & 0x3;
240*6777b538SAndroid Build Coastguard Worker internal::X86ModelInfo results =
241*6777b538SAndroid Build Coastguard Worker internal::ComputeX86FamilyAndModel(cpu_vendor_, signature_);
242*6777b538SAndroid Build Coastguard Worker family_ = results.family;
243*6777b538SAndroid Build Coastguard Worker model_ = results.model;
244*6777b538SAndroid Build Coastguard Worker ext_family_ = results.ext_family;
245*6777b538SAndroid Build Coastguard Worker ext_model_ = results.ext_model;
246*6777b538SAndroid Build Coastguard Worker has_mmx_ = (cpu_info[3] & 0x00800000) != 0;
247*6777b538SAndroid Build Coastguard Worker has_sse_ = (cpu_info[3] & 0x02000000) != 0;
248*6777b538SAndroid Build Coastguard Worker has_sse2_ = (cpu_info[3] & 0x04000000) != 0;
249*6777b538SAndroid Build Coastguard Worker has_sse3_ = (cpu_info[2] & 0x00000001) != 0;
250*6777b538SAndroid Build Coastguard Worker has_ssse3_ = (cpu_info[2] & 0x00000200) != 0;
251*6777b538SAndroid Build Coastguard Worker has_sse41_ = (cpu_info[2] & 0x00080000) != 0;
252*6777b538SAndroid Build Coastguard Worker has_sse42_ = (cpu_info[2] & 0x00100000) != 0;
253*6777b538SAndroid Build Coastguard Worker has_popcnt_ = (cpu_info[2] & 0x00800000) != 0;
254*6777b538SAndroid Build Coastguard Worker
255*6777b538SAndroid Build Coastguard Worker // "Hypervisor Present Bit: Bit 31 of ECX of CPUID leaf 0x1."
256*6777b538SAndroid Build Coastguard Worker // See https://lwn.net/Articles/301888/
257*6777b538SAndroid Build Coastguard Worker // This is checking for any hypervisor. Hypervisors may choose not to
258*6777b538SAndroid Build Coastguard Worker // announce themselves. Hypervisors trap CPUID and sometimes return
259*6777b538SAndroid Build Coastguard Worker // different results to underlying hardware.
260*6777b538SAndroid Build Coastguard Worker is_running_in_vm_ = (static_cast<uint32_t>(cpu_info[2]) & 0x80000000) != 0;
261*6777b538SAndroid Build Coastguard Worker
262*6777b538SAndroid Build Coastguard Worker // AVX instructions will generate an illegal instruction exception unless
263*6777b538SAndroid Build Coastguard Worker // a) they are supported by the CPU,
264*6777b538SAndroid Build Coastguard Worker // b) XSAVE is supported by the CPU and
265*6777b538SAndroid Build Coastguard Worker // c) XSAVE is enabled by the kernel.
266*6777b538SAndroid Build Coastguard Worker // See http://software.intel.com/en-us/blogs/2011/04/14/is-avx-enabled
267*6777b538SAndroid Build Coastguard Worker //
268*6777b538SAndroid Build Coastguard Worker // In addition, we have observed some crashes with the xgetbv instruction
269*6777b538SAndroid Build Coastguard Worker // even after following Intel's example code. (See crbug.com/375968.)
270*6777b538SAndroid Build Coastguard Worker // Because of that, we also test the XSAVE bit because its description in
271*6777b538SAndroid Build Coastguard Worker // the CPUID documentation suggests that it signals xgetbv support.
272*6777b538SAndroid Build Coastguard Worker has_avx_ =
273*6777b538SAndroid Build Coastguard Worker (cpu_info[2] & 0x10000000) != 0 &&
274*6777b538SAndroid Build Coastguard Worker (cpu_info[2] & 0x04000000) != 0 /* XSAVE */ &&
275*6777b538SAndroid Build Coastguard Worker (cpu_info[2] & 0x08000000) != 0 /* OSXSAVE */ &&
276*6777b538SAndroid Build Coastguard Worker (xgetbv(0) & 6) == 6 /* XSAVE enabled by kernel */;
277*6777b538SAndroid Build Coastguard Worker has_aesni_ = (cpu_info[2] & 0x02000000) != 0;
278*6777b538SAndroid Build Coastguard Worker has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
279*6777b538SAndroid Build Coastguard Worker has_avx2_ = has_avx_ && (cpu_info7[1] & 0x00000020) != 0;
280*6777b538SAndroid Build Coastguard Worker
281*6777b538SAndroid Build Coastguard Worker has_pku_ = (cpu_info7[2] & 0x00000010) != 0;
282*6777b538SAndroid Build Coastguard Worker }
283*6777b538SAndroid Build Coastguard Worker
284*6777b538SAndroid Build Coastguard Worker // Get the brand string of the cpu.
285*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info, static_cast<int>(0x80000000));
286*6777b538SAndroid Build Coastguard Worker const uint32_t max_parameter = static_cast<uint32_t>(cpu_info[0]);
287*6777b538SAndroid Build Coastguard Worker
288*6777b538SAndroid Build Coastguard Worker static constexpr uint32_t kParameterStart = 0x80000002;
289*6777b538SAndroid Build Coastguard Worker static constexpr uint32_t kParameterEnd = 0x80000004;
290*6777b538SAndroid Build Coastguard Worker static constexpr uint32_t kParameterSize =
291*6777b538SAndroid Build Coastguard Worker kParameterEnd - kParameterStart + 1;
292*6777b538SAndroid Build Coastguard Worker static_assert(kParameterSize * sizeof(cpu_info) == kBrandNameSize,
293*6777b538SAndroid Build Coastguard Worker "cpu_brand_ has wrong size");
294*6777b538SAndroid Build Coastguard Worker
295*6777b538SAndroid Build Coastguard Worker if (max_parameter >= kParameterEnd) {
296*6777b538SAndroid Build Coastguard Worker size_t i = 0;
297*6777b538SAndroid Build Coastguard Worker for (uint32_t parameter = kParameterStart; parameter <= kParameterEnd;
298*6777b538SAndroid Build Coastguard Worker ++parameter) {
299*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info, static_cast<int>(parameter));
300*6777b538SAndroid Build Coastguard Worker memcpy(&cpu_brand_[i], cpu_info, sizeof(cpu_info));
301*6777b538SAndroid Build Coastguard Worker i += sizeof(cpu_info);
302*6777b538SAndroid Build Coastguard Worker }
303*6777b538SAndroid Build Coastguard Worker cpu_brand_[i] = '\0';
304*6777b538SAndroid Build Coastguard Worker }
305*6777b538SAndroid Build Coastguard Worker
306*6777b538SAndroid Build Coastguard Worker static constexpr uint32_t kParameterContainingNonStopTimeStampCounter =
307*6777b538SAndroid Build Coastguard Worker 0x80000007;
308*6777b538SAndroid Build Coastguard Worker if (max_parameter >= kParameterContainingNonStopTimeStampCounter) {
309*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info,
310*6777b538SAndroid Build Coastguard Worker static_cast<int>(kParameterContainingNonStopTimeStampCounter));
311*6777b538SAndroid Build Coastguard Worker has_non_stop_time_stamp_counter_ = (cpu_info[3] & (1 << 8)) != 0;
312*6777b538SAndroid Build Coastguard Worker }
313*6777b538SAndroid Build Coastguard Worker
314*6777b538SAndroid Build Coastguard Worker if (!has_non_stop_time_stamp_counter_ && is_running_in_vm_) {
315*6777b538SAndroid Build Coastguard Worker int cpu_info_hv[4] = {};
316*6777b538SAndroid Build Coastguard Worker __cpuid(cpu_info_hv, 0x40000000);
317*6777b538SAndroid Build Coastguard Worker if (cpu_info_hv[1] == 0x7263694D && // Micr
318*6777b538SAndroid Build Coastguard Worker cpu_info_hv[2] == 0x666F736F && // osof
319*6777b538SAndroid Build Coastguard Worker cpu_info_hv[3] == 0x76482074) { // t Hv
320*6777b538SAndroid Build Coastguard Worker // If CPUID says we have a variant TSC and a hypervisor has identified
321*6777b538SAndroid Build Coastguard Worker // itself and the hypervisor says it is Microsoft Hyper-V, then treat
322*6777b538SAndroid Build Coastguard Worker // TSC as invariant.
323*6777b538SAndroid Build Coastguard Worker //
324*6777b538SAndroid Build Coastguard Worker // Microsoft Hyper-V hypervisor reports variant TSC as there are some
325*6777b538SAndroid Build Coastguard Worker // scenarios (eg. VM live migration) where the TSC is variant, but for
326*6777b538SAndroid Build Coastguard Worker // our purposes we can treat it as invariant.
327*6777b538SAndroid Build Coastguard Worker has_non_stop_time_stamp_counter_ = true;
328*6777b538SAndroid Build Coastguard Worker }
329*6777b538SAndroid Build Coastguard Worker }
330*6777b538SAndroid Build Coastguard Worker #elif defined(ARCH_CPU_ARM_FAMILY)
331*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
332*6777b538SAndroid Build Coastguard Worker if (require_branding) {
333*6777b538SAndroid Build Coastguard Worker const ProcCpuInfo& info = ParseProcCpu();
334*6777b538SAndroid Build Coastguard Worker
335*6777b538SAndroid Build Coastguard Worker // Ensure the brand can be stored in the internal array.
336*6777b538SAndroid Build Coastguard Worker CHECK_LE(info.brand.size(), kBrandNameSize);
337*6777b538SAndroid Build Coastguard Worker
338*6777b538SAndroid Build Coastguard Worker const size_t chars_copied = info.brand.copy(cpu_brand_, kBrandNameSize);
339*6777b538SAndroid Build Coastguard Worker cpu_brand_[chars_copied] = '\0';
340*6777b538SAndroid Build Coastguard Worker
341*6777b538SAndroid Build Coastguard Worker implementer_ = info.implementer;
342*6777b538SAndroid Build Coastguard Worker part_number_ = info.part_number;
343*6777b538SAndroid Build Coastguard Worker }
344*6777b538SAndroid Build Coastguard Worker
345*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_ARM64)
346*6777b538SAndroid Build Coastguard Worker // Check for Armv8.5-A BTI/MTE support, exposed via HWCAP2
347*6777b538SAndroid Build Coastguard Worker unsigned long hwcap2 = getauxval(AT_HWCAP2);
348*6777b538SAndroid Build Coastguard Worker has_mte_ = hwcap2 & HWCAP2_MTE;
349*6777b538SAndroid Build Coastguard Worker has_bti_ = hwcap2 & HWCAP2_BTI;
350*6777b538SAndroid Build Coastguard Worker #endif
351*6777b538SAndroid Build Coastguard Worker
352*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_WIN)
353*6777b538SAndroid Build Coastguard Worker // Windows makes high-resolution thread timing information available in
354*6777b538SAndroid Build Coastguard Worker // user-space.
355*6777b538SAndroid Build Coastguard Worker has_non_stop_time_stamp_counter_ = true;
356*6777b538SAndroid Build Coastguard Worker #endif
357*6777b538SAndroid Build Coastguard Worker #endif
358*6777b538SAndroid Build Coastguard Worker }
359*6777b538SAndroid Build Coastguard Worker
360*6777b538SAndroid Build Coastguard Worker #if defined(ARCH_CPU_X86_FAMILY)
GetIntelMicroArchitecture() const361*6777b538SAndroid Build Coastguard Worker CPU::IntelMicroArchitecture CPU::GetIntelMicroArchitecture() const {
362*6777b538SAndroid Build Coastguard Worker if (has_avx2()) return AVX2;
363*6777b538SAndroid Build Coastguard Worker if (has_fma3()) return FMA3;
364*6777b538SAndroid Build Coastguard Worker if (has_avx()) return AVX;
365*6777b538SAndroid Build Coastguard Worker if (has_sse42()) return SSE42;
366*6777b538SAndroid Build Coastguard Worker if (has_sse41()) return SSE41;
367*6777b538SAndroid Build Coastguard Worker if (has_ssse3()) return SSSE3;
368*6777b538SAndroid Build Coastguard Worker if (has_sse3()) return SSE3;
369*6777b538SAndroid Build Coastguard Worker if (has_sse2()) return SSE2;
370*6777b538SAndroid Build Coastguard Worker if (has_sse()) return SSE;
371*6777b538SAndroid Build Coastguard Worker return PENTIUM;
372*6777b538SAndroid Build Coastguard Worker }
373*6777b538SAndroid Build Coastguard Worker #endif
374*6777b538SAndroid Build Coastguard Worker
GetInstanceNoAllocation()375*6777b538SAndroid Build Coastguard Worker const CPU& CPU::GetInstanceNoAllocation() {
376*6777b538SAndroid Build Coastguard Worker static ProtectedMemoryInitializer cpu_initializer(g_cpu_instance, CPU(false));
377*6777b538SAndroid Build Coastguard Worker
378*6777b538SAndroid Build Coastguard Worker return *g_cpu_instance;
379*6777b538SAndroid Build Coastguard Worker }
380*6777b538SAndroid Build Coastguard Worker
381*6777b538SAndroid Build Coastguard Worker } // namespace base
382