diff options
author | David Woodhouse <David.Woodhouse@intel.com> | 2013-12-30 01:14:13 +0000 |
---|---|---|
committer | lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524> | 2013-12-30 01:14:13 +0000 |
commit | af8aa62d5941518e6397c13a567a06b5eabd68d2 (patch) | |
tree | d0a7f44288a869c0a29ddc98d5480fb6515b21ed | |
parent | 321c89c208f4b1afaab37c33cf355dba11090ed5 (diff) | |
download | edk2-af8aa62d5941518e6397c13a567a06b5eabd68d2.zip edk2-af8aa62d5941518e6397c13a567a06b5eabd68d2.tar.gz edk2-af8aa62d5941518e6397c13a567a06b5eabd68d2.tar.bz2 |
MdePkg: First instruction after clearing CR0.PE must be a far jmp.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15029 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r-- | MdePkg/Library/BaseLib/Ia32/Thunk16.S | 24 | ||||
-rw-r--r-- | MdePkg/Library/BaseLib/Ia32/Thunk16.asm | 40 |
2 files changed, 35 insertions, 29 deletions
diff --git a/MdePkg/Library/BaseLib/Ia32/Thunk16.S b/MdePkg/Library/BaseLib/Ia32/Thunk16.S index 331ea16..185655e 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 3e84aed..08955d4 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
|