Save segment registers on stack in case the thunk code assembly calls CF9 soft reset and the x64 registers get cleared.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@8123 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
qhuang8 2009-04-17 07:38:57 +00:00
parent 14ca06407d
commit 0fe43214e3
2 changed files with 42 additions and 22 deletions

View File

@ -136,10 +136,13 @@ SavedCr4: .space 4
SavedCr0: .space 4
movq %rax, %cr0
.byte 0x66,0xea # jmp far cs:L_64Bit
L_64Eip: .space 4
L_64Eip: .space 4
SavedCs: .space 2
L_64BitCode:
movq %r8, %rsp
.byte 0x90
.byte 0x67,0xbc # mov esp, imm32
SavedSp: .space 4 # restore stack
nop
ret
_EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start)
@ -227,7 +230,6 @@ ASM_PFX(_32Data):
# IN OUT VOID *Transition
# );
#------------------------------------------------------------------------------
# MISMATCH: "InternalAsmThunk16 PROC USES rbp rbx rsi rdi"
.globl ASM_PFX(InternalAsmThunk16)
ASM_PFX(InternalAsmThunk16):
@ -236,9 +238,13 @@ ASM_PFX(InternalAsmThunk16):
pushq %rsi
pushq %rdi
movl %ds, %r10d # r9 ~ r11 are not accessible in 16-bit
movl %es, %r11d # so use them for saving seg registers
movl %ss, %r9d
movq %ds, %rbx
pushq %rbx # Save ds segment register on the stack
movq %es, %rbx
pushq %rbx # Save es segment register on the stack
movq %ss, %rbx
pushq %rbx # Save ss segment register on the stack
.byte 0x0f, 0xa0 #push fs
.byte 0x0f, 0xa8 #push gs
movq %rcx, %rsi
@ -259,7 +265,7 @@ ASM_PFX(InternalAsmThunk16):
lea (_BackFromUserCode - ASM_PFX(m16Start))(%rdx), %ax
stosl # [edi] <- return address of user code
sgdt (SavedGdt - SavedCr4)(%rcx)
sidt 0x38(%rsp)
sidt 0x50(%rsp)
movq %cr0, %rax
movl %eax, (SavedCr0 - SavedCr4)(%rcx)
andl $0x7ffffffe,%eax # clear PE, PG bits
@ -277,18 +283,22 @@ ASM_PFX(InternalAsmThunk16):
pushq %r8
movl %cs, %r8d
movw %r8w, (SavedCs - SavedCr4)(%rcx)
movq %rsp, %r8
movl %esp, (SavedSp - SavedCr4)(%rcx)
.byte 0xff, 0x69 # jmp (_EntryPoint - SavedCr4)(%rcx)
.byte _EntryPoint - SavedCr4
L_RetFromRealMode:
popfq
lidt 0x38(%rsp)
lidt 0x50(%rsp)
lea -IA32_REGS_SIZE(%rbp), %eax
.byte 0x0f, 0xa9 # pop gs
.byte 0x0f, 0xa1 # pop fs
movl %r9d, %ss
movl %r11d, %es
movl %r10d, %ds
popq %rbx
movq %rbx, %ss
popq %rbx
movq %rbx, %es
popq %rbx
movq %rbx, %ds
popq %rdi
popq %rsi

View File

@ -140,7 +140,10 @@ SavedCr0 DD ?
@64Eip DD ?
SavedCs DW ?
@64BitCode:
mov rsp, r8 ; restore stack
db 090h
db 067h, 0bch ; mov esp, imm32
SavedSp DD ? ; restore stack
nop
ret
_BackFromUserCode ENDP
@ -230,9 +233,13 @@ GDT_SIZE = $ - _NullSeg
; );
;------------------------------------------------------------------------------
InternalAsmThunk16 PROC USES rbp rbx rsi rdi
mov r10d, ds ; r9 ~ r11 are not accessible in 16-bit
mov r11d, es ; so use them for saving seg registers
mov r9d, ss
mov rbx, ds
push rbx ; Save ds segment register on the stack
mov rbx, es
push rbx ; Save es segment register on the stack
mov rbx, ss
push rbx ; Save ss segment register on the stack
push fs
push gs
mov rsi, rcx
@ -252,7 +259,7 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
lea ax, [rdx + (_BackFromUserCode - m16Start)] ; offset address
stosd ; [edi] <- return address of user code
sgdt fword ptr [rcx + (SavedGdt - SavedCr4)]
sidt fword ptr [rsp + 38h] ; save IDT stack in argument space
sidt fword ptr [rsp + 50h] ; save IDT stack in argument space
mov rax, cr0
mov [rcx + (SavedCr0 - SavedCr4)], eax
and eax, 7ffffffeh ; clear PE, PG bits
@ -270,17 +277,20 @@ InternalAsmThunk16 PROC USES rbp rbx rsi rdi
push r8
mov r8d, cs
mov [rcx + (SavedCs - SavedCr4)], r8w
mov r8, rsp
mov [rcx + (SavedSp - SavedCr4)], esp
jmp fword ptr [rcx + (_EntryPoint - SavedCr4)]
@RetFromRealMode:
popfq
lidt fword ptr [rsp + 38h] ; restore protected mode IDTR
lidt fword ptr [rsp + 50h] ; restore protected mode IDTR
lea eax, [rbp - sizeof (IA32_REGS)]
pop gs
pop fs
mov ss, r9d
mov es, r11d
mov ds, r10d
pop rbx
mov ss, rbx
pop rbx
mov es, rbx
pop rbx
mov ds, rbx
ret
InternalAsmThunk16 ENDP