TITLE CpuAsm.asm:\r
;------------------------------------------------------------------------------\r
;*\r
-;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+;* Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
;* This program and the accompanying materials\r
;* are licensed and made available under the terms and conditions of the BSD License\r
;* which accompanies this distribution. The full text of the license may be found at\r
.model flat,C\r
.code\r
\r
-EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
-\r
-;\r
-; point to the external interrupt vector table\r
-;\r
-ExternalVectorTablePtr DWORD 0\r
-\r
-InitializeExternalVectorTablePtr PROC PUBLIC\r
- mov eax, [esp+4]\r
- mov ExternalVectorTablePtr, eax\r
- ret\r
-InitializeExternalVectorTablePtr ENDP\r
-\r
;------------------------------------------------------------------------------\r
; VOID\r
; SetCodeSelector (\r
ret\r
SetDataSelectors ENDP\r
\r
-;---------------------------------------;\r
-; CommonInterruptEntry ;\r
-;---------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-\r
-CommonInterruptEntry PROC PUBLIC\r
- cli\r
- ;\r
- ; All interrupt handlers are invoked through interrupt gates, so\r
- ; IF flag automatically cleared at the entry point\r
- ;\r
-\r
- ;\r
- ; Calculate vector number\r
- ;\r
- ; Get the return address of call, actually, it is the\r
- ; address of vector number.\r
- ;\r
- xchg ecx, [esp]\r
- mov cx, [ecx]\r
- and ecx, 0FFFFh\r
- cmp ecx, 32 ; Intel reserved vector for exceptions?\r
- jae NoErrorCode\r
- bt mErrorCodeFlag, ecx\r
- jc HasErrorCode\r
-\r
-NoErrorCode:\r
-\r
- ;\r
- ; Stack:\r
- ; +---------------------+\r
- ; + EFlags +\r
- ; +---------------------+\r
- ; + CS +\r
- ; +---------------------+\r
- ; + EIP +\r
- ; +---------------------+\r
- ; + ECX +\r
- ; +---------------------+ <-- ESP\r
- ;\r
- ; Registers:\r
- ; ECX - Vector Number\r
- ;\r
-\r
- ;\r
- ; Put Vector Number on stack\r
- ;\r
- push ecx\r
-\r
- ;\r
- ; Put 0 (dummy) error code on stack, and restore ECX\r
- ;\r
- xor ecx, ecx ; ECX = 0\r
- xchg ecx, [esp+4]\r
-\r
- jmp ErrorCodeAndVectorOnStack\r
-\r
-HasErrorCode:\r
-\r
- ;\r
- ; Stack:\r
- ; +---------------------+\r
- ; + EFlags +\r
- ; +---------------------+\r
- ; + CS +\r
- ; +---------------------+\r
- ; + EIP +\r
- ; +---------------------+\r
- ; + Error Code +\r
- ; +---------------------+\r
- ; + ECX +\r
- ; +---------------------+ <-- ESP\r
- ;\r
- ; Registers:\r
- ; ECX - Vector Number\r
- ;\r
-\r
- ;\r
- ; Put Vector Number on stack and restore ECX\r
- ;\r
- xchg ecx, [esp]\r
-\r
-ErrorCodeAndVectorOnStack:\r
- push ebp\r
- mov ebp, esp\r
-\r
- ;\r
- ; Stack:\r
- ; +---------------------+\r
- ; + EFlags +\r
- ; +---------------------+\r
- ; + CS +\r
- ; +---------------------+\r
- ; + EIP +\r
- ; +---------------------+\r
- ; + Error Code +\r
- ; +---------------------+\r
- ; + Vector Number +\r
- ; +---------------------+\r
- ; + EBP +\r
- ; +---------------------+ <-- EBP\r
- ;\r
-\r
- ;\r
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
- ; is 16-byte aligned\r
- ;\r
- and esp, 0fffffff0h\r
- sub esp, 12\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- push eax\r
- push ecx\r
- push edx\r
- push ebx\r
- lea ecx, [ebp + 6 * 4]\r
- push ecx ; ESP\r
- push dword ptr [ebp] ; EBP\r
- push esi\r
- push edi\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
- mov eax, ss\r
- push eax\r
- movzx eax, word ptr [ebp + 4 * 4]\r
- push eax\r
- mov eax, ds\r
- push eax\r
- mov eax, es\r
- push eax\r
- mov eax, fs\r
- push eax\r
- mov eax, gs\r
- push eax\r
-\r
-;; UINT32 Eip;\r
- mov eax, [ebp + 3 * 4]\r
- push eax\r
-\r
-;; UINT32 Gdtr[2], Idtr[2];\r
- sub esp, 8\r
- sidt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
- sub esp, 8\r
- sgdt [esp]\r
- mov eax, [esp + 2]\r
- xchg eax, [esp]\r
- and eax, 0FFFFh\r
- mov [esp+4], eax\r
-\r
-;; UINT32 Ldtr, Tr;\r
- xor eax, eax\r
- str ax\r
- push eax\r
- sldt ax\r
- push eax\r
-\r
-;; UINT32 EFlags;\r
- mov eax, [ebp + 5 * 4]\r
- push eax\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- mov eax, cr4\r
- or eax, 208h\r
- mov cr4, eax\r
- push eax\r
- mov eax, cr3\r
- push eax\r
- mov eax, cr2\r
- push eax\r
- xor eax, eax\r
- push eax\r
- mov eax, cr0\r
- push eax\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov eax, dr7\r
- push eax\r
- mov eax, dr6\r
- push eax\r
- mov eax, dr3\r
- push eax\r
- mov eax, dr2\r
- push eax\r
- mov eax, dr1\r
- push eax\r
- mov eax, dr0\r
- push eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- sub esp, 512\r
- mov edi, esp\r
- db 0fh, 0aeh, 07h ;fxsave [edi]\r
-\r
-;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT32 ExceptionData;\r
- push dword ptr [ebp + 2 * 4]\r
-\r
-;; call into exception handler\r
- mov eax, ExternalVectorTablePtr ; get the interrupt vectors base\r
- or eax, eax ; NULL?\r
- jz nullExternalExceptionHandler\r
-\r
- mov ecx, [ebp + 4]\r
- mov eax, [eax + ecx * 4]\r
- or eax, eax ; NULL?\r
- jz nullExternalExceptionHandler\r
-\r
-;; Prepare parameter and call\r
- mov edx, esp\r
- push edx\r
- mov edx, dword ptr [ebp + 1 * 4]\r
- push edx\r
-\r
- ;\r
- ; Call External Exception Handler\r
- ;\r
- call eax\r
- add esp, 8\r
-\r
-nullExternalExceptionHandler:\r
-\r
- cli\r
-;; UINT32 ExceptionData;\r
- add esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- mov esi, esp\r
- db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
- add esp, 512\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; Skip restoration of DRx registers to support in-circuit emualators\r
-;; or debuggers set breakpoint in interrupt/exception context\r
- add esp, 4 * 6\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop eax\r
- mov cr0, eax\r
- add esp, 4 ; not for Cr1\r
- pop eax\r
- mov cr2, eax\r
- pop eax\r
- mov cr3, eax\r
- pop eax\r
- mov cr4, eax\r
-\r
-;; UINT32 EFlags;\r
- pop dword ptr [ebp + 5 * 4]\r
-\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add esp, 24\r
-\r
-;; UINT32 Eip;\r
- pop dword ptr [ebp + 3 * 4]\r
-\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; NOTE - modified segment registers could hang the debugger... We\r
-;; could attempt to insulate ourselves against this possibility,\r
-;; but that poses risks as well.\r
-;;\r
- pop gs\r
- pop fs\r
- pop es\r
- pop ds\r
- pop dword ptr [ebp + 4 * 4]\r
- pop ss\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pop edi\r
- pop esi\r
- add esp, 4 ; not for ebp\r
- add esp, 4 ; not for esp\r
- pop ebx\r
- pop edx\r
- pop ecx\r
- pop eax\r
-\r
- mov esp, ebp\r
- pop ebp\r
- add esp, 8\r
- iretd\r
-\r
-CommonInterruptEntry ENDP\r
\r
END\r