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 PARTITION_ALLOC_PARTITION_ALLOC_BASE_CPU_H_
6 #define PARTITION_ALLOC_PARTITION_ALLOC_BASE_CPU_H_
7 
8 #include "build/build_config.h"
9 #include "partition_alloc/partition_alloc_base/component_export.h"
10 
11 namespace partition_alloc::internal::base {
12 
13 // Query information about the processor.
PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE)14 class PA_COMPONENT_EXPORT(PARTITION_ALLOC_BASE) CPU final {
15  public:
16   CPU();
17   CPU(CPU&&);
18   CPU(const CPU&) = delete;
19 
20   // Get a preallocated instance of CPU.
21   // This can be used in very early application startup. The instance of CPU is
22   // created without branding, see CPU(bool requires_branding) for details and
23   // implications.
24   static const CPU& GetInstanceNoAllocation();
25 
26   enum IntelMicroArchitecture {
27     PENTIUM = 0,
28     SSE = 1,
29     SSE2 = 2,
30     SSE3 = 3,
31     SSSE3 = 4,
32     SSE41 = 5,
33     SSE42 = 6,
34     AVX = 7,
35     AVX2 = 8,
36     FMA3 = 9,
37     MAX_INTEL_MICRO_ARCHITECTURE = 10
38   };
39 
40   // Accessors for CPU information.
41   int signature() const { return signature_; }
42   int stepping() const { return stepping_; }
43   int type() const { return type_; }
44   bool has_mmx() const { return has_mmx_; }
45   bool has_sse() const { return has_sse_; }
46   bool has_sse2() const { return has_sse2_; }
47   bool has_sse3() const { return has_sse3_; }
48   bool has_ssse3() const { return has_ssse3_; }
49   bool has_sse41() const { return has_sse41_; }
50   bool has_sse42() const { return has_sse42_; }
51   bool has_popcnt() const { return has_popcnt_; }
52   bool has_avx() const { return has_avx_; }
53   bool has_fma3() const { return has_fma3_; }
54   bool has_avx2() const { return has_avx2_; }
55   bool has_aesni() const { return has_aesni_; }
56   bool has_non_stop_time_stamp_counter() const {
57     return has_non_stop_time_stamp_counter_;
58   }
59   bool is_running_in_vm() const { return is_running_in_vm_; }
60 
61   // Armv8.5-A extensions for control flow and memory safety.
62 #if defined(ARCH_CPU_ARM_FAMILY)
63   bool has_mte() const { return has_mte_; }
64   bool has_bti() const { return has_bti_; }
65 #else
66   constexpr bool has_mte() const { return false; }
67   constexpr bool has_bti() const { return false; }
68 #endif
69 
70 #if defined(ARCH_CPU_X86_FAMILY)
71   // Memory protection key support for user-mode pages
72   bool has_pku() const { return has_pku_; }
73 #else
74   constexpr bool has_pku() const { return false; }
75 #endif
76 
77  private:
78   // Query the processor for CPUID information.
79   void Initialize();
80 
81   int signature_ = 0;  // raw form of type, family, model, and stepping
82   int type_ = 0;       // process type
83   int stepping_ = 0;   // processor revision number
84   bool has_mmx_ = false;
85   bool has_sse_ = false;
86   bool has_sse2_ = false;
87   bool has_sse3_ = false;
88   bool has_ssse3_ = false;
89   bool has_sse41_ = false;
90   bool has_sse42_ = false;
91   bool has_popcnt_ = false;
92   bool has_avx_ = false;
93   bool has_fma3_ = false;
94   bool has_avx2_ = false;
95   bool has_aesni_ = false;
96 #if defined(ARCH_CPU_ARM_FAMILY)
97   bool has_mte_ = false;  // Armv8.5-A MTE (Memory Taggging Extension)
98   bool has_bti_ = false;  // Armv8.5-A BTI (Branch Target Identification)
99 #endif
100 #if defined(ARCH_CPU_X86_FAMILY)
101   bool has_pku_ = false;
102 #endif
103   bool has_non_stop_time_stamp_counter_ = false;
104   bool is_running_in_vm_ = false;
105 };
106 
107 }  // namespace partition_alloc::internal::base
108 
109 #endif  // PARTITION_ALLOC_PARTITION_ALLOC_BASE_CPU_H_
110