Skip to content

Commit

Permalink
OcCpuLib: Add support for AMD_CPU_EXT_FAMILY_1AH (#557)
Browse files Browse the repository at this point in the history
  • Loading branch information
Shaneee authored Sep 11, 2024
1 parent fa4112e commit 5c42665
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
1 change: 1 addition & 0 deletions Include/Intel/IndustryStandard/ProcessorInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ typedef enum {
#define AMD_CPU_EXT_FAMILY_16H 0x7
#define AMD_CPU_EXT_FAMILY_17H 0x8
#define AMD_CPU_EXT_FAMILY_19H 0xA
#define AMD_CPU_EXT_FAMILY_1AH 0x1A

// CPU_P_STATE_COORDINATION
/// P-State Coordination
Expand Down
13 changes: 10 additions & 3 deletions Library/OcAppleKernelLib/CpuidPatches.c
Original file line number Diff line number Diff line change
Expand Up @@ -1646,15 +1646,22 @@ PatchProvideCurrentCpuInfo (
// Perform TSC and FSB calculations. This is traditionally done in tsc.c in XNU.
//
// For AMD Processors
if ((CpuInfo->Family == 0xF) && ((CpuInfo->ExtFamily == 0x8) || (CpuInfo->ExtFamily == 0xA))) {
if ((CpuInfo->Family == 0xF) && ((CpuInfo->ExtFamily == 0x8) || (CpuInfo->ExtFamily == 0xA) || (CpuInfo->ExtFamily == 0xB))) {
DEBUG ((DEBUG_INFO, "OCAK: Setting FSB and TSC for Family 0x%x and ExtFamily 0x%x\n", (UINT16)CpuInfo->Family, (UINT16)CpuInfo->ExtFamily));
busFreqValue = CpuInfo->FSBFrequency;
busFreqValue = CpuInfo->FSBFrequency;

// Handle case where FSBFrequency is zero, providing a fallback
if (busFreqValue == 0) {
busFreqValue = 100000000; // Assume 100 MHz FSB as fallback
DEBUG ((DEBUG_WARN, "OCAK: FSBFrequency is zero, using fallback value: 100 MHz\n"));
}

busFCvtt2nValue = DivU64x64Remainder ((1000000000ULL << 32), busFreqValue, NULL);
busFCvtn2tValue = DivU64x64Remainder ((1000000000ULL << 32), busFCvtt2nValue, NULL);

tscFreqValue = CpuInfo->CPUFrequency;
tscFCvtt2nValue = DivU64x64Remainder ((1000000000ULL << 32), tscFreqValue, NULL);
tscFCvtn2tValue = DivU64x64Remainder ((1000000000ULL << 32), tscFCvtt2nValue, NULL);
tscFCvtn2tValue = DivU64x64Remainder ((1000000000ULL << 32), tscFCvtt2nValue, NULL);
}
// For all other processors
else {
Expand Down
31 changes: 31 additions & 0 deletions Library/OcCpuLib/OcCpuLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -690,6 +690,35 @@ ScanAmdProcessor (
MaxBusRatio = 0;

switch (Cpu->ExtFamily) {
case AMD_CPU_EXT_FAMILY_1AH:
if (Cpu->CPUFrequencyFromVMT == 0) {
CofVid = AsmReadMsr64 (K10_PSTATE_STATUS);
CoreFrequencyID = (UINT8)BitFieldRead64 (CofVid, 0, 11); // 12-bit field for FID

// On AMD Family 1Ah and later, if the Frequency ID (FID) exceeds 0x0f,
// the core frequency is scaled by a factor of 5. This scaling behavior
// is based on Linux kernel logic for handling higher frequency multipliers
// in newer AMD CPUs, where the FID no longer directly correlates to the
// bus ratio.
if (CoreFrequencyID > 0x0f) {
CoreFrequencyID *= 5;
}

MaxBusRatio = (UINT8)(CoreFrequencyID);
}

//
// Get core count from CPUID
//
if (Cpu->MaxExtId >= 0x8000001E) {
AsmCpuid (0x8000001E, NULL, &CpuidEbx, NULL, NULL);
Cpu->CoreCount = (UINT16)DivU64x32 (
Cpu->ThreadCount,
(BitFieldRead32 (CpuidEbx, 8, 15) + 1)
);
}

break;
case AMD_CPU_EXT_FAMILY_17H:
case AMD_CPU_EXT_FAMILY_19H:
if (Cpu->CPUFrequencyFromVMT == 0) {
Expand Down Expand Up @@ -785,6 +814,8 @@ ScanAmdProcessor (
//
if (MaxBusRatio == 0) {
Cpu->FSBFrequency = 100000000; // 100 MHz like Intel part.
} else if (Cpu->ExtFamily == AMD_CPU_EXT_FAMILY_1AH) {
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, CoreFrequencyID); // No divisor for Family 1Ah
} else {
Cpu->FSBFrequency = DivU64x32 (Cpu->CPUFrequency, MaxBusRatio);
}
Expand Down

0 comments on commit 5c42665

Please sign in to comment.