blob: 686c039ab504984031b1c3169bb19af28b2ac530 [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_; }
Steinar H. Gundersonabf09a02025-05-12 14:00:3397 // NOTE: This does not include 256-bit PCLMUL, which is
98 // a separate feature flag.
99 bool has_pclmul() const { return has_pclmul_; }
Lei Zhang2c986d52024-04-30 22:12:30100#endif
[email protected]b54d16d2013-12-02 16:15:03101 bool has_aesni() const { return has_aesni_; }
[email protected]aa312812013-04-30 19:46:05102 bool has_non_stop_time_stamp_counter() const {
103 return has_non_stop_time_stamp_counter_;
104 }
Julian Pastarmov6f4a3182019-06-26 07:00:43105 bool is_running_in_vm() const { return is_running_in_vm_; }
[email protected]c37c1a8c2014-08-08 08:45:24106
Richard Townsend8cb7ba0b2020-11-26 23:23:22107 // Armv8.5-A extensions for control flow and memory safety.
André Kempe60269112021-09-17 13:14:11108#if defined(ARCH_CPU_ARM_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22109 bool has_mte() const { return has_mte_; }
110 bool has_bti() const { return has_bti_; }
André Kempe60269112021-09-17 13:14:11111#else
112 constexpr bool has_mte() const { return false; }
113 constexpr bool has_bti() const { return false; }
114#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22115
Lei Zhange668a1d2022-01-04 21:06:33116#if defined(ARCH_CPU_X86_FAMILY)
Stephen Roettger6f1a4242022-10-07 10:04:25117 // Memory protection key support for user-mode pages
118 bool has_pku() const { return has_pku_; }
119#else
120 constexpr bool has_pku() const { return false; }
121#endif
122
123#if defined(ARCH_CPU_X86_FAMILY)
[email protected]5016a9dd2013-02-02 01:10:02124 IntelMicroArchitecture GetIntelMicroArchitecture() const;
Lei Zhange668a1d2022-01-04 21:06:33125#endif
André Kempe1994caac2024-04-05 15:01:39126 std::string cpu_brand() const { return cpu_brand_; }
[email protected]de8d26672008-09-25 22:08:44127
128 private:
129 // Query the processor for CPUID information.
Peter Boström20a6e682024-09-30 22:10:11130 void Initialize();
[email protected]de8d26672008-09-25 22:08:44131
Richard Townsend8cb7ba0b2020-11-26 23:23:22132 int signature_ = 0; // raw form of type, family, model, and stepping
133 int type_ = 0; // process type
134 int family_ = 0; // family of the processor
135 int model_ = 0; // model of processor
136 int stepping_ = 0; // processor revision number
137 int ext_model_ = 0;
138 int ext_family_ = 0;
Lei Zhang9fc2f7b2024-04-30 23:20:12139#if defined(ARCH_CPU_X86_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22140 bool has_mmx_ = false;
141 bool has_sse_ = false;
142 bool has_sse2_ = false;
143 bool has_sse3_ = false;
144 bool has_ssse3_ = false;
145 bool has_sse41_ = false;
146 bool has_sse42_ = false;
147 bool has_popcnt_ = false;
148 bool has_avx_ = false;
Ng Zhi An03baf5e2021-10-04 22:56:52149 bool has_fma3_ = false;
Richard Townsend8cb7ba0b2020-11-26 23:23:22150 bool has_avx2_ = false;
James Zern8a904ed2024-05-08 23:28:27151 bool has_avx_vnni_ = false;
152 bool has_avx512_f_ = false;
153 bool has_avx512_bw_ = false;
154 bool has_avx512_vnni_ = false;
Steinar H. Gundersonabf09a02025-05-12 14:00:33155 bool has_pclmul_ = false;
Lei Zhang2c986d52024-04-30 22:12:30156#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22157 bool has_aesni_ = false;
André Kempe60269112021-09-17 13:14:11158#if defined(ARCH_CPU_ARM_FAMILY)
Richard Townsend8cb7ba0b2020-11-26 23:23:22159 bool has_mte_ = false; // Armv8.5-A MTE (Memory Taggging Extension)
160 bool has_bti_ = false; // Armv8.5-A BTI (Branch Target Identification)
André Kempe60269112021-09-17 13:14:11161#endif
Stephen Roettger6f1a4242022-10-07 10:04:25162#if defined(ARCH_CPU_X86_FAMILY)
163 bool has_pku_ = false;
164#endif
Richard Townsend8cb7ba0b2020-11-26 23:23:22165 bool has_non_stop_time_stamp_counter_ = false;
166 bool is_running_in_vm_ = false;
André Kempe1994caac2024-04-05 15:01:39167
168 // The CPUID instruction of the X86 instruction set returns the vendor name in
169 // 3 32bit registers, which make 12 characters. See "Intel® 64 and IA-32
170 // Architectures Software Developer’s Manual - Volume 2".
171 static constexpr size_t kVendorNameSize = 12;
172 char cpu_vendor_[kVendorNameSize + 1] = "unknown";
173 // The CPUID instruction of the X86 instruction set returns the brand name in
174 // 3*4 32bit registers, which make 48 characters. See "Intel® 64 and IA-32
175 // Architectures Software Developer’s Manual - Volume 2".
176 static constexpr size_t kBrandNameSize = 48;
177 char cpu_brand_[kBrandNameSize + 1] = "\0";
[email protected]de8d26672008-09-25 22:08:44178};
179
180} // namespace base
181
182#endif // BASE_CPU_H_