Skip to content
This repository has been archived by the owner on Feb 29, 2020. It is now read-only.

Add cpuid hypervisor support to work with virtualization #17

Merged
merged 10 commits into from
Oct 30, 2019
1 change: 1 addition & 0 deletions Include/Library/OcCpuLib.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ typedef struct {
UINT16 PackageCount;
UINT16 CoreCount;
UINT16 ThreadCount;
BOOLEAN Hypervisor;
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved

//
// Platform-dependent frequency for the Always Running Timer (ART), normally
Expand Down
27 changes: 21 additions & 6 deletions Library/OcCpuLib/OcCpuLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1105,8 +1105,8 @@ ScanIntelProcessor (

//
// Calculate number of cores
//
if (Cpu->MaxId >= CPUID_CACHE_PARAMS && Cpu->Model <= CPU_MODEL_PENRYN) {
// If we are under visualization, then we should get topology from acpi as Penryn
if ((Cpu->MaxId >= CPUID_CACHE_PARAMS && Cpu->Model <= CPU_MODEL_PENRYN) || Cpu->Hypervisor) {
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &CpuidCacheEax.Uint32, &CpuidCacheEbx.Uint32, NULL, NULL);
if (CpuidCacheEax.Bits.CacheType != CPUID_CACHE_PARAMS_CACHE_TYPE_NULL) {
CoreCount = (UINT16)GetPowerOfTwo32 (CpuidCacheEax.Bits.MaximumAddressableIdsForProcessorCores + 1);
Expand Down Expand Up @@ -1201,7 +1201,11 @@ ScanAmdProcessor (
CofVid = AsmReadMsr64 (K10_PSTATE_STATUS);
CoreFrequencyID = BitFieldRead64 (CofVid, 0, 7);
CoreDivisorID = BitFieldRead64 (CofVid, 8, 13);
Cpu->MaxBusRatio = (UINT8) (CoreFrequencyID / CoreDivisorID * 2);
if (CoreDivisorID > 0ULL){
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
Cpu->MaxBusRatio = (UINT8) (CoreFrequencyID / CoreDivisorID * 2);
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
} else {
Cpu->MaxBusRatio = 0;
}
//
// Get core count from CPUID
//
Expand All @@ -1226,7 +1230,11 @@ ScanAmdProcessor (
// Core current operating frequency in MHz. CoreCOF = 100 *
// (MSRC001_00[6B:64][CpuFid] + 10h) / (2 ^ MSRC001_00[6B:64][CpuDid]).
//
Cpu->MaxBusRatio = (UINT8)((CoreFrequencyID + 0x10) / Divisor);
if (Divisor > 0ULL){
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
Cpu->MaxBusRatio = (UINT8)((CoreFrequencyID + 0x10) / Divisor);
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
} else {
Cpu->MaxBusRatio = 0;
}
//
// AMD 15h and 16h CPUs don't support hyperthreading,
// so the core count is equal to the thread count
Expand All @@ -1252,8 +1260,12 @@ ScanAmdProcessor (
//
Cpu->CurBusRatio = Cpu->MaxBusRatio;
Cpu->MinBusRatio = Cpu->MaxBusRatio;

Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio);
if (Cpu->MaxBusRatio == 0 || Cpu->Hypervisor) {
// if hypervisor is true, then we just set FSBFrequency
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
Cpu->FSBFrequency = 100000000;
} else {
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, Cpu->MaxBusRatio);
}
}
}

Expand Down Expand Up @@ -1363,13 +1375,16 @@ OcCpuScanProcessor (
Cpu->ExtFamily = (UINT8) Cpu->CpuidVerEax.Bits.ExtendedFamilyId;
Cpu->Brand = (UINT8) Cpu->CpuidVerEbx.Bits.BrandIndex;
Cpu->Features = (((UINT64) Cpu->CpuidVerEcx.Uint32) << 32ULL) | Cpu->CpuidVerEdx.Uint32;
Cpu->Hypervisor = (BOOLEAN) Cpu->CpuidVerEcx.Bits.HYPERVISOR;
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved
if (Cpu->Features & CPUID_FEATURE_HTT) {
Cpu->ThreadCount = (UINT16) Cpu->CpuidVerEbx.Bits.MaximumAddressableIdsForLogicalProcessors;
}
}

DEBUG ((DEBUG_INFO, "OCCPU: %a %a\n", "Found", Cpu->BrandString));

DEBUG ((DEBUG_INFO, "OCCPU: Hypervisor: %a\n", Cpu->Hypervisor ? "Yes": "No"));
Leoyzen marked this conversation as resolved.
Show resolved Hide resolved

DEBUG ((
DEBUG_INFO,
"OCCPU: Signature %0X Stepping %0X Model %0X Family %0X Type %0X ExtModel %0X ExtFamily %0X\n",
Expand Down