Complete ArpIdentifyProcessor unimplemented logic

- Fixes CPUID VendorName
- Fixes Model on AMD Family 0x19
- Stores raw CPU features to PRCB
This commit is contained in:
Pedro Valadés 2024-05-06 17:09:49 +02:00
parent bde7f644ba
commit b8fa862066
2 changed files with 58 additions and 44 deletions

View File

@ -121,24 +121,22 @@ ArpIdentifyProcessor(VOID)
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature; CPUID_SIGNATURE CpuSignature;
UINT32 VendorNameBytes[3];
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */ /* Get current processor control block */
Prcb = KeGetCurrentProcessorControlBlock(); Prcb = KeGetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issuing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor name in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx; RtlZeroMemory(&Prcb->CpuId.VendorName[0], 13);
Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; VendorNameBytes[0] = CpuRegisters.Ebx;
Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; VendorNameBytes[1] = CpuRegisters.Edx;
Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; VendorNameBytes[2] = CpuRegisters.Ecx;
Prcb->CpuId.VendorName[12] = '\0'; RtlCopyMemory(&Prcb->CpuId.VendorName[0], &VendorNameBytes[0], 12);
/* Get CPU features */ /* Get CPU features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
@ -151,19 +149,28 @@ ArpIdentifyProcessor(VOID)
Prcb->CpuId.Model = CpuSignature.Model; Prcb->CpuId.Model = CpuSignature.Model;
Prcb->CpuId.Stepping = CpuSignature.Stepping; Prcb->CpuId.Stepping = CpuSignature.Stepping;
/* CPU vendor specific quirks */ /* Set CPU vendor on processor control block by comparing known vendor names,
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) * along with specific CPU family and model detection quirks */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
if(RtlCompareMemory(&VendorNameBytes[0], "AuthenticAMD", 12) == 12)
{ {
/* AMD CPU */ Prcb->CpuId.Vendor = CPU_VENDOR_AMD;
/* AMD CPU specific family and model handling */
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
if(Prcb->CpuId.Model == 0xF)
// https://en.wikichip.org/wiki/amd/cpuid - AMD CPUID
if(Prcb->CpuId.Model == 0xF || Prcb->CpuId.Family >= 0x19)
{ {
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL) else if(RtlCompareMemory(&VendorNameBytes[0], "GenuineIntel", 12) == 12)
{ {
/* Intel CPU */ Prcb->CpuId.Vendor = CPU_VENDOR_INTEL;
/* Intel CPU specific family and model handling */
if(Prcb->CpuId.Family == 0xF) if(Prcb->CpuId.Family == 0xF)
{ {
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
@ -174,13 +181,13 @@ ArpIdentifyProcessor(VOID)
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else
{
/* Unknown CPU vendor */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
}
/* TODO: Store a list of CPU features in processor control block */ /* Store CPU features in processor control block */
RtlZeroMemory(&Prcb->CpuFeatures, sizeof(CPU_FEATURES));
RtlCopyMemory(&Prcb->CpuFeatures.Ecx, &CpuRegisters.Ecx, sizeof(UINT32));
RtlCopyMemory(&Prcb->CpuFeatures.Edx, &CpuRegisters.Edx, sizeof(UINT32));
KeDbgPrint(L"CPU %hhu: %s %hu.%hu.%hu\n", Prcb->Number, Prcb->CpuId.VendorName, Prcb->CpuId.Family, Prcb->CpuId.Model, Prcb->CpuId.Stepping);
} }
/** /**

View File

@ -116,24 +116,22 @@ ArpIdentifyProcessor(VOID)
PKPROCESSOR_CONTROL_BLOCK Prcb; PKPROCESSOR_CONTROL_BLOCK Prcb;
CPUID_REGISTERS CpuRegisters; CPUID_REGISTERS CpuRegisters;
CPUID_SIGNATURE CpuSignature; CPUID_SIGNATURE CpuSignature;
UINT32 VendorNameBytes[3];
/* Not fully implemented yet */
UNIMPLEMENTED;
/* Get current processor control block */ /* Get current processor control block */
Prcb = KeGetCurrentProcessorControlBlock(); Prcb = KeGetCurrentProcessorControlBlock();
/* Get CPU vendor by issueing CPUID instruction */ /* Get CPU vendor by issuing CPUID instruction */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING;
ArCpuId(&CpuRegisters); ArCpuId(&CpuRegisters);
/* Store CPU vendor in processor control block */ /* Store CPU vendor name in processor control block */
Prcb->CpuId.Vendor = CpuRegisters.Ebx; RtlZeroMemory(&Prcb->CpuId.VendorName[0], 13);
Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; VendorNameBytes[0] = CpuRegisters.Ebx;
Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; VendorNameBytes[1] = CpuRegisters.Edx;
Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; VendorNameBytes[2] = CpuRegisters.Ecx;
Prcb->CpuId.VendorName[12] = '\0'; RtlCopyMemory(&Prcb->CpuId.VendorName[0], &VendorNameBytes[0], 12);
/* Get CPU features */ /* Get CPU features */
RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS));
@ -146,19 +144,28 @@ ArpIdentifyProcessor(VOID)
Prcb->CpuId.Model = CpuSignature.Model; Prcb->CpuId.Model = CpuSignature.Model;
Prcb->CpuId.Stepping = CpuSignature.Stepping; Prcb->CpuId.Stepping = CpuSignature.Stepping;
/* CPU vendor specific quirks */ /* Set CPU vendor on processor control block by comparing known vendor names,
if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) * along with specific CPU family and model detection quirks */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
if(RtlCompareMemory(&VendorNameBytes[0], "AuthenticAMD", 12) == 12)
{ {
/* AMD CPU */ Prcb->CpuId.Vendor = CPU_VENDOR_AMD;
/* AMD CPU specific family and model handling */
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
if(Prcb->CpuId.Model == 0xF)
// https://en.wikichip.org/wiki/amd/cpuid - AMD CPUID
if(Prcb->CpuId.Model == 0xF || Prcb->CpuId.Family >= 0x19)
{ {
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else if(Prcb->CpuId.Vendor == CPU_VENDOR_INTEL) else if(RtlCompareMemory(&VendorNameBytes[0], "GenuineIntel", 12) == 12)
{ {
/* Intel CPU */ Prcb->CpuId.Vendor = CPU_VENDOR_INTEL;
/* Intel CPU specific family and model handling */
if(Prcb->CpuId.Family == 0xF) if(Prcb->CpuId.Family == 0xF)
{ {
Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily;
@ -169,13 +176,13 @@ ArpIdentifyProcessor(VOID)
Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4); Prcb->CpuId.Model = Prcb->CpuId.Model + (CpuSignature.ExtendedModel << 4);
} }
} }
else
{
/* Unknown CPU vendor */
Prcb->CpuId.Vendor = CPU_VENDOR_UNKNOWN;
}
/* TODO: Store a list of CPU features in processor control block */ /* Store CPU features in processor control block */
RtlZeroMemory(&Prcb->CpuFeatures, sizeof(CPU_FEATURES));
RtlCopyMemory(&Prcb->CpuFeatures.Ecx, &CpuRegisters.Ecx, sizeof(UINT32));
RtlCopyMemory(&Prcb->CpuFeatures.Edx, &CpuRegisters.Edx, sizeof(UINT32));
KeDbgPrint(L"CPU %hhu: %s %hu.%hu.%hu\n", Prcb->Number, Prcb->CpuId.VendorName, Prcb->CpuId.Family, Prcb->CpuId.Model, Prcb->CpuId.Stepping);
} }
/** /**