From e2f219e07592ba1f0f1c763d68db1eb264d19fae Mon Sep 17 00:00:00 2001 From: vit9696 Date: Thu, 25 Feb 2021 19:44:41 +0300 Subject: [PATCH] OcCpuLib: Fixed `FSBFrequency` calculation with fractional multiplier closes acidanthera/bugtracker#1529 --- Changelog.md | 1 + .../Library/OcAfterBootCompatLib.h | 6 +- Include/Acidanthera/Library/OcCpuLib.h | 63 ++--- Include/Acidanthera/Library/OcGuardLib.h | 19 ++ Include/Acidanthera/Library/OcMiscLib.h | 19 -- .../OcAfterBootCompatLib/BootCompatInternal.h | 4 + Library/OcAfterBootCompatLib/CustomSlide.c | 17 +- .../OcAfterBootCompatLib.c | 3 +- Library/OcCpuLib/FrequencyDetect.c | 2 +- Library/OcCpuLib/OcCpuInternals.h | 23 +- Library/OcCpuLib/OcCpuLib.c | 242 +++++++++--------- Library/OcCpuLib/OcCpuLib.inf | 1 + Library/{OcMiscLib => OcGuardLib}/Math.c | 0 Library/OcGuardLib/OcGuardLib.inf | 1 + Library/OcMainLib/OpenCoreUefi.c | 7 +- Library/OcMiscLib/OcMiscLib.inf | 1 - 16 files changed, 209 insertions(+), 200 deletions(-) rename Library/{OcMiscLib => OcGuardLib}/Math.c (100%) diff --git a/Changelog.md b/Changelog.md index da515ab3..b1c50a6c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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 diff --git a/Include/Acidanthera/Library/OcAfterBootCompatLib.h b/Include/Acidanthera/Library/OcAfterBootCompatLib.h index 039359d8..d0681fbc 100644 --- a/Include/Acidanthera/Library/OcAfterBootCompatLib.h +++ b/Include/Acidanthera/Library/OcAfterBootCompatLib.h @@ -15,6 +15,8 @@ #ifndef OC_AFTER_BOOT_COMPAT_LIB_H #define OC_AFTER_BOOT_COMPAT_LIB_H +#include + /** 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 diff --git a/Include/Acidanthera/Library/OcCpuLib.h b/Include/Acidanthera/Library/OcCpuLib.h index 3687e039..9c9d72de 100755 --- a/Include/Acidanthera/Library/OcCpuLib.h +++ b/Include/Acidanthera/Library/OcCpuLib.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. diff --git a/Include/Acidanthera/Library/OcGuardLib.h b/Include/Acidanthera/Library/OcGuardLib.h index 4866fab5..480f5c7a 100644 --- a/Include/Acidanthera/Library/OcGuardLib.h +++ b/Include/Acidanthera/Library/OcGuardLib.h @@ -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 diff --git a/Include/Acidanthera/Library/OcMiscLib.h b/Include/Acidanthera/Library/OcMiscLib.h index 41171987..941db8d0 100755 --- a/Include/Acidanthera/Library/OcMiscLib.h +++ b/Include/Acidanthera/Library/OcMiscLib.h @@ -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(). diff --git a/Library/OcAfterBootCompatLib/BootCompatInternal.h b/Library/OcAfterBootCompatLib/BootCompatInternal.h index 770b120b..f632789a 100644 --- a/Library/OcAfterBootCompatLib/BootCompatInternal.h +++ b/Library/OcAfterBootCompatLib/BootCompatInternal.h @@ -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; /** diff --git a/Library/OcAfterBootCompatLib/CustomSlide.c b/Library/OcAfterBootCompatLib/CustomSlide.c index c08cf444..8466a742 100644 --- a/Library/OcAfterBootCompatLib/CustomSlide.c +++ b/Library/OcAfterBootCompatLib/CustomSlide.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -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 diff --git a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c b/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c index 29aeca19..705fdfad 100644 --- a/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c +++ b/Library/OcAfterBootCompatLib/OcAfterBootCompatLib.c @@ -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; diff --git a/Library/OcCpuLib/FrequencyDetect.c b/Library/OcCpuLib/FrequencyDetect.c index 6340e16a..331c342e 100644 --- a/Library/OcCpuLib/FrequencyDetect.c +++ b/Library/OcCpuLib/FrequencyDetect.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/Library/OcCpuLib/OcCpuInternals.h b/Library/OcCpuLib/OcCpuInternals.h index 180ac098..17ca6c01 100755 --- a/Library/OcCpuLib/OcCpuInternals.h +++ b/Library/OcCpuLib/OcCpuInternals.h @@ -15,6 +15,8 @@ #ifndef OC_CPU_INTERNALS_H #define OC_CPU_INTERNALS_H +#include + // // 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. diff --git a/Library/OcCpuLib/OcCpuLib.c b/Library/OcCpuLib/OcCpuLib.c index cd4a6776..b4cc6284 100755 --- a/Library/OcCpuLib/OcCpuLib.c +++ b/Library/OcCpuLib/OcCpuLib.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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 )); diff --git a/Library/OcCpuLib/OcCpuLib.inf b/Library/OcCpuLib/OcCpuLib.inf index d560a15b..5a6410ad 100755 --- a/Library/OcCpuLib/OcCpuLib.inf +++ b/Library/OcCpuLib/OcCpuLib.inf @@ -34,6 +34,7 @@ [LibraryClasses] BaseLib + OcGuardLib IoLib UefiRuntimeServicesTableLib diff --git a/Library/OcMiscLib/Math.c b/Library/OcGuardLib/Math.c similarity index 100% rename from Library/OcMiscLib/Math.c rename to Library/OcGuardLib/Math.c diff --git a/Library/OcGuardLib/OcGuardLib.inf b/Library/OcGuardLib/OcGuardLib.inf index b360b152..8a5d98b0 100644 --- a/Library/OcGuardLib/OcGuardLib.inf +++ b/Library/OcGuardLib/OcGuardLib.inf @@ -32,6 +32,7 @@ Alignment.c BitOverflow.c Canary.c + Math.c NativeOverflow.c TripleOverflow.c UbsanPrintf.c diff --git a/Library/OcMainLib/OpenCoreUefi.c b/Library/OcMainLib/OpenCoreUefi.c index 39e48f4b..23ad004b 100644 --- a/Library/OcMainLib/OpenCoreUefi.c +++ b/Library/OcMainLib/OpenCoreUefi.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); diff --git a/Library/OcMiscLib/OcMiscLib.inf b/Library/OcMiscLib/OcMiscLib.inf index 20eeb38d..c599d5b1 100755 --- a/Library/OcMiscLib/OcMiscLib.inf +++ b/Library/OcMiscLib/OcMiscLib.inf @@ -51,4 +51,3 @@ ImageRunner.c ReleaseUsbOwnership.c ProtocolSupport.c - Math.c