1 // Copyright 2012 The Chromium Authors 2 // 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 8 #include <cstdint> 9 #include <string> 10 11 #include "base/base_export.h" 12 #include "build/build_config.h" 13 14 namespace base { 15 16 #if defined(ARCH_CPU_X86_FAMILY) 17 namespace internal { 18 19 struct X86ModelInfo { 20 int family; 21 int model; 22 int ext_family; 23 int ext_model; 24 }; 25 26 // Compute the CPU family and model based on the vendor and CPUID signature. 27 BASE_EXPORT X86ModelInfo ComputeX86FamilyAndModel(const std::string& vendor, 28 int signature); 29 30 } // namespace internal 31 #endif // defined(ARCH_CPU_X86_FAMILY) 32 33 // Query information about the processor. 34 class BASE_EXPORT CPU final { 35 public: 36 CPU(); 37 CPU(CPU&&); 38 CPU(const CPU&) = delete; 39 40 // Get a preallocated instance of CPU. 41 // This can be used in very early application startup. The instance of CPU is 42 // created without branding, see CPU(bool requires_branding) for details and 43 // implications. 44 static const CPU& GetInstanceNoAllocation(); 45 46 enum IntelMicroArchitecture { 47 PENTIUM = 0, 48 SSE = 1, 49 SSE2 = 2, 50 SSE3 = 3, 51 SSSE3 = 4, 52 SSE41 = 5, 53 SSE42 = 6, 54 AVX = 7, 55 AVX2 = 8, 56 FMA3 = 9, 57 MAX_INTEL_MICRO_ARCHITECTURE = 10 58 }; 59 60 // Accessors for CPU information. vendor_name()61 const std::string& vendor_name() const { return cpu_vendor_; } signature()62 int signature() const { return signature_; } stepping()63 int stepping() const { return stepping_; } model()64 int model() const { return model_; } family()65 int family() const { return family_; } type()66 int type() const { return type_; } extended_model()67 int extended_model() const { return ext_model_; } extended_family()68 int extended_family() const { return ext_family_; } has_mmx()69 bool has_mmx() const { return has_mmx_; } has_sse()70 bool has_sse() const { return has_sse_; } has_sse2()71 bool has_sse2() const { return has_sse2_; } has_sse3()72 bool has_sse3() const { return has_sse3_; } has_ssse3()73 bool has_ssse3() const { return has_ssse3_; } has_sse41()74 bool has_sse41() const { return has_sse41_; } has_sse42()75 bool has_sse42() const { return has_sse42_; } has_popcnt()76 bool has_popcnt() const { return has_popcnt_; } has_avx()77 bool has_avx() const { return has_avx_; } has_fma3()78 bool has_fma3() const { return has_fma3_; } has_avx2()79 bool has_avx2() const { return has_avx2_; } has_aesni()80 bool has_aesni() const { return has_aesni_; } has_non_stop_time_stamp_counter()81 bool has_non_stop_time_stamp_counter() const { 82 return has_non_stop_time_stamp_counter_; 83 } is_running_in_vm()84 bool is_running_in_vm() const { return is_running_in_vm_; } 85 86 #if defined(ARCH_CPU_ARM_FAMILY) 87 // The cpuinfo values for ARM cores are from the MIDR_EL1 register, a 88 // bitfield whose format is described in the core-specific manuals. E.g., 89 // ARM Cortex-A57: 90 // https://developer.arm.com/documentation/ddi0488/h/system-control/aarch64-register-descriptions/main-id-register--el1. implementer()91 uint8_t implementer() const { return implementer_; } part_number()92 uint32_t part_number() const { return part_number_; } 93 #endif 94 95 // Armv8.5-A extensions for control flow and memory safety. 96 #if defined(ARCH_CPU_ARM_FAMILY) has_mte()97 bool has_mte() const { return has_mte_; } has_bti()98 bool has_bti() const { return has_bti_; } 99 #else has_mte()100 constexpr bool has_mte() const { return false; } has_bti()101 constexpr bool has_bti() const { return false; } 102 #endif 103 104 #if defined(ARCH_CPU_X86_FAMILY) 105 // Memory protection key support for user-mode pages has_pku()106 bool has_pku() const { return has_pku_; } 107 #else has_pku()108 constexpr bool has_pku() const { return false; } 109 #endif 110 111 #if defined(ARCH_CPU_X86_FAMILY) 112 IntelMicroArchitecture GetIntelMicroArchitecture() const; 113 #endif cpu_brand()114 const std::string& cpu_brand() const { return cpu_brand_; } 115 116 private: 117 // Query the processor for CPUID information. 118 void Initialize(bool requires_branding); 119 explicit CPU(bool requires_branding); 120 121 int signature_ = 0; // raw form of type, family, model, and stepping 122 int type_ = 0; // process type 123 int family_ = 0; // family of the processor 124 int model_ = 0; // model of processor 125 int stepping_ = 0; // processor revision number 126 int ext_model_ = 0; 127 int ext_family_ = 0; 128 #if defined(ARCH_CPU_ARM_FAMILY) 129 uint32_t part_number_ = 0; // ARM MIDR part number 130 uint8_t implementer_ = 0; // ARM MIDR implementer identifier 131 #endif 132 bool has_mmx_ = false; 133 bool has_sse_ = false; 134 bool has_sse2_ = false; 135 bool has_sse3_ = false; 136 bool has_ssse3_ = false; 137 bool has_sse41_ = false; 138 bool has_sse42_ = false; 139 bool has_popcnt_ = false; 140 bool has_avx_ = false; 141 bool has_fma3_ = false; 142 bool has_avx2_ = false; 143 bool has_aesni_ = false; 144 #if defined(ARCH_CPU_ARM_FAMILY) 145 bool has_mte_ = false; // Armv8.5-A MTE (Memory Taggging Extension) 146 bool has_bti_ = false; // Armv8.5-A BTI (Branch Target Identification) 147 #endif 148 #if defined(ARCH_CPU_X86_FAMILY) 149 bool has_pku_ = false; 150 #endif 151 bool has_non_stop_time_stamp_counter_ = false; 152 bool is_running_in_vm_ = false; 153 std::string cpu_vendor_ = "unknown"; 154 std::string cpu_brand_; 155 }; 156 157 } // namespace base 158 159 #endif // BASE_CPU_H_ 160