PageRenderTime 269ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/edk2/Clover/UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm

https://gitlab.com/envieidoc/Clover
Assembly | 445 lines | 214 code | 53 blank | 178 comment | 0 complexity | dea34e6960affdb4ac8bae7a0efcf400 MD5 | raw file
  1. ;------------------------------------------------------------------------------ ;
  2. ; Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
  3. ; This program and the accompanying materials
  4. ; are licensed and made available under the terms and conditions of the BSD License
  5. ; which accompanies this distribution. The full text of the license may be found at
  6. ; http://opensource.org/licenses/bsd-license.php.
  7. ;
  8. ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  9. ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  10. ;
  11. ; Module Name:
  12. ;
  13. ; ExceptionHandlerAsm.Asm
  14. ;
  15. ; Abstract:
  16. ;
  17. ; IA32 CPU Exception Handler
  18. ;
  19. ; Notes:
  20. ;
  21. ;------------------------------------------------------------------------------
  22. .686
  23. .model flat,C
  24. ;
  25. ; CommonExceptionHandler()
  26. ;
  27. CommonExceptionHandler PROTO C
  28. .data
  29. EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
  30. EXTRN mDoFarReturnFlag:DWORD ; Do far return flag
  31. .code
  32. ALIGN 8
  33. ;
  34. ; exception handler stub table
  35. ;
  36. AsmIdtVectorBegin:
  37. REPEAT 32
  38. db 6ah ; push #VectorNum
  39. db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
  40. push eax
  41. mov eax, CommonInterruptEntry
  42. jmp eax
  43. ENDM
  44. AsmIdtVectorEnd:
  45. HookAfterStubBegin:
  46. db 6ah ; push
  47. VectorNum:
  48. db 0 ; 0 will be fixed
  49. push eax
  50. mov eax, HookAfterStubHeaderEnd
  51. jmp eax
  52. HookAfterStubHeaderEnd:
  53. pop eax
  54. sub esp, 8 ; reserve room for filling exception data later
  55. push [esp + 8]
  56. xchg ecx, [esp] ; get vector number
  57. bt mErrorCodeFlag, ecx
  58. jnc @F
  59. push [esp] ; addition push if exception data needed
  60. @@:
  61. xchg ecx, [esp] ; restore ecx
  62. push eax
  63. ;----------------------------------------------------------------------------;
  64. ; CommonInterruptEntry ;
  65. ;----------------------------------------------------------------------------;
  66. ; The follow algorithm is used for the common interrupt routine.
  67. ; Entry from each interrupt with a push eax and eax=interrupt number
  68. ; Stack:
  69. ; +---------------------+
  70. ; + EFlags +
  71. ; +---------------------+
  72. ; + CS +
  73. ; +---------------------+
  74. ; + EIP +
  75. ; +---------------------+
  76. ; + Error Code +
  77. ; +---------------------+
  78. ; + Vector Number +
  79. ; +---------------------+
  80. ; + EBP +
  81. ; +---------------------+ <-- EBP
  82. CommonInterruptEntry PROC PUBLIC
  83. cli
  84. pop eax
  85. ;
  86. ; All interrupt handlers are invoked through interrupt gates, so
  87. ; IF flag automatically cleared at the entry point
  88. ;
  89. ;
  90. ; Get vector number from top of stack
  91. ;
  92. xchg ecx, [esp]
  93. and ecx, 0FFh ; Vector number should be less than 256
  94. cmp ecx, 32 ; Intel reserved vector for exceptions?
  95. jae NoErrorCode
  96. bt mErrorCodeFlag, ecx
  97. jc HasErrorCode
  98. NoErrorCode:
  99. ;
  100. ; Stack:
  101. ; +---------------------+
  102. ; + EFlags +
  103. ; +---------------------+
  104. ; + CS +
  105. ; +---------------------+
  106. ; + EIP +
  107. ; +---------------------+
  108. ; + ECX +
  109. ; +---------------------+ <-- ESP
  110. ;
  111. ; Registers:
  112. ; ECX - Vector Number
  113. ;
  114. ;
  115. ; Put Vector Number on stack
  116. ;
  117. push ecx
  118. ;
  119. ; Put 0 (dummy) error code on stack, and restore ECX
  120. ;
  121. xor ecx, ecx ; ECX = 0
  122. xchg ecx, [esp+4]
  123. jmp ErrorCodeAndVectorOnStack
  124. HasErrorCode:
  125. ;
  126. ; Stack:
  127. ; +---------------------+
  128. ; + EFlags +
  129. ; +---------------------+
  130. ; + CS +
  131. ; +---------------------+
  132. ; + EIP +
  133. ; +---------------------+
  134. ; + Error Code +
  135. ; +---------------------+
  136. ; + ECX +
  137. ; +---------------------+ <-- ESP
  138. ;
  139. ; Registers:
  140. ; ECX - Vector Number
  141. ;
  142. ;
  143. ; Put Vector Number on stack and restore ECX
  144. ;
  145. xchg ecx, [esp]
  146. ErrorCodeAndVectorOnStack:
  147. push ebp
  148. mov ebp, esp
  149. ;
  150. ; Stack:
  151. ; +---------------------+
  152. ; + EFlags +
  153. ; +---------------------+
  154. ; + CS +
  155. ; +---------------------+
  156. ; + EIP +
  157. ; +---------------------+
  158. ; + Error Code +
  159. ; +---------------------+
  160. ; + Vector Number +
  161. ; +---------------------+
  162. ; + EBP +
  163. ; +---------------------+ <-- EBP
  164. ;
  165. ;
  166. ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
  167. ; is 16-byte aligned
  168. ;
  169. and esp, 0fffffff0h
  170. sub esp, 12
  171. sub esp, 8
  172. push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
  173. push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
  174. ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
  175. push eax
  176. push ecx
  177. push edx
  178. push ebx
  179. lea ecx, [ebp + 6 * 4]
  180. push ecx ; ESP
  181. push dword ptr [ebp] ; EBP
  182. push esi
  183. push edi
  184. ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
  185. mov eax, ss
  186. push eax
  187. movzx eax, word ptr [ebp + 4 * 4]
  188. push eax
  189. mov eax, ds
  190. push eax
  191. mov eax, es
  192. push eax
  193. mov eax, fs
  194. push eax
  195. mov eax, gs
  196. push eax
  197. ;; UINT32 Eip;
  198. mov eax, [ebp + 3 * 4]
  199. push eax
  200. ;; UINT32 Gdtr[2], Idtr[2];
  201. sub esp, 8
  202. sidt [esp]
  203. mov eax, [esp + 2]
  204. xchg eax, [esp]
  205. and eax, 0FFFFh
  206. mov [esp+4], eax
  207. sub esp, 8
  208. sgdt [esp]
  209. mov eax, [esp + 2]
  210. xchg eax, [esp]
  211. and eax, 0FFFFh
  212. mov [esp+4], eax
  213. ;; UINT32 Ldtr, Tr;
  214. xor eax, eax
  215. str ax
  216. push eax
  217. sldt ax
  218. push eax
  219. ;; UINT32 EFlags;
  220. mov eax, [ebp + 5 * 4]
  221. push eax
  222. ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
  223. mov eax, cr4
  224. or eax, 208h
  225. mov cr4, eax
  226. push eax
  227. mov eax, cr3
  228. push eax
  229. mov eax, cr2
  230. push eax
  231. xor eax, eax
  232. push eax
  233. mov eax, cr0
  234. push eax
  235. ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
  236. mov eax, dr7
  237. push eax
  238. mov eax, dr6
  239. push eax
  240. mov eax, dr3
  241. push eax
  242. mov eax, dr2
  243. push eax
  244. mov eax, dr1
  245. push eax
  246. mov eax, dr0
  247. push eax
  248. ;; FX_SAVE_STATE_IA32 FxSaveState;
  249. sub esp, 512
  250. mov edi, esp
  251. db 0fh, 0aeh, 07h ;fxsave [edi]
  252. ;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
  253. cld
  254. ;; UINT32 ExceptionData;
  255. push dword ptr [ebp + 2 * 4]
  256. ;; Prepare parameter and call
  257. mov edx, esp
  258. push edx
  259. mov edx, dword ptr [ebp + 1 * 4]
  260. push edx
  261. ;
  262. ; Call External Exception Handler
  263. ;
  264. mov eax, CommonExceptionHandler
  265. call eax
  266. add esp, 8
  267. cli
  268. ;; UINT32 ExceptionData;
  269. add esp, 4
  270. ;; FX_SAVE_STATE_IA32 FxSaveState;
  271. mov esi, esp
  272. db 0fh, 0aeh, 0eh ; fxrstor [esi]
  273. add esp, 512
  274. ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
  275. ;; Skip restoration of DRx registers to support in-circuit emualators
  276. ;; or debuggers set breakpoint in interrupt/exception context
  277. add esp, 4 * 6
  278. ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
  279. pop eax
  280. mov cr0, eax
  281. add esp, 4 ; not for Cr1
  282. pop eax
  283. mov cr2, eax
  284. pop eax
  285. mov cr3, eax
  286. pop eax
  287. mov cr4, eax
  288. ;; UINT32 EFlags;
  289. pop dword ptr [ebp + 5 * 4]
  290. ;; UINT32 Ldtr, Tr;
  291. ;; UINT32 Gdtr[2], Idtr[2];
  292. ;; Best not let anyone mess with these particular registers...
  293. add esp, 24
  294. ;; UINT32 Eip;
  295. pop dword ptr [ebp + 3 * 4]
  296. ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
  297. ;; NOTE - modified segment registers could hang the debugger... We
  298. ;; could attempt to insulate ourselves against this possibility,
  299. ;; but that poses risks as well.
  300. ;;
  301. pop gs
  302. pop fs
  303. pop es
  304. pop ds
  305. pop dword ptr [ebp + 4 * 4]
  306. pop ss
  307. ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
  308. pop edi
  309. pop esi
  310. add esp, 4 ; not for ebp
  311. add esp, 4 ; not for esp
  312. pop ebx
  313. pop edx
  314. pop ecx
  315. pop eax
  316. pop dword ptr [ebp - 8]
  317. pop dword ptr [ebp - 4]
  318. mov esp, ebp
  319. pop ebp
  320. add esp, 8
  321. cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
  322. jz DoReturn
  323. cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
  324. jz ErrorCode
  325. jmp dword ptr [esp - 16]
  326. ErrorCode:
  327. sub esp, 4
  328. jmp dword ptr [esp - 12]
  329. DoReturn:
  330. cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET
  331. jz DoIret
  332. push [esp + 8] ; save EFLAGS
  333. add esp, 16
  334. push [esp - 8] ; save CS in new location
  335. push [esp - 8] ; save EIP in new location
  336. push [esp - 8] ; save EFLAGS in new location
  337. popfd ; restore EFLAGS
  338. retf ; far return
  339. DoIret:
  340. iretd
  341. CommonInterruptEntry ENDP
  342. ;---------------------------------------;
  343. ; _AsmGetTemplateAddressMap ;
  344. ;----------------------------------------------------------------------------;
  345. ;
  346. ; Protocol prototype
  347. ; AsmGetTemplateAddressMap (
  348. ; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
  349. ; );
  350. ;
  351. ; Routine Description:
  352. ;
  353. ; Return address map of interrupt handler template so that C code can generate
  354. ; interrupt table.
  355. ;
  356. ; Arguments:
  357. ;
  358. ;
  359. ; Returns:
  360. ;
  361. ; Nothing
  362. ;
  363. ;
  364. ; Input: [ebp][0] = Original ebp
  365. ; [ebp][4] = Return address
  366. ;
  367. ; Output: Nothing
  368. ;
  369. ; Destroys: Nothing
  370. ;-----------------------------------------------------------------------------;
  371. AsmGetTemplateAddressMap proc near public
  372. push ebp ; C prolog
  373. mov ebp, esp
  374. pushad
  375. mov ebx, dword ptr [ebp + 08h]
  376. mov dword ptr [ebx], AsmIdtVectorBegin
  377. mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
  378. mov dword ptr [ebx + 8h], HookAfterStubBegin
  379. popad
  380. pop ebp
  381. ret
  382. AsmGetTemplateAddressMap ENDP
  383. ;-------------------------------------------------------------------------------------
  384. ; AsmVectorNumFixup (*VectorBase, VectorNum, HookStub);
  385. ;-------------------------------------------------------------------------------------
  386. AsmVectorNumFixup proc near public
  387. mov eax, dword ptr [esp + 8]
  388. mov ecx, [esp + 4]
  389. mov [ecx + (VectorNum - HookAfterStubBegin)], al
  390. ret
  391. AsmVectorNumFixup ENDP
  392. END