From af8aa62d5941518e6397c13a567a06b5eabd68d2 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Mon, 30 Dec 2013 01:14:13 +0000 Subject: MdePkg: First instruction after clearing CR0.PE must be a far jmp. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: David Woodhouse Reviewed-by: Liming Gao git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15029 6f19259b-4bc3-4df7-8a09-765794883524 --- MdePkg/Library/BaseLib/Ia32/Thunk16.S | 24 +++++++++----------- MdePkg/Library/BaseLib/Ia32/Thunk16.asm | 40 ++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 29 deletions(-) (limited to 'MdePkg/Library/BaseLib') diff --git a/MdePkg/Library/BaseLib/Ia32/Thunk16.S b/MdePkg/Library/BaseLib/Ia32/Thunk16.S index 331ea1634e..185655eecb 100644 --- a/MdePkg/Library/BaseLib/Ia32/Thunk16.S +++ b/MdePkg/Library/BaseLib/Ia32/Thunk16.S @@ -113,22 +113,18 @@ ASM_PFX(ToUserCode): movw %cx, %es movw %cx, %fs movw %cx, %gs - movl %eax, %cr0 - movl %ebp, %cr4 # real mode starts at next instruction + movl %eax, %cr0 # real mode starts at next instruction + # which (per SDM) *must* be a far JMP. + ljmpw $0,$0 # will be filled in by InternalAsmThunk16 +L_Base: # to point here. + movl %ebp, %cr4 movw %si, %ss # set up 16-bit stack segment xchgl %ebx, %esp # set up 16-bit stack pointer - calll L_Base # push eip -L_Base: - popl %ebp # ebp <- offset L_Base - push (IA32_REGS_SIZE + 2)(%esp) - lea (L_RealMode - L_Base)(%bp), %ax - push %ax - lret -L_RealMode: - mov %dx, %cs:(SavedSs - L_Base)(%bp) - mov %ebx, %cs:(SavedEsp - L_Base)(%bp) - lidtl %cs:(_16Idtr - L_Base)(%bp) + movw IA32_REGS_SIZE(%esp), %bp # get BackToUserCode address from stack + mov %dx, %cs:(SavedSs - ASM_PFX(BackFromUserCode))(%bp) + mov %ebx, %cs:(SavedEsp - ASM_PFX(BackFromUserCode))(%bp) + lidtl %cs:(_16Idtr - ASM_PFX(BackFromUserCode))(%bp) popal pop %ds pop %es @@ -189,6 +185,8 @@ ASM_PFX(InternalAsmThunk16): lea (ASM_PFX(BackFromUserCode) - ASM_PFX(m16Start))(%ecx), %ecx movw %cx, %ax stosl # [edi] <- return address of user code + addl $(L_Base - ASM_PFX(BackFromUserCode)), %eax + movl %eax, (L_Base - SavedCr0 - 4)(%edx) sgdtl (SavedGdt - SavedCr0)(%edx) sidtl 0x24(%esp) movl %cr0, %eax diff --git a/MdePkg/Library/BaseLib/Ia32/Thunk16.asm b/MdePkg/Library/BaseLib/Ia32/Thunk16.asm index 3e84aedf3d..08955d4e91 100644 --- a/MdePkg/Library/BaseLib/Ia32/Thunk16.asm +++ b/MdePkg/Library/BaseLib/Ia32/Thunk16.asm @@ -157,24 +157,30 @@ _ToUserCode PROC mov es, ecx mov fs, ecx mov gs, ecx - mov cr0, eax - mov cr4, ebp ; real mode starts at next instruction + mov cr0, eax ; real mode starts at next instruction + ; which (per SDM) *must* be a far JMP. + DB 0eah +_RealAddr DW 0,0 ; filled in by InternalAsmThunk16 + + mov cr4, ebp mov ss, esi ; set up 16-bit stack segment xchg sp, bx ; set up 16-bit stack pointer - DB 66h - call @Base ; push eip -@Base: - pop bp ; ebp <- address of @Base - DB 67h ; address size override - push [esp + sizeof (IA32_REGS) + 2] - lea eax, [esi + (@RealMode - @Base)] - push eax - retf -@RealMode: - mov cs:[esi + (SavedSs - @Base)], edx - mov cs:[esi + (SavedEsp - @Base)], bx - DB 66h - lidt fword ptr cs:[esi + (_16Idtr - @Base)] + +; mov bp, [esp + sizeof(IA32_REGS) + DB 67h + mov ebp, [esp + sizeof(IA32_REGS)] ; BackFromUserCode address from stack + +; mov cs:[bp + (SavedSs - _BackFromUserCode)], dx + mov cs:[esi + (SavedSs - _BackFromUserCode)], edx + +; mov cs:[bp + (SavedEsp - _BackFromUserCode)], ebx + DB 2eh, 66h, 89h, 9eh + DW SavedEsp - _BackFromUserCode + +; lidt cs:[bp + (_16Idtr - _BackFromUserCode)] + DB 2eh, 66h, 0fh, 01h, 9eh + DW _16Idtr - _BackFromUserCode + popaw ; popad actually pop ds pop es @@ -230,6 +236,8 @@ InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs lea ecx, [ecx + (_BackFromUserCode - m16Start)] mov ax, cx stosd ; [edi] <- return address of user code + add eax, _RealAddr + 4 - _BackFromUserCode + mov dword ptr [edx + (_RealAddr - SavedCr0)], eax sgdt fword ptr [edx + (SavedGdt - SavedCr0)] sidt fword ptr [esp + 36] ; save IDT stack in argument space mov eax, cr0 -- cgit v1.2.3