]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdePkg/Library/BaseLib/Ia32/Thunk16.asm
MdePkg: First instruction after clearing CR0.PE must be a far jmp.
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / Thunk16.asm
index 3e84aedf3df72b84621644895a6e6791e58da092..08955d4e91d4c91babd9e2646de0264cd46b7b24 100644 (file)
@@ -157,24 +157,30 @@ _ToUserCode PROC
     mov     es, ecx\r
     mov     fs, ecx\r
     mov     gs, ecx\r
-    mov     cr0, eax\r
-    mov     cr4, ebp                    ; real mode starts at next instruction\r
+    mov     cr0, eax                    ; real mode starts at next instruction\r
+                                        ;  which (per SDM) *must* be a far JMP.\r
+    DB      0eah\r
+_RealAddr DW 0,0                       ; filled in by InternalAsmThunk16\r
+\r
+    mov     cr4, ebp\r
     mov     ss, esi                     ; set up 16-bit stack segment\r
     xchg    sp, bx                      ; set up 16-bit stack pointer\r
-    DB      66h\r
-    call    @Base                       ; push eip\r
-@Base:\r
-    pop     bp                          ; ebp <- address of @Base\r
-    DB      67h                         ; address size override\r
-    push    [esp + sizeof (IA32_REGS) + 2]\r
-    lea     eax, [esi + (@RealMode - @Base)]\r
-    push    eax\r
-    retf\r
-@RealMode:\r
-    mov     cs:[esi + (SavedSs - @Base)], edx\r
-    mov     cs:[esi + (SavedEsp - @Base)], bx\r
-    DB      66h\r
-    lidt    fword ptr cs:[esi + (_16Idtr - @Base)]\r
+\r
+;   mov     bp, [esp + sizeof(IA32_REGS)\r
+    DB      67h\r
+    mov     ebp, [esp + sizeof(IA32_REGS)] ; BackFromUserCode address from stack\r
+\r
+;   mov     cs:[bp + (SavedSs - _BackFromUserCode)], dx\r
+    mov     cs:[esi + (SavedSs - _BackFromUserCode)], edx\r
+\r
+;   mov     cs:[bp + (SavedEsp - _BackFromUserCode)], ebx\r
+    DB      2eh, 66h, 89h, 9eh\r
+    DW      SavedEsp - _BackFromUserCode\r
+\r
+;   lidt    cs:[bp + (_16Idtr - _BackFromUserCode)]\r
+    DB      2eh, 66h, 0fh, 01h, 9eh\r
+    DW      _16Idtr - _BackFromUserCode\r
+\r
     popaw                               ; popad actually\r
     pop     ds\r
     pop     es\r
@@ -230,6 +236,8 @@ InternalAsmThunk16  PROC    USES    ebp ebx esi edi ds  es  fs  gs
     lea     ecx, [ecx + (_BackFromUserCode - m16Start)]\r
     mov     ax, cx\r
     stosd                               ; [edi] <- return address of user code\r
+    add     eax, _RealAddr + 4 - _BackFromUserCode\r
+    mov     dword ptr [edx + (_RealAddr - SavedCr0)], eax\r
     sgdt    fword ptr [edx + (SavedGdt - SavedCr0)]\r
     sidt    fword ptr [esp + 36]        ; save IDT stack in argument space\r
     mov     eax, cr0\r