]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/X64/Thunk16.asm
Use rsp instead of esp to save 64-bit stack pointer.
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / Thunk16.asm
index d93af4459766d49cf04cc06fb1c9364216e5f5e2..e01de272d22bc0bbddacd216fcc71305f80c0a1f 100644 (file)
@@ -3,11 +3,11 @@
 \r
 ;------------------------------------------------------------------------------\r
 ;\r
-; Copyright (c) 2006 - 2008, Intel Corporation\r
-; All rights reserved. This program and the accompanying materials\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
-; http://opensource.org/licenses/bsd-license.php\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
@@ -105,7 +105,8 @@ _ThunkAttr  DD      ?
     or      al, 2\r
     out     92h, al                     ; deactivate A20M#\r
 @2:\r
-    mov     eax, ss\r
+    xor     ax, ax                      ; xor eax, eax\r
+    mov     eax, ss                     ; mov ax, ss\r
     lea     bp, [esp + sizeof (IA32_REGS)]\r
     ;\r
     ; rsi in the following 2 instructions is indeed bp in 16-bit code\r
@@ -140,7 +141,10 @@ SavedCr0    DD      ?
 @64Eip      DD      ?\r
 SavedCs     DW      ?\r
 @64BitCode:\r
-    mov     rsp, r8                     ; restore stack\r
+    db      090h \r
+    db      048h, 0bch                 ; mov rsp, imm64\r
+SavedSp     DQ   ?                     ; restore stack\r
+    nop\r
     ret\r
 _BackFromUserCode   ENDP\r
 \r
@@ -230,9 +234,13 @@ GDT_SIZE = $ - _NullSeg
 ;   );\r
 ;------------------------------------------------------------------------------\r
 InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi\r
-    mov     r10d, ds                    ; r9 ~ r11 are not accessible in 16-bit\r
-    mov     r11d, es                    ; so use them for saving seg registers\r
-    mov     r9d, ss\r
+    mov     rbx, ds\r
+    push    rbx          ; Save ds segment register on the stack\r
+    mov     rbx, es\r
+    push    rbx          ; Save es segment register on the stack\r
+    mov     rbx, ss\r
+    push    rbx          ; Save ss segment register on the stack\r
+    \r
     push    fs\r
     push    gs\r
     mov     rsi, rcx\r
@@ -251,14 +259,30 @@ InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi
     shl     eax, 12                     ; segment address in high order 16 bits\r
     lea     ax, [rdx + (_BackFromUserCode - m16Start)]  ; offset address\r
     stosd                               ; [edi] <- return address of user code\r
-    sgdt    fword ptr [rcx + (SavedGdt - SavedCr4)]\r
-    sidt    fword ptr [rsp + 38h]       ; save IDT stack in argument space\r
+  \r
+    sgdt    fword ptr [rsp + 60h]       ; save GDT stack in argument space\r
+    movzx   r10, word ptr [rsp + 60h]   ; r10 <- GDT limit \r
+    lea     r11, [rcx + (InternalAsmThunk16 - SavedCr4) + 0xf]\r
+    and     r11, 0xfffffff0             ; r11 <- 16-byte aligned shadowed GDT table in real mode buffer\r
+    \r
+    mov     word ptr [rcx + (SavedGdt - SavedCr4)], r10w      ; save the limit of shadowed GDT table\r
+    mov     qword ptr [rcx + (SavedGdt - SavedCr4) + 2], r11  ; save the base address of shadowed GDT table\r
+    \r
+    mov     rsi, qword ptr [rsp + 62h]  ; rsi <- the original GDT base address\r
+    xchg    rcx, r10                    ; save rcx to r10 and initialize rcx to be the limit of GDT table\r
+    inc     rcx                         ; rcx <- the size of memory to copy\r
+    xchg    rdi, r11                    ; save rdi to r11 and initialize rdi to the base address of shadowed GDT table\r
+    rep     movsb                       ; perform memory copy to shadow GDT table\r
+    mov     rcx, r10                    ; restore the orignal rcx before memory copy\r
+    mov     rdi, r11                    ; restore the original rdi before memory copy\r
+    \r
+    sidt    fword ptr [rsp + 50h]       ; save IDT stack in argument space\r
     mov     rax, cr0\r
     mov     [rcx + (SavedCr0 - SavedCr4)], eax\r
     and     eax, 7ffffffeh              ; clear PE, PG bits\r
     mov     rbp, cr4\r
     mov     [rcx], ebp                  ; save CR4 in SavedCr4\r
-    and     ebp, 300h                   ; clear all but PCE and OSFXSR bits\r
+    and     ebp, NOT 30h                ; clear PAE, PSE bits\r
     mov     esi, r8d                    ; esi <- 16-bit stack segment\r
     DB      6ah, DATA32                 ; push DATA32\r
     pop     rdx                         ; rdx <- 32-bit data segment selector\r
@@ -270,17 +294,21 @@ InternalAsmThunk16  PROC    USES    rbp rbx rsi rdi
     push    r8\r
     mov     r8d, cs\r
     mov     [rcx + (SavedCs - SavedCr4)], r8w\r
-    mov     r8, rsp\r
+    mov     [rcx + (SavedSp - SavedCr4)], rsp\r
     jmp     fword ptr [rcx + (_EntryPoint - SavedCr4)]\r
 @RetFromRealMode:\r
     popfq\r
-    lidt    fword ptr [rsp + 38h]       ; restore protected mode IDTR\r
+    lgdt    fword ptr [rsp + 60h]       ; restore protected mode GDTR\r
+    lidt    fword ptr [rsp + 50h]       ; restore protected mode IDTR\r
     lea     eax, [rbp - sizeof (IA32_REGS)]\r
     pop     gs\r
     pop     fs\r
-    mov     ss, r9d\r
-    mov     es, r11d\r
-    mov     ds, r10d\r
+    pop     rbx\r
+    mov     ss, rbx\r
+    pop     rbx\r
+    mov     es, rbx\r
+    pop     rbx\r
+    mov     ds, rbx\r
     ret\r
 InternalAsmThunk16  ENDP\r
 \r