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