1 | /********************************************************************** <BR>
|
---|
2 | This file is part of Crack dot Com's free source code release of
|
---|
3 | Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
|
---|
4 | information about compiling & licensing issues visit this URL</a>
|
---|
5 | <PRE> If that doesn't help, contact Jonathan Clark at
|
---|
6 | golgotha_source@usa.net (Subject should have "GOLG" in it)
|
---|
7 | ***********************************************************************/
|
---|
8 |
|
---|
9 | #include "device/processor.hh"
|
---|
10 | #include <string.h>
|
---|
11 |
|
---|
12 | w32 x86_can_do_cpuid()
|
---|
13 | {
|
---|
14 | w32 result;
|
---|
15 |
|
---|
16 | _asm
|
---|
17 | {
|
---|
18 | pushfd //save EFLAGS
|
---|
19 |
|
---|
20 | pop eax
|
---|
21 | test eax,0x00200000 //check ID bit (bit 21)
|
---|
22 | jz set_21 //bit 21 is not set, so jump to set_21
|
---|
23 | and eax,0xffdfffff //clear bit 21
|
---|
24 | push eax //save new value in register
|
---|
25 |
|
---|
26 | popfd //store new value in flags
|
---|
27 | pushfd
|
---|
28 |
|
---|
29 | pop eax
|
---|
30 | test eax,0x00200000 //check ID bit
|
---|
31 |
|
---|
32 | jnz cpu_id_not_ok //if bit 21 isnt clear,then jump to cpu_id_not_ok
|
---|
33 |
|
---|
34 | mov dword ptr [result],1 // return 1
|
---|
35 | jmp done
|
---|
36 |
|
---|
37 | set_21:
|
---|
38 | or eax,0x00200000 //set bit 21
|
---|
39 | push eax //store new value
|
---|
40 |
|
---|
41 | popfd //store new value in EFLAGS
|
---|
42 | pushfd
|
---|
43 |
|
---|
44 | pop eax
|
---|
45 | test eax,0x00200000 //if bit 21 is on
|
---|
46 | jz cpu_id_not_ok //then jump to cpu_id_ok
|
---|
47 |
|
---|
48 | mov dword ptr [result],1 // return 1
|
---|
49 | jmp done
|
---|
50 |
|
---|
51 | cpu_id_not_ok:
|
---|
52 |
|
---|
53 | mov dword ptr [result],0 //CPUID inst is not supported
|
---|
54 |
|
---|
55 | done:
|
---|
56 | }
|
---|
57 |
|
---|
58 | return result;
|
---|
59 | }
|
---|
60 |
|
---|
61 | w32 x86_get_cpu_type()
|
---|
62 | {
|
---|
63 | char name[32];
|
---|
64 |
|
---|
65 | _asm
|
---|
66 | {
|
---|
67 | mov eax,0
|
---|
68 |
|
---|
69 | __emit 0x0F //cpuid
|
---|
70 | __emit 0xA2
|
---|
71 |
|
---|
72 | //store it
|
---|
73 | mov byte ptr [name],bl
|
---|
74 | mov byte ptr [name+1],bh
|
---|
75 |
|
---|
76 | ror ebx, 16
|
---|
77 |
|
---|
78 | mov byte ptr [name+2],bl
|
---|
79 | mov byte ptr [name+3],bh
|
---|
80 | mov byte ptr [name+4],dl
|
---|
81 | mov byte ptr [name+5],dh
|
---|
82 |
|
---|
83 | ror edx,16
|
---|
84 |
|
---|
85 | mov byte ptr [name+6],dl
|
---|
86 | mov byte ptr [name+7],dh
|
---|
87 | mov byte ptr [name+8],cl
|
---|
88 | mov byte ptr [name+9],ch
|
---|
89 |
|
---|
90 | ror ecx,16
|
---|
91 |
|
---|
92 | mov byte ptr [name+10],cl
|
---|
93 | mov byte ptr [name+11],ch
|
---|
94 | mov byte ptr [name+12],0
|
---|
95 | }
|
---|
96 |
|
---|
97 | if (!strcmp(name,"AuthenticAMD") || !strcmp(name,"CentaurHauls"))
|
---|
98 | return i4_cpu_info_struct::AMD_X86;
|
---|
99 | else
|
---|
100 | if (!strcmp(name,"GenuineIntel"))
|
---|
101 | return i4_cpu_info_struct::INTEL_X86;
|
---|
102 | else
|
---|
103 | return i4_cpu_info_struct::UNKNOWN_X86;
|
---|
104 | }
|
---|
105 |
|
---|
106 | w32 x86_get_cpu_flags(w32 cpu_type)
|
---|
107 | {
|
---|
108 | unsigned int processor_sig;
|
---|
109 | unsigned int extended_flags;
|
---|
110 |
|
---|
111 | _asm
|
---|
112 | {
|
---|
113 | mov eax,0x80000001 //the cpuid function we're requesting
|
---|
114 |
|
---|
115 | __emit 0x0F
|
---|
116 | __emit 0xA2 //cpuid
|
---|
117 |
|
---|
118 | mov dword ptr [processor_sig],eax
|
---|
119 | mov dword ptr [extended_flags],edx
|
---|
120 | }
|
---|
121 |
|
---|
122 | //perhaps check the processor signature too?
|
---|
123 |
|
---|
124 | w32 flags = 0;
|
---|
125 |
|
---|
126 | if (cpu_type==i4_cpu_info_struct::AMD_X86)
|
---|
127 | {
|
---|
128 | if (extended_flags & (1<<4))
|
---|
129 | flags |= i4_cpu_info_struct::RDTSC;
|
---|
130 |
|
---|
131 | if (extended_flags & (23<<31))
|
---|
132 | flags |= i4_cpu_info_struct::MMX;
|
---|
133 |
|
---|
134 | if (extended_flags & (1<<31))
|
---|
135 | flags |= i4_cpu_info_struct::AMD3D;
|
---|
136 | }
|
---|
137 | else
|
---|
138 | if (cpu_type==i4_cpu_info_struct::INTEL_X86)
|
---|
139 | {
|
---|
140 | if (extended_flags & (1<<4))
|
---|
141 | flags |= i4_cpu_info_struct::RDTSC;
|
---|
142 |
|
---|
143 | /*
|
---|
144 | if (extended_flags & (23<<31))
|
---|
145 | flags |= i4_cpu_info_struct::MMX;
|
---|
146 |
|
---|
147 | if (extended_flags & (1<<31))
|
---|
148 | flags |= i4_cpu_info_struct::AMD3D;
|
---|
149 | */
|
---|
150 | }
|
---|
151 |
|
---|
152 | return flags;
|
---|
153 | }
|
---|
154 |
|
---|
155 | void i4_win32_get_cpu_info(i4_cpu_info_struct *s)
|
---|
156 | {
|
---|
157 | _asm pusha
|
---|
158 |
|
---|
159 | if (!x86_can_do_cpuid())
|
---|
160 | {
|
---|
161 | s->cpu_type = i4_cpu_info_struct::UNKNOWN_X86;
|
---|
162 | s->cpu_flags = 0;
|
---|
163 | }
|
---|
164 | else
|
---|
165 | {
|
---|
166 | s->cpu_type = x86_get_cpu_type();
|
---|
167 | s->cpu_flags = x86_get_cpu_flags(s->cpu_type);
|
---|
168 | }
|
---|
169 | _asm popa
|
---|
170 | }
|
---|