]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiCpuPkg CpuExceptionHandlerLib:Convert X64/ExceptionHandlerAsm.asm to NASM
authorLiming Gao <liming.gao@intel.com>
Tue, 14 Jun 2016 08:12:10 +0000 (16:12 +0800)
committerLiming Gao <liming.gao@intel.com>
Tue, 28 Jun 2016 01:52:10 +0000 (09:52 +0800)
The BaseTools/Scripts/ConvertMasmToNasm.py script was used to convert
X64/ExceptionHandlerAsm.asm to X64/ExceptionHandlerAsm.nasm.
Then, manually update nasm to pass build.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm [new file with mode: 0644]

diff --git a/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm b/UefiCpuPkg/Library/CpuExceptionHandlerLib/X64/ExceptionHandlerAsm.nasm
new file mode 100644 (file)
index 0000000..ba8993d
--- /dev/null
@@ -0,0 +1,387 @@
+;------------------------------------------------------------------------------ ;\r
+; Copyright (c) 2012 - 2014, 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
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+;\r
+; Module Name:\r
+;\r
+;   ExceptionHandlerAsm.Asm\r
+;\r
+; Abstract:\r
+;\r
+;   x64 CPU Exception Handler\r
+;\r
+; Notes:\r
+;\r
+;------------------------------------------------------------------------------\r
+\r
+;\r
+; CommonExceptionHandler()\r
+;\r
+\r
+extern ASM_PFX(mErrorCodeFlag)    ; Error code flags for exceptions\r
+extern ASM_PFX(mDoFarReturnFlag)  ; Do far return flag\r
+extern ASM_PFX(CommonExceptionHandler)\r
+\r
+SECTION .data\r
+\r
+DEFAULT REL\r
+SECTION .text\r
+\r
+ALIGN   8\r
+\r
+AsmIdtVectorBegin:\r
+%rep  32\r
+    db      0x6a        ; push  #VectorNum\r
+    db      ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
+    push    rax\r
+    mov     rax, ASM_PFX(CommonInterruptEntry)\r
+    jmp     rax\r
+%endrep\r
+AsmIdtVectorEnd:\r
+\r
+HookAfterStubHeaderBegin:\r
+    db      0x6a        ; push\r
+@VectorNum:\r
+    db      0          ; 0 will be fixed\r
+    push    rax\r
+    mov     rax, HookAfterStubHeaderEnd\r
+    jmp     rax\r
+HookAfterStubHeaderEnd:\r
+    mov     rax, rsp\r
+    and     sp,  0xfff0        ; make sure 16-byte aligned for exception context\r
+    sub     rsp, 0x18           ; reserve room for filling exception data later\r
+    push    rcx\r
+    mov     rcx, [rax + 8]\r
+    bt      [ASM_PFX(mErrorCodeFlag)], ecx\r
+    jnc     .0\r
+    push    qword [rsp]             ; push additional rcx to make stack alignment\r
+.0:\r
+    xchg    rcx, [rsp]        ; restore rcx, save Exception Number in stack\r
+    push    qword [rax]             ; push rax into stack to keep code consistence\r
+\r
+;---------------------------------------;\r
+; CommonInterruptEntry                  ;\r
+;---------------------------------------;\r
+; The follow algorithm is used for the common interrupt routine.\r
+; Entry from each interrupt with a push eax and eax=interrupt number\r
+; Stack frame would be as follows as specified in IA32 manuals:\r
+;\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
+; +   Vector Number     +\r
+; +---------------------+\r
+; +    RBP              +\r
+; +---------------------+ <-- RBP, 16-byte aligned\r
+; The follow algorithm is used for the common interrupt routine.\r
+global ASM_PFX(CommonInterruptEntry)\r
+ASM_PFX(CommonInterruptEntry):\r
+    cli\r
+    pop     rax\r
+    ;\r
+    ; All interrupt handlers are invoked through interrupt gates, so\r
+    ; IF flag automatically cleared at the entry point\r
+    ;\r
+    xchg    rcx, [rsp]      ; Save rcx into stack and save vector number into rcx\r
+    and     rcx, 0xFF\r
+    cmp     ecx, 32         ; Intel reserved vector for exceptions?\r
+    jae     NoErrorCode\r
+    bt      [ASM_PFX(mErrorCodeFlag)], ecx\r
+    jc      HasErrorCode\r
+\r
+NoErrorCode:\r
+\r
+    ;\r
+    ; Push a dummy error code on the stack\r
+    ; to maintain coherent stack map\r
+    ;\r
+    push    qword [rsp]\r
+    mov     qword [rsp + 8], 0\r
+HasErrorCode:\r
+    push    rbp\r
+    mov     rbp, rsp\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    push    0             ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\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
+    ; 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 [rbp + 8]   ; RCX\r
+    push rdx\r
+    push rbx\r
+    push qword [rbp + 48]  ; RSP\r
+    push qword [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 [rbp + 56]\r
+    push    rax                      ; for ss\r
+    movzx   rax, word [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 [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 [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, 0x208\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
+    mov     rax, dr6\r
+    push    rax\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 0xf, 0xae, 0x7 ;fxsave [rdi]\r
+\r
+;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
+    cld\r
+\r
+;; UINT32  ExceptionData;\r
+    push    qword [rbp + 16]\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
+    mov     rax, ASM_PFX(CommonExceptionHandler)\r
+    call    rax\r
+    add     rsp, 4 * 8 + 8\r
+\r
+    cli\r
+;; UINT64  ExceptionData;\r
+    add     rsp, 8\r
+\r
+;; FX_SAVE_STATE_X64 FxSaveState;\r
+\r
+    mov rsi, rsp\r
+    db 0xf, 0xae, 0xE ; fxrstor [rsi]\r
+    add rsp, 512\r
+\r
+;; UINT64  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     rsp, 8 * 6\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 [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 [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 [rbp + 32]  ; for cs\r
+    pop     qword [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 [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
+    cmp     qword [rsp - 32], 0  ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
+    jz      DoReturn\r
+    cmp     qword [rsp - 40], 1  ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
+    jz      ErrorCode\r
+    jmp     qword [rsp - 32]\r
+ErrorCode:\r
+    sub     rsp, 8\r
+    jmp     qword [rsp - 24]\r
+\r
+DoReturn:\r
+    cmp     qword [ASM_PFX(mDoFarReturnFlag)], 0   ; Check if need to do far return instead of IRET\r
+    jz      DoIret\r
+    push    rax\r
+    mov     rax, rsp          ; save old RSP to rax\r
+    mov     rsp, [rsp + 0x20]\r
+    push    qword [rax + 0x10]       ; save CS in new location\r
+    push    qword [rax + 0x8]        ; save EIP in new location\r
+    push    qword [rax + 0x18]       ; save EFLAGS in new location\r
+    mov     rax, [rax]        ; restore rax\r
+    popfq                     ; restore EFLAGS\r
+    DB      0x48               ; prefix to composite "retq" with next "retf"\r
+    retf                      ; far return\r
+DoIret:\r
+    iretq\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  GetTemplateAddressMap (&AddressMap);\r
+;-------------------------------------------------------------------------------------\r
+; comments here for definition of address map\r
+global ASM_PFX(AsmGetTemplateAddressMap)\r
+ASM_PFX(AsmGetTemplateAddressMap):\r
+    mov     rax, AsmIdtVectorBegin\r
+    mov     qword [rcx], rax\r
+    mov     qword [rcx + 0x8],  (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
+    mov     rax, HookAfterStubHeaderBegin\r
+    mov     qword [rcx + 0x10], rax\r
+    ret\r
+\r
+;-------------------------------------------------------------------------------------\r
+;  AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);\r
+;-------------------------------------------------------------------------------------\r
+global ASM_PFX(AsmVectorNumFixup)\r
+ASM_PFX(AsmVectorNumFixup):\r
+    mov     rax, rdx\r
+    mov     [rcx + (@VectorNum - HookAfterStubHeaderBegin)], al\r
+    ret\r
+\r