OcCpuLib: Fixed FSBFrequency calculation with fractional multiplier

closes acidanthera/bugtracker#1529
This commit is contained in:
vit9696 2021-02-25 19:44:41 +03:00
parent e5d0896eb8
commit e2f219e075
16 changed files with 209 additions and 200 deletions

View File

@ -17,6 +17,7 @@ OpenCore Changelog
- Fixed CPU speed rounding for certain Xeon and Core 2 CPUs
- Removed `KeyMergeThreshold` as it never functioned anyway
- Added `acdtinfo` utility to lookup certain products
- Fixed `FSBFrequency` calculation with fractional multiplier
#### v0.6.6
- Added keyboard and pointer entry scroll support in OpenCanopy

View File

@ -15,6 +15,8 @@
#ifndef OC_AFTER_BOOT_COMPAT_LIB_H
#define OC_AFTER_BOOT_COMPAT_LIB_H
#include <Library/OcCpuLib.h>
/**
Booter patch structure.
**/
@ -196,12 +198,14 @@ typedef struct OC_ABC_SETTINGS_ {
incompatible firmware to prevent boot failure and UEFI services breakage.
@param[in] Settings Compatibility layer configuration.
@param[in] CpuInfo CPU information.
@retval EFI_SUCCESS on success.
**/
EFI_STATUS
OcAbcInitialize (
IN OC_ABC_SETTINGS *Settings
IN OC_ABC_SETTINGS *Settings,
IN OC_CPU_INFO *CpuInfo
);
#endif // OC_AFTER_BOOT_COMPAT_LIB_H

View File

@ -26,6 +26,31 @@
#define OC_FALLBACK_CPU_FREQUENCY 1000000000
#endif
/**
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;
typedef struct {
//
// Note, Vendor and BrandString are reordered for proper alignment.
@ -57,19 +82,11 @@ typedef struct {
UINT16 AppleProcessorType;
BOOLEAN CstConfigLock;
OC_CPU_GENERATION CpuGeneration;
UINT32 MaxId;
UINT32 MaxExtId;
UINT8 MaxDiv;
UINT8 CurBusRatio; ///< Current Multiplier
UINT8 MinBusRatio; ///< Min Bus Ratio
UINT8 MaxBusRatio; ///< Max Bus Ratio
UINT8 TurboBusRatio1;
UINT8 TurboBusRatio2;
UINT8 TurboBusRatio3;
UINT8 TurboBusRatio4;
UINT16 PackageCount;
UINT16 CoreCount;
UINT16 ThreadCount;
@ -133,22 +150,6 @@ typedef struct {
UINT64 FSBFrequency;
} OC_CPU_INFO;
typedef enum {
OcCpuGenerationUnknown,
OcCpuGenerationPenryn,
OcCpuGenerationNehalem,
OcCpuGenerationWestmere,
OcCpuGenerationSandyBridge,
OcCpuGenerationIvyBridge,
OcCpuGenerationHaswell,
OcCpuGenerationBroadwell,
OcCpuGenerationSkylake,
OcCpuGenerationKabyLake,
OcCpuGenerationCoffeeLake,
OcCpuGenerationCannonLake,
OcCpuGenerationMaxGeneration
} OC_CPU_GENERATION;
/**
Scan the processor and fill the cpu info structure with results.
@ -203,16 +204,6 @@ OcCpuModelToAppleFamily (
IN CPUID_VERSION_INFO_EAX VersionEax
);
/**
Obtain CPU's generation.
@retval CPU's generation (e.g. OcCpuGenerationUnknown).
*/
OC_CPU_GENERATION
OcCpuGetGeneration (
VOID
);
/**
Obtain CPU's invariant TSC frequency.

View File

@ -31,6 +31,25 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define OC_POT_ALIGNED(Align, Ptr) (0ULL == (((UINTN) (Ptr)) & (Align-1U)))
#define OC_TYPE_ALIGNED(Type, Ptr) (OC_POT_ALIGNED (OC_ALIGNOF (Type), Ptr))
/**
Return the result of (Multiplicand * Multiplier / Divisor).
@param Multiplicand A 64-bit unsigned value.
@param Multiplier A 64-bit unsigned value.
@param Divisor A 32-bit unsigned value.
@param Remainder A pointer to a 32-bit unsigned value. This parameter is
optional and may be NULL.
@return Multiplicand * Multiplier / Divisor.
**/
UINT64
MultThenDivU64x64x32 (
IN UINT64 Multiplicand,
IN UINT64 Multiplier,
IN UINT32 Divisor,
OUT UINT32 *Remainder OPTIONAL
);
//
// The interfaces below provide base safe arithmetics, reporting
// signed integer overflow and unsigned integer wraparound similarly to

View File

@ -139,25 +139,6 @@ DirectResetCold (
VOID
);
/**
Return the result of (Multiplicand * Multiplier / Divisor).
@param Multiplicand A 64-bit unsigned value.
@param Multiplier A 64-bit unsigned value.
@param Divisor A 32-bit unsigned value.
@param Remainder A pointer to a 32-bit unsigned value. This parameter is
optional and may be NULL.
@return Multiplicand * Multiplier / Divisor.
**/
UINT64
MultThenDivU64x64x32 (
IN UINT64 Multiplicand,
IN UINT64 Multiplier,
IN UINT32 Divisor,
OUT UINT32 *Remainder OPTIONAL
);
/**
Internal worker macro that calls DebugPrint().

View File

@ -412,6 +412,10 @@ typedef struct BOOT_COMPAT_CONTEXT_ {
/// Apple booter KASLR slide support internal state.
///
SLIDE_SUPPORT_STATE SlideSupport;
///
/// CPU information.
///
OC_CPU_INFO *CpuInfo;
} BOOT_COMPAT_CONTEXT;
/**

View File

@ -24,7 +24,6 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcBootManagementLib.h>
#include <Library/OcCpuLib.h>
#include <Library/OcCryptoLib.h>
#include <Library/OcDeviceTreeLib.h>
#include <Library/OcMachoLib.h>
@ -229,7 +228,8 @@ ShouldUseCustomSlideOffset (
IN OUT SLIDE_SUPPORT_STATE *SlideSupport,
IN EFI_GET_MEMORY_MAP GetMemoryMap OPTIONAL,
IN OC_MEMORY_FILTER FilterMap OPTIONAL,
IN VOID *FilterMapContext OPTIONAL
IN VOID *FilterMapContext OPTIONAL,
IN BOOLEAN HasSandyOrIvy
)
{
EFI_PHYSICAL_ADDRESS AllocatedMapPages;
@ -240,7 +240,6 @@ ShouldUseCustomSlideOffset (
EFI_STATUS Status;
UINTN DescriptorSize;
UINT32 DescriptorVersion;
OC_CPU_GENERATION CpuGeneration;
UINTN Index;
UINTN Slide;
UINTN NumEntries;
@ -280,9 +279,7 @@ ShouldUseCustomSlideOffset (
FilterMap (FilterMapContext, MemoryMapSize, MemoryMap, DescriptorSize);
}
CpuGeneration = OcCpuGetGeneration ();
SlideSupport->HasSandyOrIvy = CpuGeneration == OcCpuGenerationSandyBridge ||
CpuGeneration == OcCpuGenerationIvyBridge;
SlideSupport->HasSandyOrIvy = HasSandyOrIvy;
SlideSupport->EstimatedKernelArea = (UINTN) EFI_PAGES_TO_SIZE (
OcCountRuntimePages (MemoryMapSize, MemoryMap, DescriptorSize, NULL)
@ -807,7 +804,13 @@ AppleSlideGetVariable (
);
} else if (StrCmp (VariableName, L"boot-args") == 0
&& (!BootCompat->ServiceState.AppleCustomSlide || BootCompat->Settings.AllowRelocationBlock)
&& ShouldUseCustomSlideOffset (&BootCompat->SlideSupport, GetMemoryMap, FilterMap, FilterMapContext)
&& ShouldUseCustomSlideOffset (
&BootCompat->SlideSupport,
GetMemoryMap,
FilterMap,
FilterMapContext,
BootCompat->CpuInfo->CpuGeneration == OcCpuGenerationSandyBridge
|| BootCompat->CpuInfo->CpuGeneration == OcCpuGenerationIvyBridge)
&& !BootCompat->ServiceState.AppleCustomSlide) {
//
// When we cannot allow some KASLR values due to used address we generate

View File

@ -96,7 +96,8 @@ GetBootCompatContext (
EFI_STATUS
OcAbcInitialize (
IN OC_ABC_SETTINGS *Settings
IN OC_ABC_SETTINGS *Settings,
IN OC_CPU_INFO *CpuInfo
)
{
EFI_STATUS Status;

View File

@ -24,7 +24,7 @@
#include <Library/IoLib.h>
#include <Library/OcCpuLib.h>
#include <Library/PciLib.h>
#include <Library/OcMiscLib.h>
#include <Library/OcGuardLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <IndustryStandard/ProcessorInfo.h>

View File

@ -15,6 +15,8 @@
#ifndef OC_CPU_INTERNALS_H
#define OC_CPU_INTERNALS_H
#include <Library/OcCpuLib.h>
//
// Tolerance within which we consider two frequency values to be roughly
// equivalent.
@ -83,13 +85,26 @@ InternalDetectAppleMajorType (
**/
UINT16
InternalDetectAppleProcessorType (
IN UINT8 Model,
IN UINT8 Stepping,
IN UINT8 AppleMajorType,
IN UINT16 CoreCount,
IN UINT8 Model,
IN UINT8 Stepping,
IN UINT8 AppleMajorType,
IN UINT16 CoreCount,
IN BOOLEAN Is64Bit
);
/**
Obtain Intel CPU generation.
@param[in] Model CPU model from CPUID.
@retval CPU's generation (e.g. OcCpuGenerationUnknown).
*/
OC_CPU_GENERATION
InternalDetectIntelProcessorGeneration (
IN OC_CPU_INFO *CpuInfo
);
/**
Obtain ACPI PM timer address for this BSP.

View File

@ -21,6 +21,7 @@
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/OcCpuLib.h>
#include <Library/OcGuardLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <IndustryStandard/ProcessorInfo.h>
#include <Register/Microcode.h>
@ -270,6 +271,69 @@ ScanThreadCount (
return Status;
}
STATIC
VOID
ScanIntelFSBFrequency (
IN OC_CPU_INFO *CpuInfo
)
{
MSR_IA32_PERF_STATUS_REGISTER PerfStatus;
MSR_NEHALEM_PLATFORM_INFO_REGISTER PlatformInfo;
UINT8 MaxBusRatio;
UINT8 MaxBusRatioDiv;
//
// TODO: this may not be accurate on some older processors.
//
if (CpuInfo->CpuGeneration >= OcCpuGenerationNehalem) {
PlatformInfo.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_INFO);
MaxBusRatio = (UINT8) PlatformInfo.Bits.MaximumNonTurboRatio;
MaxBusRatioDiv = 0;
} else {
PerfStatus.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS);
MaxBusRatio = (UINT8) (RShiftU64 (PerfStatus.Uint64, 8) & 0x1FU);
//
// Undocumented values:
// Non-integer bus ratio for the max-multi.
// Non-integer bus ratio for the current-multi.
//
MaxBusRatioDiv = (UINT8) (RShiftU64 (PerfStatus.Uint64, 46) & BIT0);
}
//
// There may be some quirks with virtual CPUs (VMware is fine).
// Formerly we checked Cpu->MinBusRatio > 0, but we have no MinBusRatio on Penryn.
//
if (CpuInfo->CPUFrequency > 0 && MaxBusRatio > 0) {
if (MaxBusRatioDiv == 0) {
CpuInfo->FSBFrequency = DivU64x32 (CpuInfo->CPUFrequency, MaxBusRatio);
} else {
CpuInfo->FSBFrequency = MultThenDivU64x64x32 (
CpuInfo->CPUFrequency,
2,
2 * MaxBusRatio + 1,
NULL
);
}
} else {
//
// TODO: It seems to be possible that CPU frequency == 0 here...
//
CpuInfo->FSBFrequency = 100000000; // 100 MHz
}
DEBUG ((
DEBUG_INFO,
"OCCPU: Intel TSC: %11LuHz, %5LuMHz; FSB: %11LuHz, %5LuMHz; MaxBusRatio: %u%a\n",
CpuInfo->CPUFrequency,
DivU64x32 (CpuInfo->CPUFrequency, 1000000),
CpuInfo->FSBFrequency,
DivU64x32 (CpuInfo->FSBFrequency, 1000000),
MaxBusRatio,
MaxBusRatioDiv != 0 ? ".5" : ""
));
}
STATIC
VOID
ScanIntelProcessorApple (
@ -300,10 +364,6 @@ ScanIntelProcessor (
CPUID_CACHE_PARAMS_EAX CpuidCacheEax;
CPUID_CACHE_PARAMS_EBX CpuidCacheEbx;
MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL_REGISTER PkgCstConfigControl;
MSR_IA32_PERF_STATUS_REGISTER PerfStatus;
MSR_NEHALEM_PLATFORM_INFO_REGISTER PlatformInfo;
OC_CPU_GENERATION CpuGeneration;
MSR_NEHALEM_TURBO_RATIO_LIMIT_REGISTER TurboLimit;
UINT16 CoreCount;
CONST CHAR8 *TimerSourceType;
UINTN TimerAddr;
@ -315,11 +375,13 @@ ScanIntelProcessor (
return;
}
Cpu->CpuGeneration = InternalDetectIntelProcessorGeneration (Cpu);
//
// Some virtual machines like QEMU 5.0 with KVM will fail to read this value.
// REF: https://github.com/acidanthera/bugtracker/issues/914
//
if (Cpu->Model >= CPU_MODEL_SANDYBRIDGE && !Cpu->Hypervisor) {
if (Cpu->CpuGeneration >= OcCpuGenerationSandyBridge && !Cpu->Hypervisor) {
PkgCstConfigControl.Uint64 = AsmReadMsr64 (MSR_SANDY_BRIDGE_PKG_CST_CONFIG_CONTROL);
Cpu->CstConfigLock = PkgCstConfigControl.Bits.CFGLock == 1;
} else {
@ -334,59 +396,6 @@ ScanIntelProcessor (
// Things may be different in other hypervisors, but should work with QEMU/VMWare for now.
//
if (Cpu->CPUFrequencyFromVMT == 0) {
//
// TODO: this may not be accurate on some older processors.
//
if (Cpu->Model >= CPU_MODEL_NEHALEM) {
PerfStatus.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS);
PlatformInfo.Uint64 = AsmReadMsr64 (MSR_NEHALEM_PLATFORM_INFO);
Cpu->MinBusRatio = (UINT8) PlatformInfo.Bits.MaximumEfficiencyRatio;
Cpu->MaxBusRatio = (UINT8) PlatformInfo.Bits.MaximumNonTurboRatio;
CpuGeneration = OcCpuGetGeneration ();
if (CpuGeneration == OcCpuGenerationNehalem
|| CpuGeneration == OcCpuGenerationWestmere) {
Cpu->CurBusRatio = (UINT8) PerfStatus.Bits.State;
} else {
Cpu->CurBusRatio = (UINT8) (PerfStatus.Bits.State >> 8U);
}
} else {
PerfStatus.Uint64 = AsmReadMsr64 (MSR_IA32_PERF_STATUS);
Cpu->MaxBusRatio = (UINT8) (RShiftU64 (PerfStatus.Uint64, 8) & 0x1FU);
//
// Undocumented values:
// Non-integer bus ratio for the max-multi.
// Non-integer bus ratio for the current-multi.
//
// MaxBusRatioDiv = (UINT8) (RShiftU64 (PerfStatus.Uint64, 46) & 0x01U);
// CurrDiv = (UINT8) (RShiftU64 (PerfStatus.Uint64, 14) & 0x01U);
//
}
if (Cpu->Model >= CPU_MODEL_NEHALEM
&& Cpu->Model != CPU_MODEL_NEHALEM_EX
&& Cpu->Model != CPU_MODEL_WESTMERE_EX
&& Cpu->Model != CPU_MODEL_BONNELL
&& Cpu->Model != CPU_MODEL_BONNELL_MID) {
TurboLimit.Uint64 = AsmReadMsr64 (MSR_NEHALEM_TURBO_RATIO_LIMIT);
Cpu->TurboBusRatio1 = (UINT8) TurboLimit.Bits.Maximum1C;
Cpu->TurboBusRatio2 = (UINT8) TurboLimit.Bits.Maximum2C;
Cpu->TurboBusRatio3 = (UINT8) TurboLimit.Bits.Maximum3C;
Cpu->TurboBusRatio4 = (UINT8) TurboLimit.Bits.Maximum4C;
}
DEBUG ((
DEBUG_INFO,
"OCCPU: Ratio Min %d Max %d Current %d Turbo %d %d %d %d\n",
Cpu->MinBusRatio,
Cpu->MaxBusRatio,
Cpu->CurBusRatio,
Cpu->TurboBusRatio1,
Cpu->TurboBusRatio2,
Cpu->TurboBusRatio3,
Cpu->TurboBusRatio4
));
//
// For logging purposes (the first call to these functions might happen
// before logging is fully initialised), do not use the cached results in
@ -436,27 +445,16 @@ ScanIntelProcessor (
));
}
//
// There may be some quirks with virtual CPUs (VMware is fine).
// Formerly we checked Cpu->MinBusRatio > 0, but we have no MinBusRatio on Penryn.
//
if (Cpu->CPUFrequency > 0 && Cpu->MaxBusRatio > Cpu->MinBusRatio) {
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio);
} else {
//
// TODO: It seems to be possible that CPU frequency == 0 here...
//
Cpu->FSBFrequency = 100000000; // 100 Mhz
}
ScanIntelFSBFrequency (Cpu);
}
//
// Calculate number of cores.
// If we are under virtualization, then we should get the topology from CPUID the same was as with Penryn.
//
if (Cpu->MaxId >= CPUID_CACHE_PARAMS
&& (Cpu->Model <= CPU_MODEL_PENRYN
|| Cpu->Model == CPU_MODEL_BONNELL
|| Cpu->Model == CPU_MODEL_BONNELL_MID
&& (Cpu->CpuGeneration == OcCpuGenerationPrePenryn
|| Cpu->CpuGeneration == OcCpuGenerationPenryn
|| Cpu->CpuGeneration == OcCpuGenerationBonnel
|| Cpu->Hypervisor)) {
AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CpuidCacheEax.Uint32, &CpuidCacheEbx.Uint32, NULL, NULL);
if (CpuidCacheEax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) {
@ -473,11 +471,11 @@ ScanIntelProcessor (
Cpu->ThreadCount = Cpu->CoreCount;
}
}
} else if (Cpu->Model == CPU_MODEL_WESTMERE) {
} else if (Cpu->CpuGeneration == OcCpuGenerationWestmere) {
Msr = AsmReadMsr64 (MSR_CORE_THREAD_COUNT);
Cpu->CoreCount = (UINT16)BitFieldRead64 (Msr, 16, 19);
Cpu->ThreadCount = (UINT16)BitFieldRead64 (Msr, 0, 15);
} else if (Cpu->Model == CPU_MODEL_BANIAS || Cpu->Model == CPU_MODEL_DOTHAN) {
} else if (Cpu->CpuGeneration == OcCpuGenerationBanias) {
//
// Banias and Dothan (Pentium M and Celeron M) never had
// multiple cores or threads, and do not support the MSR below.
@ -513,6 +511,7 @@ ScanAmdProcessor (
UINT8 CoreFrequencyID;
UINT8 CoreDivisorID;
UINT8 Divisor;
UINT8 MaxBusRatio;
BOOLEAN Recalculate;
//
@ -556,6 +555,7 @@ ScanAmdProcessor (
Divisor = 0;
CoreFrequencyID = 0;
CoreDivisorID = 0;
MaxBusRatio = 0;
switch (Cpu->ExtFamily) {
case AMD_CPU_EXT_FAMILY_17H:
@ -569,7 +569,7 @@ ScanAmdProcessor (
// Sometimes incorrect hypervisor configuration will lead to dividing by zero,
// but these variables will not be used under hypervisor, so just skip these.
//
Cpu->MaxBusRatio = (UINT8) (CoreFrequencyID / CoreDivisorID * 2);
MaxBusRatio = (UINT8) (CoreFrequencyID / CoreDivisorID * 2);
}
}
//
@ -602,7 +602,7 @@ ScanAmdProcessor (
// Sometimes incorrect hypervisor configuration will lead to dividing by zero,
// but these variables will not be used under hypervisor, so just skip these.
//
Cpu->MaxBusRatio = (UINT8)((CoreFrequencyID + 0x10) / Divisor);
MaxBusRatio = (UINT8)((CoreFrequencyID + 0x10) / Divisor);
}
}
//
@ -621,7 +621,7 @@ ScanAmdProcessor (
CoreFrequencyID,
CoreDivisorID,
Divisor,
Cpu->MaxBusRatio
MaxBusRatio
));
//
@ -631,20 +631,12 @@ ScanAmdProcessor (
//
// Sometimes incorrect hypervisor configuration will lead to dividing by zero.
//
if (Cpu->MaxBusRatio == 0) {
Cpu->FSBFrequency = 100000000; // 100 Mhz like Intel part.
Cpu->MaxBusRatio = 1; // TODO: Maybe unsafe too, we need more investigation.
if (MaxBusRatio == 0) {
Cpu->FSBFrequency = 100000000; // 100 MHz like Intel part.
} else {
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio);
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, MaxBusRatio);
}
//
// CPUPM is not supported on AMD, meaning the current
// and minimum bus ratio are equal to the maximum bus ratio
//
Cpu->CurBusRatio = Cpu->MaxBusRatio;
Cpu->MinBusRatio = Cpu->MaxBusRatio;
}
}
}
@ -790,24 +782,14 @@ OcCpuScanProcessor (
if (Cpu->CPUFrequencyFromVMT > 0) {
Cpu->CPUFrequency = Cpu->CPUFrequencyFromVMT;
//
// We can calculate Bus Ratio here
//
Cpu->MaxBusRatio = (UINT8) DivU64x32 (Cpu->CPUFrequency, (UINT32)Cpu->FSBFrequency);
//
// We don't have anything like turbo, so we just assign some variables here
//
Cpu->MinBusRatio = Cpu->MaxBusRatio;
Cpu->CurBusRatio = Cpu->MaxBusRatio;
DEBUG ((
DEBUG_INFO,
"OCCPU: VMWare TSC: %11LuHz, %5LuMHz; FSB: %11LuHz, %5LuMHz; BusRatio: %d\n",
"OCCPU: VMWare TSC: %11LuHz, %5LuMHz; FSB: %11LuHz, %5LuMHz\n",
Cpu->CPUFrequency,
DivU64x32 (Cpu->CPUFrequency, 1000000),
Cpu->FSBFrequency,
DivU64x32 (Cpu->FSBFrequency, 1000000),
Cpu->MaxBusRatio
DivU64x32 (Cpu->FSBFrequency, 1000000)
));
}
@ -1004,32 +986,19 @@ OcCpuCorrectTscSync (
}
OC_CPU_GENERATION
OcCpuGetGeneration (
VOID
InternalDetectIntelProcessorGeneration (
IN OC_CPU_INFO *CpuInfo
)
{
CPU_MICROCODE_PROCESSOR_SIGNATURE Sig;
UINT32 CpuFamily;
UINT32 CpuModel;
OC_CPU_GENERATION CpuGeneration;
Sig.Uint32 = 0;
AsmCpuid (1, &Sig.Uint32, NULL, NULL, NULL);
CpuFamily = Sig.Bits.Family;
if (CpuFamily == 15) {
CpuFamily += Sig.Bits.ExtendedFamily;
}
CpuModel = Sig.Bits.Model;
if (CpuFamily == 15 || CpuFamily == 6) {
CpuModel |= Sig.Bits.ExtendedModel << 4;
}
OC_CPU_GENERATION CpuGeneration;
CpuGeneration = OcCpuGenerationUnknown;
if (CpuFamily == 6) {
switch (CpuModel) {
if (CpuInfo->Family == 6) {
switch (CpuInfo->Model) {
case CPU_MODEL_BANIAS:
case CPU_MODEL_DOTHAN:
CpuGeneration = OcCpuGenerationBanias;
break;
case CPU_MODEL_PENRYN:
CpuGeneration = OcCpuGenerationPenryn;
break;
@ -1039,6 +1008,10 @@ OcCpuGetGeneration (
case CPU_MODEL_NEHALEM_EX:
CpuGeneration = OcCpuGenerationNehalem;
break;
case CPU_MODEL_BONNELL:
case CPU_MODEL_BONNELL_MID:
CpuGeneration = OcCpuGenerationBonnel;
break;
case CPU_MODEL_DALES_32NM:
case CPU_MODEL_WESTMERE:
case CPU_MODEL_WESTMERE_EX:
@ -1073,7 +1046,7 @@ OcCpuGetGeneration (
//
// Kaby has 0x9 stepping, and Coffee use 0xA / 0xB stepping.
//
if (Sig.Bits.Stepping == 9) {
if (CpuInfo->Stepping == 9) {
CpuGeneration = OcCpuGenerationKabyLake;
} else {
CpuGeneration = OcCpuGenerationCoffeeLake;
@ -1082,15 +1055,30 @@ OcCpuGetGeneration (
case CPU_MODEL_CANNONLAKE:
CpuGeneration = OcCpuGenerationCannonLake;
break;
case CPU_MODEL_COMETLAKE_S:
case CPU_MODEL_COMETLAKE_U:
CpuGeneration = OcCpuGenerationCometLake;
break;
case CPU_MODEL_ICELAKE_Y:
case CPU_MODEL_ICELAKE_U:
case CPU_MODEL_ICELAKE_SP:
CpuGeneration = OcCpuGenerationIceLake;
break;
default:
if (CpuInfo->Model < CPU_MODEL_PENRYN) {
CpuGeneration = OcCpuGenerationPrePenryn;
} else if (CpuInfo->Model >= CPU_MODEL_SANDYBRIDGE) {
CpuGeneration = OcCpuGenerationPostSandyBridge;
}
}
}
DEBUG ((
DEBUG_VERBOSE,
"OCCPU: Discovered CpuFamily %d CpuModel %d CpuStepping %d CpuGeneration %d\n",
CpuFamily,
CpuModel,
Sig.Bits.Stepping,
CpuInfo->Family,
CpuInfo->Model,
CpuInfo->Stepping,
CpuGeneration
));

View File

@ -34,6 +34,7 @@
[LibraryClasses]
BaseLib
OcGuardLib
IoLib
UefiRuntimeServicesTableLib

View File

@ -32,6 +32,7 @@
Alignment.c
BitOverflow.c
Canary.c
Math.c
NativeOverflow.c
TripleOverflow.c
UbsanPrintf.c

View File

@ -511,7 +511,8 @@ OcInstallPermissiveSecurityPolicy (
VOID
OcLoadBooterUefiSupport (
IN OC_GLOBAL_CONFIG *Config
IN OC_GLOBAL_CONFIG *Config,
IN OC_CPU_INFO *CpuInfo
)
{
OC_ABC_SETTINGS AbcSettings;
@ -656,7 +657,7 @@ OcLoadBooterUefiSupport (
AbcSettings.ExitBootServicesHandlers = mOcExitBootServicesHandlers;
AbcSettings.ExitBootServicesHandlerContexts = mOcExitBootServicesContexts;
OcAbcInitialize (&AbcSettings);
OcAbcInitialize (&AbcSettings, CpuInfo);
}
VOID
@ -728,7 +729,7 @@ OcLoadUefiSupport (
//
// Setup Apple bootloader specific UEFI features.
//
OcLoadBooterUefiSupport (Config);
OcLoadBooterUefiSupport (Config, CpuInfo);
if (Config->Uefi.Quirks.IgnoreInvalidFlexRatio) {
OcCpuCorrectFlexRatio (CpuInfo);

View File

@ -51,4 +51,3 @@
ImageRunner.c
ReleaseUsbOwnership.c
ProtocolSupport.c
Math.c