diff options
author | qhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-04-17 07:47:08 +0000 |
---|---|---|
committer | qhuang8 <qhuang8@6f19259b-4bc3-4df7-8a09-765794883524> | 2009-04-17 07:47:08 +0000 |
commit | 1e4371671bb4e564b2dbedb4ceb23006942d4b41 (patch) | |
tree | 6c5bb5b1b868eaf0713c0f92344d0fde9e378c37 | |
parent | 0fe43214e33e4276741872a783528d896d82e785 (diff) | |
download | edk2-platforms-1e4371671bb4e564b2dbedb4ceb23006942d4b41.tar.xz |
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@8124 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r-- | EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.S | 95 | ||||
-rw-r--r-- | EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.asm | 30 |
2 files changed, 73 insertions, 52 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.S b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.S index 9fddda5ab0..ad2775f71d 100644 --- a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.S +++ b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.S @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ # -# Copyright (c) 2006 - 2008, Intel Corporation +# Copyright (c) 2006 - 2009, Intel Corporation # All rights reserved. This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -18,6 +18,7 @@ # Real mode thunk # #------------------------------------------------------------------------------ + #include <EdkIIGlueBase.h> .globl ASM_PFX(m16Start) @@ -51,7 +52,7 @@ ASM_PFX(m16Size): .word ASM_PFX(InternalAsmThunk16) - ASM_PFX(m16Start) ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start) -ASM_PFX(m16Gdt): .word _NullSeg - ASM_PFX(m16Start) +ASM_PFX(m16Gdt): .word ASM_PFX(NullSeg) - ASM_PFX(m16Start) ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start) ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start) @@ -78,8 +79,8 @@ ASM_PFX(BackFromUserCode): .byte 0x16 # push ss .byte 0xe # push cs .byte 0x66 - call @Base # push eip -@Base: + call L_Base # push eip +L_Base: .byte 0x66 pushq $0 # reserved high order 32 bits of EFlags .byte 0x66, 0x9c # pushfd actually @@ -92,17 +93,17 @@ ASM_PFX(BackFromUserCode): .byte 0x66,0xba # mov edx, imm32 _ThunkAttr: .space 4 testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl - jz @1 + jz L_1 movl $0x15cd2401,%eax # mov ax, 2401h & int 15h cli # disable interrupts - jnc @2 -@1: + jnc L_2 +L_1: testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl - jz @2 + jz L_2 inb $0x92,%al orb $2,%al outb %al, $0x92 # deactivate A20M# -@2: +L_2: movl %ss,%eax lea IA32_REGS_SIZE(%esp), %bp # @@ -115,9 +116,9 @@ _ThunkAttr: .space 4 addw %ax,%bp # add ebp, eax movw %cs,%ax shlw $4,%ax - lea (@64BitCode - @Base)(%ebx, %eax), %ax - .byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (@64Eip - @Base)], eax - .word @64Eip - @Base + lea (L_64BitCode - L_Base)(%ebx, %eax), %ax + .byte 0x66,0x2e,0x89,0x87 # mov cs:[bx + (L_64Eip - L_Base)], eax + .word L_64Eip - L_Base .byte 0x66,0xb8 # mov eax, imm32 SavedCr4: .space 4 movq %rax, %cr4 @@ -125,7 +126,7 @@ SavedCr4: .space 4 # rdi in the instruction below is indeed bx in 16-bit code # .byte 0x66,0x2e # 2eh is "cs:" segment override - lgdt (SavedGdt - @Base)(%rdi) + lgdt (SavedGdt - L_Base)(%rdi) .byte 0x66 movl $0xc0000080,%ecx rdmsr @@ -134,17 +135,20 @@ SavedCr4: .space 4 .byte 0x66,0xb8 # mov eax, imm32 SavedCr0: .space 4 movq %rax, %cr0 - .byte 0x66,0xea # jmp far cs:@64Bit -@64Eip: .space 4 + .byte 0x66,0xea # jmp far cs:L_64Bit +L_64Eip: .space 4 SavedCs: .space 2 -@64BitCode: - movq %r8, %rsp +L_64BitCode: + .byte 0x90 + .byte 0x67,0xbc # mov esp, imm32 +SavedSp: .space 4 # restore stack + nop ret _EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start) .word CODE16 _16Gdtr: .word GDT_SIZE - 1 -_16GdtrBase: .quad _NullSeg +_16GdtrBase: .quad ASM_PFX(NullSeg) _16Idtr: .word 0x3ff .long 0 @@ -169,16 +173,16 @@ ASM_PFX(ToUserCode): movl %esi,%ss # set up 16-bit stack segment movw %bx,%sp # set up 16-bit stack pointer .byte 0x66 # make the following call 32-bit - call @Base1 # push eip -@Base1: - popw %bp # ebp <- address of @Base1 + call L_Base1 # push eip +L_Base1: + popw %bp # ebp <- address of L_Base1 pushq (IA32_REGS_SIZE + 2)(%esp) lea 0x0c(%rsi), %eax pushq %rax lret # execution begins at next instruction -@RealMode: +L_RealMode: .byte 0x66,0x2e # CS and operand size override - lidt (_16Idtr - @Base1)(%rsi) + lidt (_16Idtr - L_Base1)(%rsi) .byte 0x66,0x61 # popad .byte 0x1f # pop ds .byte 0x7 # pop es @@ -189,26 +193,26 @@ ASM_PFX(ToUserCode): .byte 0x66 # make the following retf 32-bit lret # transfer control to user code -.equ CODE16, ASM_PFX(16Code) - . -.equ DATA16, ASM_PFX(16Data) - . -.equ DATA32, ASM_PFX(32Data) - . +.equ CODE16, ASM_PFX(_16Code) - . +.equ DATA16, ASM_PFX(_16Data) - . +.equ DATA32, ASM_PFX(_32Data) - . -_NullSeg: .quad 0 -ASM_PFX(16Code): +ASM_PFX(NullSeg): .quad 0 +ASM_PFX(_16Code): .word -1 .word 0 .byte 0 .byte 0x9b .byte 0x8f # 16-bit segment, 4GB limit .byte 0 -ASM_PFX(16Data): +ASM_PFX(_16Data): .word -1 .word 0 .byte 0 .byte 0x93 .byte 0x8f # 16-bit segment, 4GB limit .byte 0 -ASM_PFX(32Data): +ASM_PFX(_32Data): .word -1 .word 0 .byte 0 @@ -226,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): @@ -235,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 @@ -258,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 @@ -272,22 +279,26 @@ ASM_PFX(InternalAsmThunk16): movl %edx,%ss pushfq lea -8(%rdx), %edx - lea @RetFromRealMode, %r8 + lea L_RetFromRealMode, %r8 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 -@RetFromRealMode: +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 diff --git a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.asm b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.asm index 0c3bb7df26..05d7e5ed1e 100644 --- a/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.asm +++ b/EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/BaseLib/X64/Thunk16.asm @@ -138,7 +138,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
@@ -228,9 +231,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
@@ -250,7 +257,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
@@ -268,17 +275,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
|