Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

221 lines
7.0 KiB

  1. ;* Procdi.asm - Processor Identification routines
  2. ;*
  3. ;* (C) Copyright Microsoft Corp., 1995
  4. ;*
  5. ;* Processor ID
  6. ;*
  7. ;* Origin:
  8. ;*
  9. ;* Change history:
  10. ;*
  11. ;* Date Who Description
  12. ;* --------- --------- -------------------------------------------------
  13. ;* 12-Oct-95 MikeG Created
  14. ;*
  15. .386p
  16. .387
  17. .model flat
  18. ;************************** Include Files ************************
  19. ; include winbase.inc
  20. ; include winerror.inc
  21. ; include kernel32.inc
  22. ; include segs.inc
  23. ; include regstr.inc
  24. ;******************** Data Declerations **************************
  25. .data
  26. _DATA SEGMENT
  27. CPU_ID macro
  28. db 0fh, 0a2h
  29. endm
  30. NONE equ 0
  31. PRESENT equ 1
  32. Nx586 equ 5
  33. UNKNOWN equ 0
  34. _nxcpu db NONE ;default to none
  35. _cputype db UNKNOWN ;default to unknown
  36. _cpuid_flag db NONE ;default to no CPUID
  37. _vendor_id db "************"
  38. _cpu_signature dd 0
  39. _features_ecx dd 0
  40. _features_edx dd 0
  41. _features_ebx dd 0
  42. NexGen_id db "NexGenDriven"
  43. ;*********************** Prototypes ******************************
  44. ;************************** Code *********************************
  45. .code
  46. _TEXT SEGMENT
  47. ;==========================================================================
  48. ; _get_nxcpu_type
  49. ; This routine identifies NexGen's processor type in following steps:
  50. ;
  51. ; if (no AC flag) { //current Nx586 does not support AC flag
  52. ; set ZF=1;
  53. ; execute DIV to result a none zero value;
  54. ; if (ZF=0) { //ZF is changed
  55. ; not a NexGen processor;
  56. ; exit;
  57. ; } else { //Nx586 does not change ZF on DIV instruction
  58. ; if (ID bit not writeable) {
  59. ; CPU is Nx586 with no CPUID support
  60. ; } else { //Nx586 with CPUID support
  61. ; execute CPUID instruction;
  62. ; save CPU information;
  63. ; }
  64. ; }
  65. ; } else {
  66. ; if (ID bit not writeable) {
  67. ; not a NexGen processor;
  68. ; } else { //NexGen future processors support CPUID
  69. ; execute CPUID instruction;
  70. ; save CPU information;
  71. ; }
  72. ; }
  73. ;
  74. ;==========================================================================
  75. get_nxcpu_type proc C cdecl:DWORD
  76. push ebx
  77. push esi
  78. push edi
  79. mov byte ptr _nxcpu,PRESENT ; default to present
  80. ; test AC bit on EFLAGS register
  81. mov bx,sp ; save the current stack pointer
  82. and sp,not 3 ; align the stack to avoid AC fault
  83. pushfd ;
  84. pop eax ; get the original EFLAGS
  85. mov ecx,eax ; save original flag
  86. xor eax,40000h ; flip AC bit in EFLAGS
  87. push eax ; save for EFLAGS
  88. popfd ; copy it to EFLAGS
  89. pushfd ;
  90. pop eax ; get the new EFLAGS value
  91. mov sp,bx ; restore stack pointer
  92. xor eax,ecx ; if the AC bit is unchanged
  93. je test_zf ; goto second step
  94. jmp nx_future_cpu
  95. test_zf:
  96. ; test ZF on DIV instruction
  97. mov ax,5555h ; init AX with a non-zero value
  98. xor dx,dx ; set ZF=1
  99. mov cx,2
  100. div cx ; Nx586 processor does not modify ZF on DIV
  101. jnz not_nx_cpu ; not a NexGen processor if ZF=0 (modified)
  102. test_cpuid:
  103. ; test if CPUID instruction is available
  104. ; new Nx586 or future CPU supports CPUID instruction
  105. pushfd ; get EFLAGs
  106. pop eax
  107. mov ecx,eax ; save it
  108. xor eax,200000h ; modify ID bit
  109. push eax
  110. popfd ; save it in new EFLAGS
  111. pushfd ; get new EFLAGS
  112. pop eax ;
  113. xor eax,ecx ; is ID bit changed?
  114. jnz cpuid_present ; yes
  115. mov byte ptr _cputype,Nx586 ; no, current Nx586
  116. mov eax,1 ; set return code == true
  117. jz cpuid_exit ; stop testing
  118. nx_future_cpu:
  119. ; all NexGen's future processors feature a CPUID instruction
  120. mov eax,ecx ; get original EFLAGS
  121. xor eax,200000h ; modify ID bit
  122. push eax
  123. popfd ; save it in new EFLAGS
  124. pushfd ; get new EFLAGS
  125. pop eax ;
  126. xor eax,ecx ; is ID bit changed?
  127. jz not_nx_cpu ; no, not a NexGen processor
  128. cpuid_present:
  129. ; execute CPUID instruction to get vendor name, stepping and feature info
  130. xor eax,eax
  131. CPU_ID
  132. mov dword ptr _vendor_id,ebx
  133. mov dword ptr _vendor_id[+4],edx
  134. mov dword ptr _vendor_id[+8],ecx
  135. mov bx,ds
  136. mov es,bx
  137. mov esi,offset _vendor_id
  138. mov edi,offset NexGen_id
  139. mov cx,12
  140. cld
  141. repe cmpsb ; compare vendor ID string
  142. jne not_nx_cpu
  143. mov byte ptr _cpuid_flag,PRESENT
  144. cmp eax,1 ; check highest level
  145. jl cpuid_exit
  146. mov eax,1
  147. CPU_ID
  148. mov _cpu_signature,eax
  149. mov _features_ecx,ecx
  150. mov _features_edx,edx
  151. mov _features_ebx,ebx
  152. shr eax,8
  153. and al,0fh
  154. mov _cputype,al
  155. jmp cpuid_exit
  156. not_nx_cpu:
  157. mov byte ptr _nxcpu,NONE
  158. xor eax,eax
  159. cpuid_exit:
  160. pop edi
  161. pop esi
  162. pop ebx
  163. ret
  164. get_nxcpu_type endp
  165. ;**************************************************************************
  166. ; Function: int is_cyrix ()
  167. ;
  168. ; Purpose: Determine if Cyrix CPU is present
  169. ; Technique: Cyrix CPUs do not change flags where flags change
  170. ; in an undefined manner on other CPUs
  171. ; Inputs: none
  172. ; Output: ax == 1 Cyrix present, 0 if not
  173. ;**************************************************************************
  174. is_cyrix proc C __cdecl:WORD
  175. .486
  176. push bx
  177. xor ax, ax ; clear ax
  178. sahf ; clear flags, bit 1 is always 1 in flags
  179. mov ax, 5
  180. mov bx, 2
  181. div bl ; do an operation that does not change flags
  182. lahf ; get flags
  183. cmp ah, 2 ; check for change in flags
  184. jne not_cyrix ; flags changed not Cyrix
  185. mov ax, 1 ; TRUE Cyrix CPU
  186. jmp done
  187. not_cyrix:
  188. mov ax, 0 ; FALSE NON-Cyrix CPU
  189. done:
  190. pop bx
  191. ret
  192. is_cyrix endp
  193. _TEXT ends
  194. end