cpuid.asm 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. ;//==========================================================================
  2. ;//
  3. ;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. ;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. ;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. ;// PURPOSE.
  7. ;//
  8. ;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
  9. ;//
  10. ;//--------------------------------------------------------------------------
  11. ;
  12. ; **-getCPUType
  13. ;
  14. ; This function will return a code indicating the type of the processor
  15. ; that is in the system. If the processor type is unknown the generic
  16. ; x86 (Intel 486) type is returned
  17. ;
  18. ; parts taken from intel's AP-485
  19. ;
  20. ;put checks for cmov and mmx support ????
  21. ;
  22. ; Assumptions:
  23. ; None
  24. ;
  25. ; Input:
  26. ; None
  27. ;
  28. ; Output:
  29. ; Code for CPU type returned. See cpuidlib.h for the supported
  30. ; types.
  31. ;
  32. .586
  33. .MODEL flat, SYSCALL, os_dos
  34. .DATA
  35. NAME x86cpuid
  36. PUBLIC getCPUType_
  37. PUBLIC _getCPUType
  38. CPU_ID MACRO
  39. db 0fh ; Hardcoded CPUID instruction
  40. db 0a2h
  41. ENDM
  42. ;see cpuidlib.h
  43. X86 EQU 0 ; /* 486, Pentium plain, or any other x86 compatible */
  44. PMMX EQU 1 ; /* Pentium with MMX */
  45. PPRO EQU 2 ; /* Pentium Pro */
  46. PII EQU 3 ; /* Pentium II */
  47. C6X86 EQU 4
  48. C6X86MX EQU 5
  49. AMDK63D EQU 6
  50. AMDK6 EQU 7
  51. AMDK5 EQU 8
  52. XMM EQU 11
  53. WMT EQU 12 ;/* Willamette */
  54. _486 EQU 4h
  55. PENT EQU 50h
  56. PENTMMX EQU 54h
  57. PENTPRO EQU 61h
  58. PENTII EQU 63h
  59. SIMD EQU 25
  60. AMD_K63D EQU 58h
  61. AMD_K6 EQU 56h
  62. AMD_K5 EQU 50h ; K5 has models 0 - 6
  63. _6X86 EQU 52h
  64. _6X86MX EQU 60h
  65. _vendor_id db "------------"
  66. intel_id db "GenuineIntel"
  67. amd_id db "AuthenticAMD"
  68. cyrix_id db "CyrixInstead"
  69. .CODE
  70. getCPUType_:
  71. _getCPUType:
  72. push esi ;safety sh*&
  73. push edi
  74. push ebp
  75. push ebx
  76. push ecx
  77. push edx
  78. ;------------------------------------------------
  79. ; Intel486 processor check
  80. ; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
  81. ; which indicates the presence of a processor with the CPUID
  82. ; instruction.
  83. ;------------------------------------------------
  84. check_80486:
  85. pushfd ; push original EFLAGS
  86. pop eax ; get original EFLAGS
  87. mov ebp,X86 ; rv
  88. mov ecx, eax ; save original EFLAGS
  89. xor eax, 200000h ; flip ID bit in EFLAGS
  90. push eax ; save new EFLAGS value on stack
  91. popfd ; replace current EFLAGS value
  92. pushfd ; get new EFLAGS
  93. pop eax ; store new EFLAGS in EAX
  94. xor eax, ecx ; can not toggle ID bit,
  95. je end_cpu_type486 ; processor=80486
  96. ;------------------------------------------------
  97. ; Execute CPUID instruction to not determine vendor, family,
  98. ; model, stepping and features. For the purpose of this
  99. ; code, only the initial set of CPUID information is saved.
  100. ;------------------------------------------------
  101. ; push ebx ; save registers
  102. ; push esi
  103. ; push edi
  104. ; push edx
  105. ; push ecx
  106. ; mov ebp,X86 ; rv
  107. mov eax, 0 ; set up for CPUID instruction
  108. CPU_ID ; get and save vendor ID
  109. mov DWORD PTR _vendor_id, ebx
  110. mov DWORD PTR _vendor_id[+4], edx
  111. mov DWORD PTR _vendor_id[+8], ecx
  112. cmp DWORD PTR intel_id, ebx
  113. jne IsProc_AMD
  114. cmp DWORD PTR intel_id[+4], edx
  115. jne end_cpuid_type
  116. cmp DWORD PTR intel_id[+8], ecx
  117. jne end_cpuid_type ; if not equal, not an Intel processor
  118. cmp eax, 1 ; make sure 1 is valid input for CPUID
  119. jl end_cpuid_type ; if not, jump to end
  120. mov eax, 1
  121. CPU_ID ; get family/model/stepping/features
  122. mov ebp,XMM ; assume PIII
  123. bt edx,SIMD ; check for SIMD support
  124. jnae end_cpuid_type
  125. SIMDContinue:
  126. shr eax, 4 ; isolate family and model
  127. mov ebp,PII ; assume PII
  128. and eax,0ffh ;mask out type and reserved
  129. nop
  130. cmp eax,PENTII
  131. jge end_cpuid_type
  132. mov ebp,PPRO
  133. cmp eax,PENTPRO
  134. je end_cpuid_type
  135. mov ebp,PMMX
  136. cmp eax,PENTMMX
  137. je end_cpuid_type
  138. mov ebp,X86
  139. cmp eax,PENT
  140. jge end_cpuid_type
  141. ; mov ebp,X86
  142. end_cpuid_type:
  143. mov eax,ebp
  144. ;remove these pops ???
  145. ; pop edi ; restore registers
  146. ; pop esi
  147. ; pop ebx
  148. ; pop edx
  149. ; pop ecx
  150. end_cpu_type:
  151. pop edx ;safety sh*&
  152. pop ecx
  153. pop ebx
  154. pop ebp
  155. pop edi
  156. pop esi
  157. ret
  158. end_cpu_type486:
  159. mov eax,ebp
  160. pop edx ;safety sh*&
  161. pop ecx
  162. pop ebx
  163. pop ebp
  164. pop edi
  165. pop esi
  166. ret
  167. ;------------------------------------------------
  168. IsProc_AMD:
  169. cmp DWORD PTR amd_id, ebx
  170. jne IsProc_CYRIX
  171. cmp DWORD PTR amd_id[+4], edx
  172. jne end_cpuid_type
  173. cmp DWORD PTR amd_id[+8], ecx
  174. jne end_cpuid_type ; if not equal, not an AMD processor
  175. cmp eax, 1 ; make sure 1 is valid input for CPUID
  176. jl end_cpuid_type ; if not, jump to end
  177. mov eax, 1
  178. CPU_ID ; get family/model/stepping/features
  179. shr eax, 4 ; isolate family and model
  180. mov ebp,AMDK63D
  181. and eax,0ffh ;mask out type and reserved
  182. nop
  183. cmp eax,AMD_K63D
  184. jge end_cpuid_type
  185. mov ebp,AMDK6
  186. nop
  187. cmp eax,AMD_K6
  188. jge end_cpuid_type
  189. mov ebp,X86
  190. nop
  191. cmp eax,AMD_K5
  192. jge end_cpuid_type
  193. mov ebp,X86
  194. jmp end_cpuid_type
  195. ;------------------------------------------------
  196. IsProc_CYRIX:
  197. cmp DWORD PTR cyrix_id, ebx
  198. jne end_cpuid_type
  199. cmp DWORD PTR cyrix_id[+4], edx
  200. jne end_cpuid_type
  201. cmp DWORD PTR cyrix_id[+8], ecx
  202. jne end_cpuid_type ; if not equal, not an CYRIX processor
  203. cmp eax, 1 ; make sure 1 is valid input for CPUID
  204. jl end_cpuid_type ; if not, jump to end
  205. mov eax, 1
  206. CPU_ID ; get family/model/stepping/features
  207. shr eax, 4 ; isolate family and model
  208. mov ebp,C6X86MX
  209. and eax,0ffh ;mask out type and reserved
  210. nop
  211. cmp eax,_6X86MX
  212. je end_cpuid_type
  213. mov ebp,X86
  214. jmp end_cpuid_type
  215. ;************************************************
  216. END