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.

299 lines
7.1 KiB

  1. ;++
  2. ;Module Name
  3. ; imca.asm
  4. ;
  5. ;Abstract:
  6. ; Assembly support needed for Intel MCA
  7. ;
  8. ; Author:
  9. ; Anil Aggarwal (Intel Corp)
  10. ;
  11. ;Revision History:
  12. ;
  13. ;
  14. ;--
  15. .586p
  16. .xlist
  17. include hal386.inc
  18. include callconv.inc
  19. include i386\kimacro.inc
  20. .list
  21. EXTRNP _HalpMcaExceptionHandler,0
  22. EXTRNP _KeBugCheckEx,5,IMPORT
  23. KGDT_MCA_TSS EQU 0A0H
  24. MINIMUM_TSS_SIZE EQU TssIoMaps
  25. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  26. ;
  27. ; TEXT Segment
  28. ;
  29. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  30. _TEXT SEGMENT PARA PUBLIC 'CODE'
  31. ASSUME DS:FLAT, ES:FLAT, SS:NOTHING, FS:NOTHING, GS:NOTHING
  32. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  33. .586p
  34. ;++
  35. ;
  36. ;VOID
  37. ;HalpSerialize(
  38. ; VOID
  39. ; )
  40. ;
  41. ; Routine Description:
  42. ; This function implements the fence operation for out-of-order execution
  43. ;
  44. ; Arguments:
  45. ; None
  46. ;
  47. ; Return Value:
  48. ; None
  49. ;
  50. ;--
  51. cPublicProc _HalpSerialize,0
  52. push ebx
  53. xor eax, eax
  54. cpuid
  55. pop ebx
  56. stdRET _HalpSerialize
  57. stdENDP _HalpSerialize
  58. ;++
  59. ;
  60. ; Routine Description:
  61. ;
  62. ; Machine Check exception handler
  63. ;
  64. ;
  65. ; Arguments:
  66. ;
  67. ; Return value:
  68. ;
  69. ; If the error is non-restartable, we will bugcheck.
  70. ; Otherwise, we just return
  71. ;
  72. ;--
  73. ASSUME DS:NOTHING, SS:NOTHING, ES:NOTHING
  74. align dword
  75. public _HalpMcaExceptionHandlerWrapper
  76. _HalpMcaExceptionHandlerWrapper proc
  77. .FPO (0, 0, 0, 0, 0, 2)
  78. cli
  79. ;
  80. ; Update the TSS pointer in the PCR to point to the MCA TSS
  81. ; (which is what we're running on, or else we wouldn't be here)
  82. ;
  83. push dword ptr PCR[PcTss]
  84. mov eax, PCR[PcGdt]
  85. mov ch, [eax+KGDT_MCA_TSS+KgdtBaseHi]
  86. mov cl, [eax+KGDT_MCA_TSS+KgdtBaseMid]
  87. shl ecx, 16
  88. mov cx, [eax+KGDT_MCA_TSS+KgdtBaseLow]
  89. mov PCR[PcTss], ecx
  90. ;
  91. ; Clear the busy bit in the TSS selector
  92. ;
  93. mov ecx, PCR[PcGdt]
  94. lea eax, [ecx] + KGDT_MCA_TSS
  95. mov byte ptr [eax+5], 089h ; 32bit, dpl=0, present, TSS32, not busy
  96. ;
  97. ; Clear Nested Task bit in EFLAGS
  98. ;
  99. pushfd
  100. and [esp], not 04000h
  101. popfd
  102. ;
  103. ; Check if there is a bugcheck-able error. If need to bugcheck, the
  104. ; caller does it.
  105. ;
  106. stdCall _HalpMcaExceptionHandler
  107. ;
  108. ; We're back which means that the error was restartable.
  109. ;
  110. pop dword ptr PCR[PcTss] ; restore PcTss
  111. mov ecx, PCR[PcGdt]
  112. lea eax, [ecx] + KGDT_TSS
  113. mov byte ptr [eax+5], 08bh ; 32bit, dpl=0, present, TSS32, *busy*
  114. pushfd ; Set Nested Task bit in EFLAGS
  115. or [esp], 04000h ; so iretd will do a tast switch
  116. popfd
  117. iretd ; Return from MCA Exception handler
  118. jmp short _HalpMcaExceptionHandlerWrapper
  119. ; For next Machine check exception
  120. _HalpMcaExceptionHandlerWrapper endp
  121. _TEXT ends
  122. INIT SEGMENT DWORD PUBLIC 'CODE'
  123. ;++
  124. ;VOID
  125. ;HalpMcaCurrentProcessorSetTSS(
  126. ; IN PULONG pTSS // MCE TSS area for this processor
  127. ; )
  128. ; Routine Description:
  129. ; This function sets up the TSS for MCA exception 18
  130. ;
  131. ; Arguments:
  132. ; pTSS : Pointer to the TSS to be used for MCE
  133. ;
  134. ; Return Value:
  135. ; None
  136. ;
  137. ;--
  138. cPublicProc _HalpMcaCurrentProcessorSetTSS,1
  139. ;
  140. ; Edit IDT Entry for MCA Exception (18) to contain a task gate
  141. ;
  142. mov ecx, PCR[PcIdt] ; Get IDT address
  143. lea eax, [ecx] + 090h ; MCA Exception is 18
  144. mov byte ptr [eax + 5], 085h ; P=1,DPL=0,Type=5
  145. mov word ptr [eax + 2], KGDT_MCA_TSS ; TSS Segment Selector
  146. mov edx, [esp+4] ; the address of TSS in edx
  147. ;
  148. ; Set various fields in TSS
  149. ;
  150. mov eax, cr3
  151. mov [edx + TssCR3], eax
  152. ;
  153. ; Get double fault stack address
  154. ;
  155. lea eax, [ecx] + 040h ; DF Exception is 8
  156. ;
  157. ; Get to TSS Descriptor of double fault handler TSS
  158. ;
  159. xor ecx, ecx
  160. mov cx, word ptr [eax+2]
  161. add ecx, PCR[PcGdt]
  162. ;
  163. ; Get the address of TSS from this TSS Descriptor
  164. ;
  165. mov ah, [ecx+KgdtBaseHi]
  166. mov al, [ecx+KgdtBaseMid]
  167. shl eax, 16
  168. mov ax, [ecx+KgdtBaseLow]
  169. ;
  170. ; Get ESP from DF TSS
  171. ;
  172. mov ecx, [eax+038h]
  173. ;
  174. ; Set address of MCA Exception stack to double fault stack address
  175. ;
  176. mov dword ptr [edx+038h], ecx ; Set ESP
  177. mov dword ptr [edx+TssEsp0], ecx ; Set ESP0
  178. mov dword ptr [edx+020h], offset FLAT:_HalpMcaExceptionHandlerWrapper ; set EIP
  179. mov dword ptr [edx+024h], 0 ; set EFLAGS
  180. mov word ptr [edx+04ch],KGDT_R0_CODE ; set value for CS
  181. mov word ptr [edx+058h],KGDT_R0_PCR ; set value for FS
  182. mov [edx+050h], ss
  183. mov word ptr [edx+048h],KGDT_R3_DATA OR RPL_MASK ; Es
  184. mov word ptr [edx+054h],KGDT_R3_DATA OR RPL_MASK ; Ds
  185. ;
  186. ; Part that gets done in KiInitialiazeTSS()
  187. ;
  188. mov word ptr [edx + 08], KGDT_R0_DATA ; Set SS0
  189. mov word ptr [edx + 060h],0 ; Set LDT
  190. mov word ptr [edx + 064h],0 ; Set T bit
  191. mov word ptr [edx + 066h],020adh ; I/O Map base address = sizeof(KTSS)+1
  192. ;
  193. ; Edit GDT entry for KGDT_MCA_TSS to create a valid TSS Descriptor
  194. ;
  195. mov ecx, PCR[PcGdt] ; Get GDT address
  196. lea eax, [ecx] + KGDT_MCA_TSS ; offset of MCA TSS in GDT
  197. mov ecx, eax
  198. ;
  199. ; Set Type field of TSS Descriptor
  200. ;
  201. mov byte ptr [ecx + 5], 089H ; P=1, DPL=0, Type = 9
  202. ;
  203. ; Set Base Address field of TSS Descriptor
  204. ;
  205. mov eax, edx ; TSS address in eax
  206. mov [ecx + KgdtBaseLow], ax
  207. shr eax, 16
  208. mov [ecx + KgdtBaseHi],ah
  209. mov [ecx + KgdtBaseMid],al
  210. ;
  211. ; Set Segment limit for TSS Descriptor
  212. ;
  213. mov eax, MINIMUM_TSS_SIZE
  214. mov [ecx + KgdtLimitLow],ax
  215. stdRET _HalpMcaCurrentProcessorSetTSS
  216. stdENDP _HalpMcaCurrentProcessorSetTSS
  217. INIT ends
  218. PAGELK SEGMENT DWORD PUBLIC 'CODE'
  219. ;++
  220. ;
  221. ;VOID
  222. ;HalpSetCr4MCEBit(
  223. ; VOID
  224. ; )
  225. ;
  226. ; Routine Description:
  227. ; This function sets the CR4.MCE bit
  228. ;
  229. ; Arguments:
  230. ; None
  231. ;
  232. ; Return Value:
  233. ; None
  234. ;
  235. ;--
  236. cPublicProc _HalpSetCr4MCEBit,0
  237. mov eax, cr4
  238. or eax, CR4_MCE
  239. mov cr4, eax
  240. stdRET _HalpSetCr4MCEBit
  241. stdENDP _HalpSetCr4MCEBit
  242. PAGELK ends
  243. end