]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg EbcDxe: Convert X64/EbcLowLevel.asm to NASM
authorJordan Justen <jordan.l.justen@intel.com>
Tue, 31 May 2016 01:52:18 +0000 (18:52 -0700)
committerLiming Gao <liming.gao@intel.com>
Tue, 28 Jun 2016 01:51:58 +0000 (09:51 +0800)
The BaseTools/Scripts/ConvertMasmToNasm.py script was used to convert
X64/EbcLowLevel.asm to X64/EbcLowLevel.nasm

And, manually update nasm code to use mov rcx, dword value and generate
the same assembly code with rcx register to asm code.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jordan Justen <jordan.l.justen@intel.com>
MdeModulePkg/Universal/EbcDxe/EbcDxe.inf
MdeModulePkg/Universal/EbcDxe/X64/EbcLowLevel.nasm [new file with mode: 0644]

index 44558aaf647bb32152c433b4fd10ad3616d3c9e8..15dc01c8eecdbfebf7e5097735a441c33a003309 100644 (file)
@@ -45,6 +45,7 @@
 \r
 [Sources.X64]\r
   X64/EbcSupport.c\r
+  X64/EbcLowLevel.nasm\r
   X64/EbcLowLevel.S\r
   X64/EbcLowLevel.asm\r
 \r
diff --git a/MdeModulePkg/Universal/EbcDxe/X64/EbcLowLevel.nasm b/MdeModulePkg/Universal/EbcDxe/X64/EbcLowLevel.nasm
new file mode 100644 (file)
index 0000000..19299a7
--- /dev/null
@@ -0,0 +1,242 @@
+;/** @file\r
+;\r
+;    This code provides low level routines that support the Virtual Machine.\r
+;    for option ROMs.\r
+;\r
+;  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
+;  Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<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
+;**/\r
+\r
+;---------------------------------------------------------------------------\r
+; Equate files needed.\r
+;---------------------------------------------------------------------------\r
+\r
+DEFAULT REL\r
+SECTION .text\r
+\r
+extern ASM_PFX(CopyMem)\r
+extern ASM_PFX(EbcInterpret)\r
+extern ASM_PFX(ExecuteEbcImageEntryPoint)\r
+\r
+;****************************************************************************\r
+; EbcLLCALLEX\r
+;\r
+; This function is called to execute an EBC CALLEX instruction.\r
+; This instruction requires that we thunk out to external native\r
+; code. For x64, we switch stacks, copy the arguments to the stack\r
+; and jump to the specified function.\r
+; On return, we restore the stack pointer to its original location.\r
+;\r
+; Destroys no working registers.\r
+;****************************************************************************\r
+; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
+global ASM_PFX(EbcLLCALLEXNative)\r
+ASM_PFX(EbcLLCALLEXNative):\r
+      push   rbp\r
+      push   rbx\r
+      mov    rbp, rsp\r
+      ; Function prolog\r
+\r
+      ; Copy FuncAddr to a preserved register.\r
+      mov    rbx, rcx\r
+\r
+      ; Set stack pointer to new value\r
+      sub    r8,  rdx\r
+\r
+      ;\r
+      ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,\r
+      ; even if the native function's arguments are less than 4.\r
+      ;\r
+      ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:\r
+      ;   "The caller is responsible for allocating space for parameters to the\r
+      ;   callee, and must always allocate sufficient space for the 4 register\r
+      ;   parameters, even if the callee doesn't have that many parameters.\r
+      ;   This aids in the simplicity of supporting C unprototyped functions,\r
+      ;   and vararg C/C++ functions."\r
+      ;\r
+      cmp    r8, 0x20\r
+      jae    skip_expansion\r
+      mov    r8, dword 0x20\r
+skip_expansion:\r
+\r
+      sub    rsp, r8\r
+\r
+      ;\r
+      ; Fix X64 native function call 16-byte alignment.\r
+      ;\r
+      ; From MSDN x64 Software Conventions, Stack Usage:\r
+      ;   "The stack will always be maintained 16-byte aligned, except within\r
+      ;   the prolog (for example, after the return address is pushed)."\r
+      ;\r
+      and    rsp, ~ 0xf\r
+\r
+      mov    rcx, rsp\r
+      sub    rsp, 0x20\r
+      call   ASM_PFX(CopyMem)\r
+      add    rsp, 0x20\r
+\r
+      ; Considering the worst case, load 4 potiential arguments\r
+      ; into registers.\r
+      mov    rcx, qword [rsp]\r
+      mov    rdx, qword [rsp+0x8]\r
+      mov    r8,  qword [rsp+0x10]\r
+      mov    r9,  qword [rsp+0x18]\r
+\r
+      ; Now call the external routine\r
+      call  rbx\r
+\r
+      ; Function epilog\r
+      mov      rsp, rbp\r
+      pop      rbx\r
+      pop      rbp\r
+      ret\r
+\r
+;****************************************************************************\r
+; EbcLLEbcInterpret\r
+;\r
+; Begin executing an EBC image.\r
+;****************************************************************************\r
+; UINT64 EbcLLEbcInterpret(VOID)\r
+global ASM_PFX(EbcLLEbcInterpret)\r
+ASM_PFX(EbcLLEbcInterpret):\r
+    ;\r
+    ;; mov rax, ca112ebccall2ebch\r
+    ;; mov r10, EbcEntryPoint\r
+    ;; mov r11, EbcLLEbcInterpret\r
+    ;; jmp r11\r
+    ;\r
+    ; Caller uses above instruction to jump here\r
+    ; The stack is below:\r
+    ; +-----------+\r
+    ; |  RetAddr  |\r
+    ; +-----------+\r
+    ; |EntryPoint | (R10)\r
+    ; +-----------+\r
+    ; |   Arg1    | <- RDI\r
+    ; +-----------+\r
+    ; |   Arg2    |\r
+    ; +-----------+\r
+    ; |   ...     |\r
+    ; +-----------+\r
+    ; |   Arg16   |\r
+    ; +-----------+\r
+    ; |   Dummy   |\r
+    ; +-----------+\r
+    ; |   RDI     |\r
+    ; +-----------+\r
+    ; |   RSI     |\r
+    ; +-----------+\r
+    ; |   RBP     | <- RBP\r
+    ; +-----------+\r
+    ; |  RetAddr  | <- RSP is here\r
+    ; +-----------+\r
+    ; |  Scratch1 | (RCX) <- RSI\r
+    ; +-----------+\r
+    ; |  Scratch2 | (RDX)\r
+    ; +-----------+\r
+    ; |  Scratch3 | (R8)\r
+    ; +-----------+\r
+    ; |  Scratch4 | (R9)\r
+    ; +-----------+\r
+    ; |   Arg5    |\r
+    ; +-----------+\r
+    ; |   Arg6    |\r
+    ; +-----------+\r
+    ; |   ...     |\r
+    ; +-----------+\r
+    ; |   Arg16   |\r
+    ; +-----------+\r
+    ;\r
+\r
+    ; save old parameter to stack\r
+    mov  [rsp + 0x8], rcx\r
+    mov  [rsp + 0x10], rdx\r
+    mov  [rsp + 0x18], r8\r
+    mov  [rsp + 0x20], r9\r
+\r
+    ; Construct new stack\r
+    push rbp\r
+    mov  rbp, rsp\r
+    push rsi\r
+    push rdi\r
+    push rbx\r
+    sub  rsp, 0x80\r
+    push r10\r
+    mov  rsi, rbp\r
+    add  rsi, 0x10\r
+    mov  rdi, rsp\r
+    add  rdi, 8\r
+    mov  rcx, dword 16\r
+    rep  movsq\r
+\r
+    ; build new paramater calling convention\r
+    mov  r9,  [rsp + 0x18]\r
+    mov  r8,  [rsp + 0x10]\r
+    mov  rdx, [rsp + 0x8]\r
+    mov  rcx, r10\r
+\r
+    ; call C-code\r
+    call ASM_PFX(EbcInterpret)\r
+    add  rsp, 0x88\r
+    pop  rbx\r
+    pop  rdi\r
+    pop  rsi\r
+    pop  rbp\r
+    ret\r
+\r
+;****************************************************************************\r
+; EbcLLExecuteEbcImageEntryPoint\r
+;\r
+; Begin executing an EBC image.\r
+;****************************************************************************\r
+; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)\r
+global ASM_PFX(EbcLLExecuteEbcImageEntryPoint)\r
+ASM_PFX(EbcLLExecuteEbcImageEntryPoint):\r
+    ;\r
+    ;; mov rax, ca112ebccall2ebch\r
+    ;; mov r10, EbcEntryPoint\r
+    ;; mov r11, EbcLLExecuteEbcImageEntryPoint\r
+    ;; jmp r11\r
+    ;\r
+    ; Caller uses above instruction to jump here\r
+    ; The stack is below:\r
+    ; +-----------+\r
+    ; |  RetAddr  |\r
+    ; +-----------+\r
+    ; |EntryPoint | (R10)\r
+    ; +-----------+\r
+    ; |ImageHandle|\r
+    ; +-----------+\r
+    ; |SystemTable|\r
+    ; +-----------+\r
+    ; |   Dummy   |\r
+    ; +-----------+\r
+    ; |   Dummy   |\r
+    ; +-----------+\r
+    ; |  RetAddr  | <- RSP is here\r
+    ; +-----------+\r
+    ; |ImageHandle| (RCX)\r
+    ; +-----------+\r
+    ; |SystemTable| (RDX)\r
+    ; +-----------+\r
+    ;\r
+\r
+    ; build new paramater calling convention\r
+    mov  r8, rdx\r
+    mov  rdx, rcx\r
+    mov  rcx, r10\r
+\r
+    ; call C-code\r
+    sub  rsp, 0x28\r
+    call ASM_PFX(ExecuteEbcImageEntryPoint)\r
+    add  rsp, 0x28\r
+    ret\r
+\r