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

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

View File

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