mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
OcCpuLib: Fixed FSBFrequency calculation with fractional multiplier
closes acidanthera/bugtracker#1529
This commit is contained in:
parent
e5d0896eb8
commit
e2f219e075
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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().
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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.
|
||||
|
||||
|
||||
@ -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
|
||||
));
|
||||
|
||||
|
||||
@ -34,6 +34,7 @@
|
||||
|
||||
[LibraryClasses]
|
||||
BaseLib
|
||||
OcGuardLib
|
||||
IoLib
|
||||
UefiRuntimeServicesTableLib
|
||||
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
Alignment.c
|
||||
BitOverflow.c
|
||||
Canary.c
|
||||
Math.c
|
||||
NativeOverflow.c
|
||||
TripleOverflow.c
|
||||
UbsanPrintf.c
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -51,4 +51,3 @@
|
||||
ImageRunner.c
|
||||
ReleaseUsbOwnership.c
|
||||
ProtocolSupport.c
|
||||
Math.c
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user