Saving processor features in the processor control block #9
@ -204,6 +204,13 @@ typedef struct _CPU_IDENTIFICATION
|
|||||||
UCHAR VendorName[13];
|
UCHAR VendorName[13];
|
||||||
} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
||||||
|
|
||||||
|
/* Processor features */
|
||||||
|
typedef struct _CPU_FEATURES
|
||||||
|
{
|
||||||
|
CPUID_FEATURES Ecx;
|
||||||
|
CPUID_FEATURES Edx;
|
||||||
|
} CPU_FEATURES, *PCPU_FEATURES;
|
||||||
|
|
||||||
/* CPUID registers */
|
/* CPUID registers */
|
||||||
typedef struct _CPUID_REGISTERS
|
typedef struct _CPUID_REGISTERS
|
||||||
{
|
{
|
||||||
|
@ -498,6 +498,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
ULONG64 RspBase;
|
ULONG64 RspBase;
|
||||||
ULONG_PTR SetMember;
|
ULONG_PTR SetMember;
|
||||||
CPU_IDENTIFICATION CpuId;
|
CPU_IDENTIFICATION CpuId;
|
||||||
|
CPU_FEATURES CpuFeatures;
|
||||||
KPROCESSOR_STATE ProcessorState;
|
KPROCESSOR_STATE ProcessorState;
|
||||||
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
||||||
KDPC_DATA DpcData[2];
|
KDPC_DATA DpcData[2];
|
||||||
|
@ -21,6 +21,7 @@ typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;
|
|||||||
/* Architecture-specific structures forward references */
|
/* Architecture-specific structures forward references */
|
||||||
typedef struct _CONTEXT CONTEXT, *PCONTEXT;
|
typedef struct _CONTEXT CONTEXT, *PCONTEXT;
|
||||||
typedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
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_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
|
||||||
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
||||||
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
typedef struct _FLOATING_SAVE_AREA FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
|
||||||
|
@ -155,6 +155,13 @@ typedef struct _CPU_IDENTIFICATION
|
|||||||
UCHAR VendorName[13];
|
UCHAR VendorName[13];
|
||||||
} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
} CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
||||||
|
|
||||||
|
/* Processor features */
|
||||||
|
typedef struct _CPU_FEATURES
|
||||||
|
{
|
||||||
|
CPUID_FEATURES Ecx;
|
||||||
|
CPUID_FEATURES Edx;
|
||||||
|
} CPU_FEATURES, *PCPU_FEATURES;
|
||||||
|
|
||||||
/* CPUID registers */
|
/* CPUID registers */
|
||||||
typedef struct _CPUID_REGISTERS
|
typedef struct _CPUID_REGISTERS
|
||||||
{
|
{
|
||||||
|
@ -456,6 +456,7 @@ typedef struct _KPROCESSOR_CONTROL_BLOCK
|
|||||||
UCHAR Number;
|
UCHAR Number;
|
||||||
ULONG_PTR SetMember;
|
ULONG_PTR SetMember;
|
||||||
CPU_IDENTIFICATION CpuId;
|
CPU_IDENTIFICATION CpuId;
|
||||||
|
CPU_FEATURES CpuFeatures;
|
||||||
KPROCESSOR_STATE ProcessorState;
|
KPROCESSOR_STATE ProcessorState;
|
||||||
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
KSPIN_LOCK_QUEUE LockQueue[MaximumLock];
|
||||||
ULONG_PTR MultiThreadProcessorSet;
|
ULONG_PTR MultiThreadProcessorSet;
|
||||||
|
@ -21,6 +21,7 @@ typedef enum _PAGE_SIZE PAGE_SIZE, *PPAGE_SIZE;
|
|||||||
/* Architecture-specific structures forward references */
|
/* Architecture-specific structures forward references */
|
||||||
typedef struct _CONTEXT CONTEXT, *PCONTEXT;
|
typedef struct _CONTEXT CONTEXT, *PCONTEXT;
|
||||||
typedef struct _CPU_IDENTIFICATION CPU_IDENTIFICATION, *PCPU_IDENTIFICATION;
|
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_REGISTERS CPUID_REGISTERS, *PCPUID_REGISTERS;
|
||||||
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
typedef struct _CPUID_SIGNATURE CPUID_SIGNATURE, *PCPUID_SIGNATURE;
|
||||||
typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;
|
typedef struct _FN_SAVE_FORMAT FN_SAVE_FORMAT, *PFN_SAVE_FORMAT;
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user