/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at golgotha_source@usa.net (Subject should have "GOLG" in it) ***********************************************************************/ #include "device/processor.hh" #includew32 x86_can_do_cpuid() { w32 result; _asm { pushfd //save EFLAGS pop eax test eax,0x00200000 //check ID bit (bit 21) jz set_21 //bit 21 is not set, so jump to set_21 and eax,0xffdfffff //clear bit 21 push eax //save new value in register popfd //store new value in flags pushfd pop eax test eax,0x00200000 //check ID bit jnz cpu_id_not_ok //if bit 21 isnt clear,then jump to cpu_id_not_ok mov dword ptr [result],1 // return 1 jmp done set_21: or eax,0x00200000 //set bit 21 push eax //store new value popfd //store new value in EFLAGS pushfd pop eax test eax,0x00200000 //if bit 21 is on jz cpu_id_not_ok //then jump to cpu_id_ok mov dword ptr [result],1 // return 1 jmp done cpu_id_not_ok: mov dword ptr [result],0 //CPUID inst is not supported done: } return result; } w32 x86_get_cpu_type() { char name[32]; _asm { mov eax,0 __emit 0x0F //cpuid __emit 0xA2 //store it mov byte ptr [name],bl mov byte ptr [name+1],bh ror ebx, 16 mov byte ptr [name+2],bl mov byte ptr [name+3],bh mov byte ptr [name+4],dl mov byte ptr [name+5],dh ror edx,16 mov byte ptr [name+6],dl mov byte ptr [name+7],dh mov byte ptr [name+8],cl mov byte ptr [name+9],ch ror ecx,16 mov byte ptr [name+10],cl mov byte ptr [name+11],ch mov byte ptr [name+12],0 } if (!strcmp(name,"AuthenticAMD") || !strcmp(name,"CentaurHauls")) return i4_cpu_info_struct::AMD_X86; else if (!strcmp(name,"GenuineIntel")) return i4_cpu_info_struct::INTEL_X86; else return i4_cpu_info_struct::UNKNOWN_X86; } w32 x86_get_cpu_flags(w32 cpu_type) { unsigned int processor_sig; unsigned int extended_flags; _asm { mov eax,0x80000001 //the cpuid function we're requesting __emit 0x0F __emit 0xA2 //cpuid mov dword ptr [processor_sig],eax mov dword ptr [extended_flags],edx } //perhaps check the processor signature too? w32 flags = 0; if (cpu_type==i4_cpu_info_struct::AMD_X86) { if (extended_flags & (1<<4)) flags |= i4_cpu_info_struct::RDTSC; if (extended_flags & (23<<31)) flags |= i4_cpu_info_struct::MMX; if (extended_flags & (1<<31)) flags |= i4_cpu_info_struct::AMD3D; } else if (cpu_type==i4_cpu_info_struct::INTEL_X86) { if (extended_flags & (1<<4)) flags |= i4_cpu_info_struct::RDTSC; /* if (extended_flags & (23<<31)) flags |= i4_cpu_info_struct::MMX; if (extended_flags & (1<<31)) flags |= i4_cpu_info_struct::AMD3D; */ } return flags; } void i4_win32_get_cpu_info(i4_cpu_info_struct *s) { _asm pusha if (!x86_can_do_cpuid()) { s->cpu_type = i4_cpu_info_struct::UNKNOWN_X86; s->cpu_flags = 0; } else { s->cpu_type = x86_get_cpu_type(); s->cpu_flags = x86_get_cpu_flags(s->cpu_type); } _asm popa }