OcCpuLib.h 6.5 KB
Newer Older
V
vit9696 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/** @file
  Copyright (C) 2016 - 2017, The HermitCrabs Lab. All rights reserved.

  All rights reserved.

  This program and the accompanying materials
  are licensed and made available under the terms and conditions of the BSD License
  which accompanies this distribution.  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/

V
vit9696 已提交
15 16
#ifndef OC_CPU_LIB_H
#define OC_CPU_LIB_H
V
vit9696 已提交
17

V
vit9696 已提交
18
#include <Uefi.h>
19
#include <IndustryStandard/CpuId.h>
20
#include <IndustryStandard/AppleIntelCpuInfo.h>
21

V
vit9696 已提交
22 23
/**
  Assumed CPU frequency when it cannot be detected.
24
  Can be overridden by e.g. emulator.
V
vit9696 已提交
25
**/
26
#ifndef OC_FALLBACK_CPU_FREQUENCY
V
vit9696 已提交
27
#define OC_FALLBACK_CPU_FREQUENCY 1000000000
28
#endif
V
vit9696 已提交
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
/**
  Sorted Intel CPU generations.
**/
typedef enum {
  OcCpuGenerationUnknown,
  OcCpuGenerationBanias,
  OcCpuGenerationPrePenryn,
  OcCpuGenerationPenryn,
  OcCpuGenerationNehalem,
  OcCpuGenerationBonnel,
  OcCpuGenerationWestmere,
  OcCpuGenerationSandyBridge,
  OcCpuGenerationPostSandyBridge,
  OcCpuGenerationIvyBridge,
  OcCpuGenerationHaswell,
  OcCpuGenerationBroadwell,
  OcCpuGenerationSkylake,
  OcCpuGenerationKabyLake,
  OcCpuGenerationCoffeeLake,
  OcCpuGenerationCometLake,
  OcCpuGenerationCannonLake,
  OcCpuGenerationIceLake,
  OcCpuGenerationMaxGeneration
} OC_CPU_GENERATION;

V
vit9696 已提交
55
typedef struct {
V
vit9696 已提交
56 57 58
  //
  // Note, Vendor and BrandString are reordered for proper alignment.
  //
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
  UINT32                      Vendor[4];
  CHAR8                       BrandString[48];

  CPUID_VERSION_INFO_EAX      CpuidVerEax;
  CPUID_VERSION_INFO_EBX      CpuidVerEbx;
  CPUID_VERSION_INFO_ECX      CpuidVerEcx;
  CPUID_VERSION_INFO_EDX      CpuidVerEdx;

  CPUID_EXTENDED_CPU_SIG_ECX  CpuidExtSigEcx;
  CPUID_EXTENDED_CPU_SIG_EDX  CpuidExtSigEdx;

  UINT32                      MicrocodeRevision;
  BOOLEAN                     Hypervisor;   ///< indicate whether we are under virtualization

  UINT8                       Type;
  UINT8                       Family;
  UINT8                       Model;
  UINT8                       ExtModel;
  UINT8                       ExtFamily;
  UINT8                       Stepping;
  UINT64                      Features;
  UINT64                      ExtFeatures;
  UINT32                      Signature;
  UINT8                       Brand;
  UINT16                      AppleProcessorType;
  BOOLEAN                     CstConfigLock;

86 87
  OC_CPU_GENERATION           CpuGeneration;

88 89 90 91 92 93
  UINT32                      MaxId;
  UINT32                      MaxExtId;

  UINT16                      PackageCount;
  UINT16                      CoreCount;
  UINT16                      ThreadCount;
94

95 96 97
  //
  // External clock for SMBIOS Type4 table.
  //
98
  UINT16                      ExternalClock;
99

100 101
  //
  // Platform-dependent frequency for the Always Running Timer (ART), normally
102
  // 24Mhz. The firmware may choose to override this. Some CPUs like Xeon Scalable
103 104 105 106
  // use a different frequency. CPUs report the frequency through CPUID.15H.ECX.
  // If unreported, the frequency is looked up based on the model and family.
  //
  // Nominal Core Crystal Clock Frequency for known processor families:
107 108 109
  //   Intel Xeon Scalable with CPUID signature 0x0655: 25 Mhz     (server segment)
  //   6th and 7th generation Intel Core & Xeon W:      24 Mhz     (client segment)
  //   Nex Generation Intel Atom with CPUID 0x065C:     19.2 Mhz   (atom segment)
110
  //
111
  UINT64                      ARTFrequency;
112 113 114 115 116 117 118 119 120

  //
  // The CPU frequency derived from either CPUFrequencyFromTSC (legacy) or
  // CPUFrequencyFromART (preferred for Skylake and presumably newer processors
  // that have an Always Running Timer).
  //
  // CPUFrequencyFromTSC should approximate equal CPUFrequencyFromART. If not,
  // there is likely a bug or miscalculation.
  //
121
  UINT64                      CPUFrequency;
122 123 124 125

  //
  // The CPU frequency as reported by the Time Stamp Counter (TSC).
  //
126
  UINT64                      CPUFrequencyFromTSC;
127 128 129

  //
  // The CPU frequency derived from the Always Running Timer (ART) frequency:
M
M. R. Miller 已提交
130
  //   TSC Freq = (ART Freq * CPUID.15H:EBX[31:0]) / CPUID.15H:EAX[31:0]
131 132 133
  //
  // 0 if ART is not present.
  //
134
  UINT64                      CPUFrequencyFromART;
135

136 137 138
  //
  // TSC adjustment value read from MSR_IA32_TSC_ADJUST if present.
  //
139
  UINT64                      TscAdjust;
140

141 142 143 144 145 146
  //
  // The CPU frequency derived from Apple Platform Info.
  // 0 if Apple Platform Info is not present.
  //
  UINT64                      CPUFrequencyFromApple;

147 148 149 150
  //
  // The CPU frequency derived from the CPUID VMWare Timing leaf.
  // 0 if VMWare Timing leaf is not present.
  //
151
  UINT64                      CPUFrequencyFromVMT;
152

153 154 155 156
  //
  // The Front Side Bus (FSB) frequency calculated from dividing the CPU
  // frequency by the Max Ratio.
  //
157
  UINT64                      FSBFrequency;
158
} OC_CPU_INFO;
V
vit9696 已提交
159

160 161
/**
  Scan the processor and fill the cpu info structure with results.
V
vit9696 已提交
162

163
  @param[in] Cpu  A pointer to the cpu info structure to fill with results.
V
vit9696 已提交
164
**/
165
VOID
V
vit9696 已提交
166
OcCpuScanProcessor (
167
  IN OUT OC_CPU_INFO  *Cpu
V
vit9696 已提交
168 169
  );

170 171 172 173 174 175 176 177 178 179 180
/**
  Disable flex ratio if it has invalid value.
  Commonly fixes early reboot on APTIO IV (Ivy/Haswell).

  @param[in] Cpu  A pointer to the cpu info.
**/
VOID
OcCpuCorrectFlexRatio (
  IN OC_CPU_INFO  *Cpu
  );

181 182 183 184
/**
  Synchronise TSC on all cores (needed on server chipsets and some laptops).
  This does not fully replace VoodooTscSync or TSCAdjustReset due to
  the need to sync on S3 as well and may also work far less reliably
185
  due to the limitation of UEFI firmware not permitting MSR update runs in
186 187 188 189 190 191 192 193 194 195 196 197 198 199
  parallel with BSP and AP cores. However, it lets debug kernels work
  most of the time till the time TSC kexts start.

  @param[in]  Cpu       A pointer to the cpu info.
  @param[in]  Timeout   Amount of time to wait for CPU core rendezvous.

  @retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcCpuCorrectTscSync (
  IN OC_CPU_INFO  *Cpu,
  IN UINTN        Timeout
  );

200 201 202 203 204 205 206
/**
  Converts CPUID Family and Model extracted from EAX
  CPUID (1) call to AppleFamily value. This implements
  cpuid_set_cpufamily functionality as it is in XNU.

  @param[in] VersionEax  CPUID (1) EAX value.

207
  @retval Apple Family (e.g. CPUFAMILY_UNKNOWN)
208 209 210
**/
UINT32
OcCpuModelToAppleFamily (
211
  IN CPUID_VERSION_INFO_EAX  VersionEax
212 213
  );

214 215 216
/**
  Obtain CPU's invariant TSC frequency.

V
vit9696 已提交
217
  @retval CPU's TSC frequency or OC_FALLBACK_CPU_FREQUENCY.
218 219 220 221 222 223
**/
UINT64
OcGetTSCFrequency (
  VOID
  );

V
vit9696 已提交
224
#endif // OC_CPU_LIB_H_