Leaked source code of windows server 2003
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.

252 lines
6.4 KiB

  1. title "Processor type and stepping detection"
  2. ;++
  3. ;
  4. ; Copyright (c) 1989 Microsoft Corporation
  5. ;
  6. ; Module Name:
  7. ;
  8. ; cpu.asm
  9. ;
  10. ; Abstract:
  11. ;
  12. ; This module implements the assembley code necessary to determine
  13. ; cpu type and stepping information.
  14. ;
  15. ; Author:
  16. ;
  17. ; Shie-Lin Tzong (shielint) 28-Oct-1991.
  18. ;
  19. ; Environment:
  20. ;
  21. ; 80x86
  22. ;
  23. ; Revision History:
  24. ;
  25. ;--
  26. .586p
  27. .xlist
  28. include mac386.inc
  29. include callconv.inc
  30. .list
  31. _TEXT SEGMENT DWORD PUBLIC 'CODE'
  32. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  33. CR0_AM equ 40000h
  34. EFLAGS_AC equ 40000h
  35. subttl "Is386"
  36. ;++
  37. ;
  38. ; BOOLEAN
  39. ; BlIs386(
  40. ; VOID
  41. ; )
  42. ;
  43. ; Routine Description:
  44. ;
  45. ; This function determines whether the processor we're running on
  46. ; is a 386. If not a 386, it is assumed that the processor is
  47. ; a 486 or greater.
  48. ;
  49. ; Arguments:
  50. ;
  51. ; None.
  52. ;
  53. ; Return Value:
  54. ;
  55. ; (al) = 1 - processor is a 386
  56. ; (al) = 0 - processor is a 486 or greater.
  57. ;
  58. ;--
  59. public _BlIs386@0
  60. _BlIs386@0 proc
  61. mov eax,cr0
  62. push eax ; save current cr0
  63. and eax,not CR0_AM ; mask out alignment check bit
  64. mov cr0,eax ; disable alignment check
  65. pushfd ; save flags
  66. pushfd ; turn on alignment check bit in
  67. or dword ptr [esp],EFLAGS_AC ; a copy of the flags register
  68. popfd ; and try to load flags
  69. pushfd
  70. pop ecx ; get new flags into ecx
  71. popfd ; restore original flags
  72. pop eax ; restore original cr0
  73. mov cr0,eax
  74. xor al,al ; prepare for return, assume not 386
  75. and ecx,EFLAGS_AC ; did AC bit get set?
  76. jnz short @f ; yes, we don't have a 386
  77. inc al ; we have a 386
  78. @@: ret
  79. _BlIs386@0 endp
  80. subttl "IsCpuidPresent"
  81. ;++
  82. ;
  83. ; BOOLEAN
  84. ; BlIsCpuidPresent(
  85. ; VOID
  86. ; )
  87. ;
  88. ; Routine Description:
  89. ;
  90. ; If bit 21 of the EFLAGS register is writable, CPUID is supported on
  91. ; this processor. If not writable, CPUID is not supported.
  92. ;
  93. ; Note: It is expected that this routine is "locked" onto a single
  94. ; processor when run.
  95. ;
  96. ; Arguments:
  97. ;
  98. ; None.
  99. ;
  100. ; Return Value:
  101. ;
  102. ; TRUE if CPUID is supported,
  103. ; FALSE otherwise.
  104. ;
  105. ;--
  106. EFLAGS_ID equ 200000h ; bit 21
  107. cPublicProc _BlIsCpuidPresent ,0
  108. pushfd ; save EFLAGS
  109. pop ecx ; get current value
  110. xor ecx, EFLAGS_ID ; flip bit 21
  111. push ecx ; set flipped value in EFLAGS
  112. popfd
  113. pushfd ; read it back again
  114. pop eax
  115. xor eax, ecx ; if new value is what we set
  116. shr eax, 21 ; then these two are the same
  117. and eax, 1 ; isolate bit 21 (in bit 0)
  118. xor eax, 1 ; and flip it
  119. stdRET _BlIsCpuidPresent
  120. stdENDP _BlIsCpuidPresent
  121. page
  122. subttl "GetFeatureBits"
  123. ;++
  124. ;
  125. ; VOID
  126. ; BlGetFeatureBits(
  127. ; VOID
  128. ; )
  129. ;
  130. ; Routine Description:
  131. ;
  132. ; Execute the CPUID instruction to get the feature bits supported
  133. ; by this processor.
  134. ;
  135. ; Arguments:
  136. ;
  137. ; None.
  138. ;
  139. ; Return Value:
  140. ;
  141. ; Returns the set of feature bits supported by this processor or
  142. ; 0 if this processor does not support the CPUID instruction.
  143. ;
  144. ;--
  145. cPublicProc _BlGetFeatureBits ,0
  146. stdCall _BlIsCpuidPresent ; Does this processor do CPUID?
  147. test eax, 1
  148. jnz short @f ; Jif yes.
  149. xor eax, eax ; No, return 0.
  150. stdRet _BlGetFeatureBits
  151. @@: mov eax, 1 ; CPUID function 1 gets feature bits.
  152. push ebx ; save ebx
  153. cpuid ; execute
  154. ;
  155. ; Due to a bug in NT 4, some processors report that they do
  156. ; not support cmpxchg8b even though they do. Win2K doesn't
  157. ; care but cmpxchg8b is a requirement for Whistler.
  158. ;
  159. ; Check to see if this is one of those processors and if we
  160. ; have been told by the processor manufacturer how to reenable
  161. ; cmpxchg8b, do so.
  162. ;
  163. test edx, 0100h ; is cmpxchg8b present?
  164. jnz short gfb90 ; yes, skip
  165. ;
  166. ; cmpxchg8b not present, check for recognized processor
  167. ;
  168. push eax ; save Family, Model, Stepping
  169. mov eax, 0
  170. cpuid
  171. pop eax
  172. cmp ebx, 0746e6543h ; Cyrix III = 'CentaurHauls'
  173. jnz short gfb30
  174. cmp edx, 048727561h
  175. jnz short gfb80
  176. cmp ecx, 0736c7561h
  177. jnz short gfb80
  178. cmp eax, 0600h ; consider Cyrix III F/M/S 600 and above
  179. ;
  180. ; Cyrix (Centaur) Set MSR 1107h bit 1 to 1.
  181. ;
  182. mov ecx, 01107h
  183. jae gfb20
  184. cmp eax, 0500h ; consider IDT/Centaur F/M/S 500 and above
  185. jb short gfb80
  186. ;
  187. ; Centaur family 5, set MSR 107h bit 1 to 1.
  188. ;
  189. mov ecx, 0107h
  190. gfb20: rdmsr
  191. or eax, 2
  192. wrmsr
  193. jmp short gfb80
  194. gfb30: cmp ebx, 0756e6547h ; Transmeta = 'GenuineTMx86'
  195. jnz short gfb80
  196. cmp edx, 054656e69h
  197. jnz short gfb80
  198. cmp ecx, 03638784dh
  199. jnz short gfb80
  200. cmp eax, 0542h ; consider Transmeta F/M/S 542 and above
  201. jb short gfb80
  202. ;
  203. ; Transmeta MSR 80860004h is a mask applied to the feature bits.
  204. ;
  205. mov ecx, 080860004h
  206. rdmsr
  207. or eax, 0100h
  208. wrmsr
  209. gfb80: mov eax, 1 ; reexecute CPUID function 1
  210. cpuid
  211. gfb90: mov eax, edx ; return feature bits
  212. pop ebx ; restore ebx, esi
  213. stdRET _BlGetFeatureBits
  214. stdENDP _BlGetFeatureBits
  215. _TEXT ends
  216. end