Tuesday, September 27, 2011

Right use CPUID

Author:DiYhAcK

If want program of use cpuid command to be passed :

1.Judge SPU that whether hold out cpuid command
The way: 21st of eflags(ID) whether can change


Code:
BOOL __declspec(naked) IsCpuidValid()
{
  __asm
  {
    pushfd
    pop eax             //eax = eflags
    mov ebx, eax
    xor eax, 00200000h  //toggle bit 21, eflags.[ID]
    push eax
    popfd
    pushfd
    pop eax
    cmp eax, ebx
    jz NO_CPUID
    mov eax, 1
    ret
NO_CPUID:
    xor eax, eax
    ret
  }
}
2.If cpu hold out cpuid command, First judge whether hold out function num before use such cpuid function num.


Code:
    CPUID_ARGS ca;
    ca.eax = 0;
    cpuid32(&ca);
    char Vendor[13];
    *((PULONG)&Vendor[0]) = ca.ebx;
    *((PULONG)&Vendor[4]) = ca.edx;
    *((PULONG)&Vendor[8]) = ca.ecx;
    Vendor[12] = '\0';

    printf("CPU Vendor: %s\n", Vendor);
    printf("Max Standard function: 0x%08x\n", ca.eax);

    ca.eax = 0x80000000;
    cpuid32(&ca);

    printf("Max Extended function: 0x%08x\n", ca.eax);
3.Reference appropriate help standard of CPU manufacturer to use homologous function num

Code:
if(strcmp(Vendor, "GenuineIntel") == 0)
{
    //Reference IPM-241618
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else if(strcmp(Vendor, "AuthenticAMD") == 0)
{
    //Reference APM-25481
    if(ca.eax >= 0x80000004) //support brand string
    {
        char Brand[48];
        ca.eax = 0x80000002;
        cpuid32(&ca);
        *((PULONG)&Brand[0]) = ca.eax;
        *((PULONG)&Brand[4]) = ca.ebx;
        *((PULONG)&Brand[8]) = ca.ecx;
        *((PULONG)&Brand[12]) = ca.edx;

        ca.eax = 0x80000003;
        cpuid32(&ca);
        *((PULONG)&Brand[16]) = ca.eax;
        *((PULONG)&Brand[20]) = ca.ebx;
        *((PULONG)&Brand[24]) = ca.ecx;
        *((PULONG)&Brand[28]) = ca.edx;

        ca.eax = 0x80000004;
        cpuid32(&ca);
        *((PULONG)&Brand[32]) = ca.eax;
        *((PULONG)&Brand[36]) = ca.ebx;
        *((PULONG)&Brand[40]) = ca.ecx;
        *((PULONG)&Brand[44]) = ca.edx;

        printf("Brand: %s\n", Brand);
    }
}
else //if(...)
{
    //Reference help of other CPU manufacturer
}

No comments:

Post a Comment