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
This commit is contained in:
David Woodhouse 2013-12-30 01:14:13 +00:00 committed by lgao4
parent 321c89c208
commit af8aa62d59
2 changed files with 35 additions and 29 deletions

View File

@ -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

View File

@ -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