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.

322 lines
8.4 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. ; Set CR3, the I/O map base address, and LDT segment selector
  81. ; in the old TSS since they are not set on context
  82. ; switches. These values will be needed to return to the
  83. ; interrupted task.
  84. mov eax, PCR[PcTss] ; get old TSS address
  85. mov ecx, PCR[PcPrcbData+PbCurrentThread] ; get thread address
  86. mov edi, [ecx].ThApcState.AsProcess ; get process address
  87. mov ecx, [edi]+PrDirectoryTableBase ; get directory base
  88. mov [eax]+TssCR3, ecx ; set previous cr3
  89. mov cx, [edi]+PrIopmOffset ; get IOPM offset
  90. mov [eax]+TssIoMapBase, cx ; set IOPM offset
  91. mov ecx, [edi]+PrLdtDescriptor ; get LDT descriptor
  92. test ecx, ecx ; does task use LDT?
  93. jz @f
  94. mov cx, KGDT_LDT
  95. @@: mov [eax]+TssLDT, cx ; set LDT into old TSS
  96. ;
  97. ; Update the TSS pointer in the PCR to point to the MCA TSS
  98. ; (which is what we're running on, or else we wouldn't be here)
  99. ;
  100. push dword ptr PCR[PcTss]
  101. mov eax, PCR[PcGdt]
  102. mov ch, [eax+KGDT_MCA_TSS+KgdtBaseHi]
  103. mov cl, [eax+KGDT_MCA_TSS+KgdtBaseMid]
  104. shl ecx, 16
  105. mov cx, [eax+KGDT_MCA_TSS+KgdtBaseLow]
  106. mov PCR[PcTss], ecx
  107. ;
  108. ; Clear Nested Task bit in EFLAGS
  109. ;
  110. pushfd
  111. and [esp], not 04000h
  112. popfd
  113. ;
  114. ; Clear the busy bit in the TSS selector
  115. ;
  116. mov ecx, PCR[PcGdt]
  117. lea eax, [ecx] + KGDT_MCA_TSS
  118. mov byte ptr [eax+5], 089h ; 32bit, dpl=0, present, TSS32, not busy
  119. ;
  120. ; Check if there is a bugcheck-able error. If need to bugcheck, the
  121. ; caller does it.
  122. ;
  123. stdCall _HalpMcaExceptionHandler
  124. ;
  125. ; We're back which means that the error was restartable.
  126. ;
  127. pop dword ptr PCR[PcTss] ; restore PcTss
  128. mov ecx, PCR[PcGdt]
  129. lea eax, [ecx] + KGDT_TSS
  130. mov byte ptr [eax+5], 08bh ; 32bit, dpl=0, present, TSS32, *busy*
  131. pushfd ; Set Nested Task bit in EFLAGS
  132. or [esp], 04000h ; so iretd will do a tast switch
  133. popfd
  134. iretd ; Return from MCA Exception handler
  135. jmp _HalpMcaExceptionHandlerWrapper
  136. ; For next Machine check exception
  137. _HalpMcaExceptionHandlerWrapper endp
  138. _TEXT ends
  139. INIT SEGMENT DWORD PUBLIC 'CODE'
  140. ;++
  141. ;VOID
  142. ;HalpMcaCurrentProcessorSetTSS(
  143. ; IN PULONG pTSS // MCE TSS area for this processor
  144. ; )
  145. ; Routine Description:
  146. ; This function sets up the TSS for MCA exception 18
  147. ;
  148. ; Arguments:
  149. ; pTSS : Pointer to the TSS to be used for MCE
  150. ;
  151. ; Return Value:
  152. ; None
  153. ;
  154. ;--
  155. cPublicProc _HalpMcaCurrentProcessorSetTSS,1
  156. ;
  157. ; Edit IDT Entry for MCA Exception (18) to contain a task gate
  158. ;
  159. mov ecx, PCR[PcIdt] ; Get IDT address
  160. lea eax, [ecx] + 090h ; MCA Exception is 18
  161. mov byte ptr [eax + 5], 085h ; P=1,DPL=0,Type=5
  162. mov word ptr [eax + 2], KGDT_MCA_TSS ; TSS Segment Selector
  163. mov edx, [esp+4] ; the address of TSS in edx
  164. ;
  165. ; Set various fields in TSS
  166. ;
  167. mov eax, cr3
  168. mov [edx + TssCR3], eax
  169. ;
  170. ; Get double fault stack address
  171. ;
  172. lea eax, [ecx] + 040h ; DF Exception is 8
  173. ;
  174. ; Get to TSS Descriptor of double fault handler TSS
  175. ;
  176. xor ecx, ecx
  177. mov cx, word ptr [eax+2]
  178. add ecx, PCR[PcGdt]
  179. ;
  180. ; Get the address of TSS from this TSS Descriptor
  181. ;
  182. mov ah, [ecx+KgdtBaseHi]
  183. mov al, [ecx+KgdtBaseMid]
  184. shl eax, 16
  185. mov ax, [ecx+KgdtBaseLow]
  186. ;
  187. ; Get ESP from DF TSS
  188. ;
  189. mov ecx, [eax+038h]
  190. ;
  191. ; Set address of MCA Exception stack to double fault stack address
  192. ;
  193. mov dword ptr [edx+038h], ecx ; Set ESP
  194. mov dword ptr [edx+TssEsp0], ecx ; Set ESP0
  195. mov dword ptr [edx+020h], offset FLAT:_HalpMcaExceptionHandlerWrapper ; set EIP
  196. mov dword ptr [edx+024h], 0 ; set EFLAGS
  197. mov word ptr [edx+04ch],KGDT_R0_CODE ; set value for CS
  198. mov word ptr [edx+058h],KGDT_R0_PCR ; set value for FS
  199. mov [edx+050h], ss
  200. mov word ptr [edx+048h],KGDT_R3_DATA OR RPL_MASK ; Es
  201. mov word ptr [edx+054h],KGDT_R3_DATA OR RPL_MASK ; Ds
  202. ;
  203. ; Part that gets done in KiInitialiazeTSS()
  204. ;
  205. mov word ptr [edx + 08], KGDT_R0_DATA ; Set SS0
  206. mov word ptr [edx + 060h],0 ; Set LDT
  207. mov word ptr [edx + 064h],0 ; Set T bit
  208. mov word ptr [edx + 066h],020adh ; I/O Map base address = sizeof(KTSS)+1
  209. ;
  210. ; Edit GDT entry for KGDT_MCA_TSS to create a valid TSS Descriptor
  211. ;
  212. mov ecx, PCR[PcGdt] ; Get GDT address
  213. lea eax, [ecx] + KGDT_MCA_TSS ; offset of MCA TSS in GDT
  214. mov ecx, eax
  215. ;
  216. ; Set Type field of TSS Descriptor
  217. ;
  218. mov byte ptr [ecx + 5], 089H ; P=1, DPL=0, Type = 9
  219. ;
  220. ; Set Base Address field of TSS Descriptor
  221. ;
  222. mov eax, edx ; TSS address in eax
  223. mov [ecx + KgdtBaseLow], ax
  224. shr eax, 16
  225. mov [ecx + KgdtBaseHi],ah
  226. mov [ecx + KgdtBaseMid],al
  227. ;
  228. ; Set Segment limit for TSS Descriptor
  229. ;
  230. mov eax, MINIMUM_TSS_SIZE
  231. mov [ecx + KgdtLimitLow],ax
  232. stdRET _HalpMcaCurrentProcessorSetTSS
  233. stdENDP _HalpMcaCurrentProcessorSetTSS
  234. INIT ends
  235. PAGELK SEGMENT DWORD PUBLIC 'CODE'
  236. ;++
  237. ;
  238. ;VOID
  239. ;HalpSetCr4MCEBit(
  240. ; VOID
  241. ; )
  242. ;
  243. ; Routine Description:
  244. ; This function sets the CR4.MCE bit
  245. ;
  246. ; Arguments:
  247. ; None
  248. ;
  249. ; Return Value:
  250. ; None
  251. ;
  252. ;--
  253. cPublicProc _HalpSetCr4MCEBit,0
  254. mov eax, cr4
  255. or eax, CR4_MCE
  256. mov cr4, eax
  257. stdRET _HalpSetCr4MCEBit
  258. stdENDP _HalpSetCr4MCEBit
  259. PAGELK ends
  260. end