blob: 39df0c609f7395c0b3435386f7cf194e2ad68bd1 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:061// Copyright 2012 The Chromium Authors
[email protected]de8d26672008-09-25 22:08:442// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef BASE_CPU_H_
6#define BASE_CPU_H_
7
Bruno Pitrus75c57b52023-06-05 21:22:558#include <cstdint>
[email protected]de8d26672008-09-25 22:08:449#include <string>
10
[email protected]0bea7252011-08-05 15:34:0011#include "base/base_export.h"
Gabriel Marin8fdd7772019-08-17 00:28:0912#include "build/build_config.h"
[email protected]90509cb2011-03-25 18:46:3813
[email protected]de8d26672008-09-25 22:08:4414namespace base {
15
Gabriel Marin8fdd7772019-08-17 00:28:0916#if defined(ARCH_CPU_X86_FAMILY)
17namespace internal {
18
Lei Zhang1b1116c52021-05-14 22:54:3819struct X86ModelInfo {
20 int family;
21 int model;
22 int ext_family;
23 int ext_model;
24};
25
Gabriel Marin8fdd7772019-08-17 00:28:0926// Compute the CPU family and model based on the vendor and CPUID signature.
Lei Zhang1b1116c52021-05-14 22:54:3827BASE_EXPORT X86ModelInfo ComputeX86FamilyAndModel(const std::string& vendor,
28 int signature);
Gabriel Marin8fdd7772019-08-17 00:28:0929
30} // namespace internal
31#endif // defined(ARCH_CPU_X86_FAMILY)
32
[email protected]de8d26672008-09-25 22:08:4433// Query information about the processor.
Thiago Farinaba7d2a422017-06-17 00:18:4934class BASE_EXPORT CPU final {
[email protected]de8d26672008-09-25 22:08:4435 public:
Richard Townsend66bf8b72021-02-18 23:39:5736 CPU();
37 CPU(CPU&&);
38 CPU(const CPU&) = delete;
André Kempe60269112021-09-17 13:14:1139
40 // Get a preallocated instance of CPU.
André Kempe1994caac2024-04-05 15:01:3941 // It can be used in very early application startup or in memory allocation
42 // handlers. The instance of CPU is created without branding, see `CPU(bool
43 // requires_branding)` for details and implications.
44 //
45 // Support for various security features such as Arm's BTI and MTE uses this
46 // instance to detect CPU support. To prevent any attempt
47 // to disable a feature by attacking this data, base::ProtectedMemory is used
48 // to protected it from write accesses.
49 // Note that base::ProtectedMemory falls back to unprotected memory if the
50 // target OS is not supported.
André Kempe60269112021-09-17 13:14:1151 static const CPU& GetInstanceNoAllocation();
[email protected]de8d26672008-09-25 22:08:4452
[email protected]5016a9dd2013-02-02 01:10:0253 enum IntelMicroArchitecture {
Ng Zhi An03baf5e2021-10-04 22:56:5254 PENTIUM = 0,
55 SSE = 1,
56 SSE2 = 2,
57 SSE3 = 3,
58 SSSE3 = 4,
59 SSE41 = 5,
60 SSE42 = 6,
61 AVX = 7,
62 AVX2 = 8,
63 FMA3 = 9,
James Zern8a904ed2024-05-08 23:28:2764 AVX_VNNI = 10,
65 AVX512F = 11,
66 AVX512BW = 12,
67 AVX512_VNNI = 13,
68 MAX_INTEL_MICRO_ARCHITECTURE = 14
[email protected]5016a9dd2013-02-02 01:10:0269 };
70
[email protected]de8d26672008-09-25 22:08:4471 // Accessors for CPU information.
Lei Zhang2c986d52024-04-30 22:12:3072 // TODO(crbug.com/335001230): Most if not all of these should be x86-only.
André Kempe1994caac2024-04-05 15:01:3973 std::string vendor_name() const { return cpu_vendor_; }
[email protected]5c8f89f692013-07-18 11:13:2874 int signature() const { return signature_; }
[email protected]de8d26672008-09-25 22:08:4475 int stepping() const { return stepping_; }
76 int model() const { return model_; }
77 int family() const { return family_; }
78 int type() const { return type_; }
79 int extended_model() const { return ext_model_; }
80 int extended_family() const { return ext_family_; }
Lei Zhang9fc2f7b2024-04-30 23:20:1281#if defined(ARCH_CPU_X86_FAMILY)
[email protected]55508c42012-06-12 08:29:3282 bool has_mmx() const { return has_mmx_; }
83 bool has_sse() const { return has_sse_; }
84 bool has_sse2() const { return has_sse2_; }
85 bool has_sse3() const { return has_sse3_; }
86 bool has_ssse3() const { return has_ssse3_; }
87 bool has_sse41() const { return has_sse41_; }
88 bool has_sse42() const { return has_sse42_; }
ilevyb7d2f4082016-10-30 20:46:5789 bool has_popcnt() const { return has_popcnt_; }
[email protected]5016a9dd2013-02-02 01:10:0290 bool has_avx() const { return has_avx_; }
Ng Zhi An03baf5e2021-10-04 22:56:5291 bool has_fma3() const { return has_fma3_; }
fbarchard0ce41ae2015-10-02 03:23:1992 bool has_avx2() const { return has_avx2_; }
James Zern8a904ed2024-05-08 23:28:2793 bool has_avx_vnni() const { return has_avx_vnni_; }
94 bool has_avx512_f() const { return has_avx512_f_; }
95 bool has_avx512_bw() const { return has_avx512_bw_; }
96 bool has_avx512_vnni() const { return has_avx512_vnni_; }
Lei Zhang2c986d52024-04-30 22:12:3097#endif
[email protected]b54d16d2013-12-02 16:15:0398 bool has_aesni() const { return has_aesni_; }
[email protected]aa312812013-04-30 19:46:0599 bool has_non_stop_time_stamp_counter() const {
100 return has_non_stop_time_stamp_counter_;
101 }
Julian Pastarmov6f4a3182019-06-26 07:00:43102 bool is_running_in_vm() const { return is_running_in_vm_; }
[email protected]c37c1a8c2014-08-08 08:45:24103
Lei Zhange668a1d2022-01-04 21:06:33104#if defined(ARCH_CPU_ARM_FAMILY)
Robert Sesekfd71c382021-01-14 18:40:52105 // The cpuinfo values for ARM cores are from the MIDR_EL1 register, a
106 // bitfield whose format is described in the core-specific manuals. E.g.,
107 // ARM Cortex-A57:
108 // https://developer.arm.com/documentation/ddi0488/h/system-control/aarch64-register-descriptions/main-id-register--el1.
109 uint8_t implementer() const { return implementer_; }
110 uint32_t part_number() const { return part_number_; }
Lei Zhange668a1d2022-01-04 21:06:33111#endif
Robert Sesekfd71c382021-01-14 18:40:52112
Richard Townsend8cb7ba0b2020-11-26 23:23:22113 // Armv8.5-A extensions for control flow and memory safety.
André Kempe60269112021-09-17 13:14:11114#if defined(ARCH_CPU_ARM_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22115 bool has_mte() const { return has_mte_; }
116 bool has_bti() const { return has_bti_; }
André Kempe60269112021-09-17 13:14:11117#else
118 constexpr bool has_mte() const { return false; }
119 constexpr bool has_bti() const { return false; }
120#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22121
Lei Zhange668a1d2022-01-04 21:06:33122#if defined(ARCH_CPU_X86_FAMILY)
Stephen Roettger6f1a4242022-10-07 10:04:25123 // Memory protection key support for user-mode pages
124 bool has_pku() const { return has_pku_; }
125#else
126 constexpr bool has_pku() const { return false; }
127#endif
128
129#if defined(ARCH_CPU_X86_FAMILY)
[email protected]5016a9dd2013-02-02 01:10:02130 IntelMicroArchitecture GetIntelMicroArchitecture() const;
Lei Zhange668a1d2022-01-04 21:06:33131#endif
André Kempe1994caac2024-04-05 15:01:39132 std::string cpu_brand() const { return cpu_brand_; }
[email protected]de8d26672008-09-25 22:08:44133
134 private:
135 // Query the processor for CPUID information.
Richard Townsend66bf8b72021-02-18 23:39:57136 void Initialize(bool requires_branding);
137 explicit CPU(bool requires_branding);
[email protected]de8d26672008-09-25 22:08:44138
Richard Townsend8cb7ba0b2020-11-26 23:23:22139 int signature_ = 0; // raw form of type, family, model, and stepping
140 int type_ = 0; // process type
141 int family_ = 0; // family of the processor
142 int model_ = 0; // model of processor
143 int stepping_ = 0; // processor revision number
144 int ext_model_ = 0;
145 int ext_family_ = 0;
Lei Zhange668a1d2022-01-04 21:06:33146#if defined(ARCH_CPU_ARM_FAMILY)
Robert Sesekfd71c382021-01-14 18:40:52147 uint32_t part_number_ = 0; // ARM MIDR part number
148 uint8_t implementer_ = 0; // ARM MIDR implementer identifier
Lei Zhange668a1d2022-01-04 21:06:33149#endif
Lei Zhang9fc2f7b2024-04-30 23:20:12150#if defined(ARCH_CPU_X86_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22151 bool has_mmx_ = false;
152 bool has_sse_ = false;
153 bool has_sse2_ = false;
154 bool has_sse3_ = false;
155 bool has_ssse3_ = false;
156 bool has_sse41_ = false;
157 bool has_sse42_ = false;
158 bool has_popcnt_ = false;
159 bool has_avx_ = false;
Ng Zhi An03baf5e2021-10-04 22:56:52160 bool has_fma3_ = false;
Richard Townsend8cb7ba0b2020-11-26 23:23:22161 bool has_avx2_ = false;
James Zern8a904ed2024-05-08 23:28:27162 bool has_avx_vnni_ = false;
163 bool has_avx512_f_ = false;
164 bool has_avx512_bw_ = false;
165 bool has_avx512_vnni_ = false;
Lei Zhang2c986d52024-04-30 22:12:30166#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22167 bool has_aesni_ = false;
André Kempe60269112021-09-17 13:14:11168#if defined(ARCH_CPU_ARM_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22169 bool has_mte_ = false; // Armv8.5-A MTE (Memory Taggging Extension)
170 bool has_bti_ = false; // Armv8.5-A BTI (Branch Target Identification)
André Kempe60269112021-09-17 13:14:11171#endif
Stephen Roettger6f1a4242022-10-07 10:04:25172#if defined(ARCH_CPU_X86_FAMILY)
173 bool has_pku_ = false;
174#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22175 bool has_non_stop_time_stamp_counter_ = false;
176 bool is_running_in_vm_ = false;
André Kempe1994caac2024-04-05 15:01:39177
178 // The CPUID instruction of the X86 instruction set returns the vendor name in
179 // 3 32bit registers, which make 12 characters. See "Intel® 64 and IA-32
180 // Architectures Software Developer’s Manual - Volume 2".
181 static constexpr size_t kVendorNameSize = 12;
182 char cpu_vendor_[kVendorNameSize + 1] = "unknown";
183 // The CPUID instruction of the X86 instruction set returns the brand name in
184 // 3*4 32bit registers, which make 48 characters. See "Intel® 64 and IA-32
185 // Architectures Software Developer’s Manual - Volume 2".
186 static constexpr size_t kBrandNameSize = 48;
187 char cpu_brand_[kBrandNameSize + 1] = "\0";
[email protected]de8d26672008-09-25 22:08:44188};
189
190} // namespace base
191
192#endif // BASE_CPU_H_