From 363e100493ab744561021ac6ba23c73ec011b3c7 Mon Sep 17 00:00:00 2001 From: PerikiyoXD Date: Mon, 6 May 2024 17:55:37 +0200 Subject: [PATCH] Saving processor features in the processor control block Fixed correct AMD Family 25 model detection Fixed procedure for saving processor vendor name (previously corrupted) Added a debugging print of the processor identification --- sdk/xtdk/amd64/artypes.h | 7 +++++ sdk/xtdk/amd64/ketypes.h | 1 + sdk/xtdk/amd64/xtstruct.h | 1 + sdk/xtdk/i686/artypes.h | 7 +++++ sdk/xtdk/i686/ketypes.h | 1 + sdk/xtdk/i686/xtstruct.h | 1 + xtoskrnl/ar/amd64/procsup.c | 51 +++++++++++++++++++++---------------- xtoskrnl/ar/i686/procsup.c | 51 +++++++++++++++++++++---------------- 8 files changed, 76 insertions(+), 44 deletions(-) diff --git a/sdk/xtdk/amd64/artypes.h b/sdk/xtdk/amd64/artypes.h index d788e3f..0a66bd1 100644 --- a/sdk/xtdk/amd64/artypes.h +++ b/sdk/xtdk/amd64/artypes.h @@ -204,6 +204,13 @@ typedef struct _CPU_IDENTIFICATION UCHAR VendorName[13]; } CPU_IDENTIFICATION, *PCPU_IDENTIFICATION; +/* Processor features */ +typedef struct _CPU_FEATURES +{ + CPUID_FEATURES Ecx; + CPUID_FEATURES Edx; +} CPU_FEATURES, *PCPU_FEATURES; + /* CPUID registers */ typedef struct _CPUID_REGISTERS { diff --git a/sdk/xtdk/amd64/ketypes.h b/sdk/xtdk/amd64/ketypes.h index 4618b04..c76b2d1 100644 --- a/sdk/xtdk/amd64/ketypes.h +++ b/sdk/xtdk/amd64/ketypes.h @@ -498,6 +498,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK ULONG64 RspBase; ULONG_PTR SetMember; CPU_IDENTIFICATION CpuId; + CPU_FEATURES CpuFeatures; KPROCESSOR_STATE ProcessorState; KSPIN_LOCK_QUEUE LockQueue[MaximumLock]; KDPC_DATA DpcData[2]; diff --git a/sdk/xtdk/amd64/xtstruct.h b/sdk/xtdk/amd64/xtstruct.h index cee10a9..fad26b5 100644 --- a/sdk/xtdk/amd64/xtstruct.h +++ b/sdk/xtdk/amd64/xtstruct.h @@ -21,6 +21,7 @@ typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE; /* Architecture-specific structures forward references */ typedef struct _CONTEXT CONTEXT, *PCONTEXT; typedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION; +typedef struct _CPU_FEATURES CPU_FEATURES, *PCPU_FEATURES; typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS; typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE; typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA; diff --git a/sdk/xtdk/i686/artypes.h b/sdk/xtdk/i686/artypes.h index 4059286..21d8bac 100644 --- a/sdk/xtdk/i686/artypes.h +++ b/sdk/xtdk/i686/artypes.h @@ -155,6 +155,13 @@ typedef struct _CPU_IDENTIFICATION UCHAR VendorName[13]; } CPU_IDENTIFICATION, *PCPU_IDENTIFICATION; +/* Processor features */ +typedef struct _CPU_FEATURES +{ + CPUID_FEATURES Ecx; + CPUID_FEATURES Edx; +} CPU_FEATURES, *PCPU_FEATURES; + /* CPUID registers */ typedef struct _CPUID_REGISTERS { diff --git a/sdk/xtdk/i686/ketypes.h b/sdk/xtdk/i686/ketypes.h index 602c831..a8cd90c 100644 --- a/sdk/xtdk/i686/ketypes.h +++ b/sdk/xtdk/i686/ketypes.h @@ -456,6 +456,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK UCHAR Number; ULONG_PTR SetMember; CPU_IDENTIFICATION CpuId; + CPU_FEATURES CpuFeatures; KPROCESSOR_STATE ProcessorState; KSPIN_LOCK_QUEUE LockQueue[MaximumLock]; ULONG_PTR MultiThreadProcessorSet; diff --git a/sdk/xtdk/i686/xtstruct.h b/sdk/xtdk/i686/xtstruct.h index a690cc1..30ef5e4 100644 --- a/sdk/xtdk/i686/xtstruct.h +++ b/sdk/xtdk/i686/xtstruct.h @@ -21,6 +21,7 @@ typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE; /* Architecture-specific structures forward references */ typedef struct _CONTEXT CONTEXT, *PCONTEXT; typedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION; +typedef struct _CPU_FEATURES CPU_FEATURES, *PCPU_FEATURES; typedef struct _CPUID_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS; typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE; typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT; diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.c index bdd8752..75c55eb 100644 --- a/xtoskrnl/ar/amd64/procsup.c +++ b/xtoskrnl/ar/amd64/procsup.c @@ -121,24 +121,22 @@ ArpIdentifyProcessor(VOID) PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; CPUID_SIGNATURE CpuSignature; - - /* Not fully implemented yet */ - UNIMPLEMENTED; + UINT32 VendorNameBytes[3]; /* Get current processor control block */ Prcb = KeGetCurrentProcessorControlBlock(); - /* Get CPU vendor by issueing CPUID instruction */ + /* Get CPU vendor by issuing CPUID instruction */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; ArCpuId(&CpuRegisters); - /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; - Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; - Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; - Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; - Prcb->CpuId.VendorName[12] = '\0'; + /* Store CPU vendor name in processor control block */ + RtlZeroMemory(&Prcb->CpuId.VendorName[0], 13); + VendorNameBytes[0] = CpuRegisters.Ebx; + VendorNameBytes[1] = CpuRegisters.Edx; + VendorNameBytes[2] = CpuRegisters.Ecx; + RtlCopyMemory(&Prcb->CpuId.VendorName[0], &VendorNameBytes[0], 12); /* Get CPU features */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); @@ -151,19 +149,28 @@ ArpIdentifyProcessor(VOID) Prcb->CpuId.Model = CpuSignature.Model; Prcb->CpuId.Stepping = CpuSignature.Stepping; - /* CPU vendor specific quirks */ - if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) + /* Set CPU vendor on processor control block by comparing known vendor names, + * 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; - 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); } } - 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) { Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; @@ -174,13 +181,13 @@ ArpIdentifyProcessor(VOID) 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); } /** diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.c index 8fd0e67..ebf8d71 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.c @@ -116,24 +116,22 @@ ArpIdentifyProcessor(VOID) PKPROCESSOR_CONTROL_BLOCK Prcb; CPUID_REGISTERS CpuRegisters; CPUID_SIGNATURE CpuSignature; - - /* Not fully implemented yet */ - UNIMPLEMENTED; + UINT32 VendorNameBytes[3]; /* Get current processor control block */ Prcb = KeGetCurrentProcessorControlBlock(); - /* Get CPU vendor by issueing CPUID instruction */ + /* Get CPU vendor by issuing CPUID instruction */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); CpuRegisters.Leaf = CPUID_GET_VENDOR_STRING; ArCpuId(&CpuRegisters); - /* Store CPU vendor in processor control block */ - Prcb->CpuId.Vendor = CpuRegisters.Ebx; - Prcb->CpuId.VendorName[0] = CpuRegisters.Ebx; - Prcb->CpuId.VendorName[4] = CpuRegisters.Edx; - Prcb->CpuId.VendorName[8] = CpuRegisters.Ecx; - Prcb->CpuId.VendorName[12] = '\0'; + /* Store CPU vendor name in processor control block */ + RtlZeroMemory(&Prcb->CpuId.VendorName[0], 13); + VendorNameBytes[0] = CpuRegisters.Ebx; + VendorNameBytes[1] = CpuRegisters.Edx; + VendorNameBytes[2] = CpuRegisters.Ecx; + RtlCopyMemory(&Prcb->CpuId.VendorName[0], &VendorNameBytes[0], 12); /* Get CPU features */ RtlZeroMemory(&CpuRegisters, sizeof(CPUID_REGISTERS)); @@ -146,19 +144,28 @@ ArpIdentifyProcessor(VOID) Prcb->CpuId.Model = CpuSignature.Model; Prcb->CpuId.Stepping = CpuSignature.Stepping; - /* CPU vendor specific quirks */ - if(Prcb->CpuId.Vendor == CPU_VENDOR_AMD) + /* Set CPU vendor on processor control block by comparing known vendor names, + * 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; - 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); } } - 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) { Prcb->CpuId.Family = Prcb->CpuId.Family + CpuSignature.ExtendedFamily; @@ -169,13 +176,13 @@ ArpIdentifyProcessor(VOID) 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); } /** -- 2.45.1