TITLE CpuAsm.asm: \r
;------------------------------------------------------------------------------\r
;*\r
-;* Copyright 2008 - 2009, Intel Corporation \r
-;* All rights reserved. This program and the accompanying materials \r
+;* Copyright (c) 2008 - 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
;* http://opensource.org/licenses/bsd-license.php \r
\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 QWORD 0\r
-\r
-InitializeExternalVectorTablePtr PROC PUBLIC\r
- mov ExternalVectorTablePtr, rcx\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
- ; Calculate vector number\r
- ;\r
- xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.\r
- movzx ecx, word ptr [rcx]\r
- cmp ecx, 32 ; Intel reserved vector for exceptions?\r
- jae NoErrorCode\r
- bt mErrorCodeFlag, ecx\r
- jc @F\r
-\r
-NoErrorCode:\r
-\r
- ;\r
- ; Push a dummy error code on the stack\r
- ; to maintain coherent stack map\r
- ;\r
- push [rsp]\r
- mov qword ptr [rsp + 8], 0\r
-@@: \r
- push rbp\r
- mov rbp, rsp\r
-\r
- ;\r
- ; Stack:\r
- ; +---------------------+ <-- 16-byte aligned ensured by processor\r
- ; + Old SS +\r
- ; +---------------------+\r
- ; + Old RSP +\r
- ; +---------------------+\r
- ; + RFlags +\r
- ; +---------------------+\r
- ; + CS +\r
- ; +---------------------+\r
- ; + RIP +\r
- ; +---------------------+\r
- ; + Error Code +\r
- ; +---------------------+\r
- ; + RCX / Vector Number +\r
- ; +---------------------+\r
- ; + RBP +\r
- ; +---------------------+ <-- RBP, 16-byte aligned\r
- ;\r
-\r
-\r
- ;\r
- ; Since here the stack pointer is 16-byte aligned, so\r
- ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
- ; is 16-byte aligned\r
- ;\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- push r15\r
- push r14\r
- push r13\r
- push r12\r
- push r11\r
- push r10\r
- push r9\r
- push r8\r
- push rax\r
- push qword ptr [rbp + 8] ; RCX\r
- push rdx\r
- push rbx\r
- push qword ptr [rbp + 48] ; RSP\r
- push qword ptr [rbp] ; RBP\r
- push rsi\r
- push rdi\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- movzx rax, word ptr [rbp + 56]\r
- push rax ; for ss\r
- movzx rax, word ptr [rbp + 32]\r
- push rax ; for cs\r
- mov rax, ds\r
- push rax\r
- mov rax, es\r
- push rax\r
- mov rax, fs\r
- push rax\r
- mov rax, gs\r
- push rax\r
-\r
- mov [rbp + 8], rcx ; save vector number\r
-\r
-;; UINT64 Rip;\r
- push qword ptr [rbp + 24]\r
-\r
-;; UINT64 Gdtr[2], Idtr[2];\r
- xor rax, rax\r
- push rax\r
- push rax\r
- sidt [rsp]\r
- xchg rax, [rsp + 2]\r
- xchg rax, [rsp]\r
- xchg rax, [rsp + 8]\r
-\r
- xor rax, rax\r
- push rax\r
- push rax\r
- sgdt [rsp]\r
- xchg rax, [rsp + 2]\r
- xchg rax, [rsp]\r
- xchg rax, [rsp + 8]\r
-\r
-;; UINT64 Ldtr, Tr;\r
- xor rax, rax\r
- str ax\r
- push rax\r
- sldt ax\r
- push rax\r
-\r
-;; UINT64 RFlags;\r
- push qword ptr [rbp + 40]\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- mov rax, cr8\r
- push rax\r
- mov rax, cr4\r
- or rax, 208h\r
- mov cr4, rax\r
- push rax\r
- mov rax, cr3\r
- push rax\r
- mov rax, cr2\r
- push rax\r
- xor rax, rax\r
- push rax\r
- mov rax, cr0\r
- push rax\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov rax, dr7\r
- push rax\r
-;; clear Dr7 while executing debugger itself\r
- xor rax, rax\r
- mov dr7, rax\r
-\r
- mov rax, dr6\r
- push rax\r
-;; insure all status bits in dr6 are clear...\r
- xor rax, rax\r
- mov dr6, rax\r
-\r
- mov rax, dr3\r
- push rax\r
- mov rax, dr2\r
- push rax\r
- mov rax, dr1\r
- push rax\r
- mov rax, dr0\r
- push rax\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
- sub rsp, 512\r
- mov rdi, rsp\r
- db 0fh, 0aeh, 07h ;fxsave [rdi]\r
-\r
-;; UINT32 ExceptionData;\r
- push qword ptr [rbp + 16]\r
-\r
-;; call into exception handler\r
- mov rcx, [rbp + 8]\r
- mov rax, ExternalVectorTablePtr ; get the interrupt vectors base\r
- mov rax, [rax + rcx * 8] \r
- or rax, rax ; NULL?\r
-\r
- je nonNullValue;\r
-\r
-;; Prepare parameter and call\r
-; mov rcx, [rbp + 8]\r
- mov rdx, rsp\r
- ;\r
- ; Per X64 calling convention, allocate maximum parameter stack space\r
- ; and make sure RSP is 16-byte aligned\r
- ;\r
- sub rsp, 4 * 8 + 8\r
- call rax\r
- add rsp, 4 * 8 + 8\r
-\r
-nonNullValue:\r
- cli\r
-;; UINT64 ExceptionData;\r
- add rsp, 8\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-\r
- mov rsi, rsp\r
- db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
- add rsp, 512\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop rax\r
- mov dr0, rax\r
- pop rax\r
- mov dr1, rax\r
- pop rax\r
- mov dr2, rax\r
- pop rax\r
- mov dr3, rax\r
-;; skip restore of dr6. We cleared dr6 during the context save.\r
- add rsp, 8\r
- pop rax\r
- mov dr7, rax\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- pop rax\r
- mov cr0, rax\r
- add rsp, 8 ; not for Cr1\r
- pop rax\r
- mov cr2, rax\r
- pop rax\r
- mov cr3, rax\r
- pop rax\r
- mov cr4, rax\r
- pop rax\r
- mov cr8, rax\r
-\r
-;; UINT64 RFlags;\r
- pop qword ptr [rbp + 40]\r
-\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add rsp, 48\r
-\r
-;; UINT64 Rip;\r
- pop qword ptr [rbp + 24]\r
-\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
- pop rax\r
- ; mov gs, rax ; not for gs\r
- pop rax\r
- ; mov fs, rax ; not for fs\r
- ; (X64 will not use fs and gs, so we do not restore it)\r
- pop rax\r
- mov es, rax\r
- pop rax\r
- mov ds, rax\r
- pop qword ptr [rbp + 32] ; for cs\r
- pop qword ptr [rbp + 56] ; for ss\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pop rdi\r
- pop rsi\r
- add rsp, 8 ; not for rbp\r
- pop qword ptr [rbp + 48] ; for rsp\r
- pop rbx\r
- pop rdx\r
- pop rcx\r
- pop rax\r
- pop r8\r
- pop r9\r
- pop r10\r
- pop r11\r
- pop r12\r
- pop r13\r
- pop r14\r
- pop r15\r
-\r
- mov rsp, rbp\r
- pop rbp\r
- add rsp, 16\r
- iretq\r
-\r
-CommonInterruptEntry ENDP\r
-\r
END\r
\r