diff options
Diffstat (limited to 'EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm')
-rw-r--r-- | EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm | 216 |
1 files changed, 216 insertions, 0 deletions
diff --git a/EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm b/EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm new file mode 100644 index 0000000000..641e8d285f --- /dev/null +++ b/EdkCompatibilityPkg/Foundation/Library/Thunk16/X64/Thunk16.asm @@ -0,0 +1,216 @@ +;*****************************************************************************
+;*
+;* Copyright (c) 2006, 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
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;* Module Name:
+;*
+;* Thunk.asm
+;*
+;* Abstract:
+;*
+;* Real mode thunk
+;*
+;*****************************************************************************
+
+EXTERNDEF mCode16Size:QWORD
+
+ .const
+
+mCode16Size DQ _Code16End - _Code16Addr
+
+ .data
+
+NullSegSel DQ 0
+_16CsSegSel LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 9bh
+ DB 8fh ; 16-bit segment
+ DB 0
+_16DsSegSel LABEL QWORD
+ DW -1
+ DW 0
+ DB 0
+ DB 93h
+ DB 8fh ; 16-bit segment
+ DB 0
+
+_16Gdtr LABEL FWORD
+ DW $ - offset NullSegSel - 1
+ DQ offset NullSegSel
+
+ .code
+
+IA32_REGS STRUC 4t
+_EDI DD ?
+_ESI DD ?
+_EBP DD ?
+_ESP DD ?
+_EBX DD ?
+_EDX DD ?
+_ECX DD ?
+_EAX DD ?
+_DS DW ?
+_ES DW ?
+_FS DW ?
+_GS DW ?
+_RFLAGS DQ ?
+_EIP DD ?
+_CS DW ?
+_SS DW ?
+IA32_REGS ENDS
+
+_STK16 STRUC 1t
+RetEip DD ?
+RetCs DW ?
+ThunkFlags DW ?
+SavedGdtr FWORD ?
+Resvd1 DW ?
+SavedCr0 DD ?
+SavedCr4 DD ?
+_STK16 ENDS
+
+_Thunk16 PROC USES rbp rbx rsi rdi r12 r13 r14 r15
+
+ push fs
+ push gs
+
+ mov r12d, ds
+ mov r13d, es
+ mov r14d, ss
+ mov r15, rsp
+ mov rsi, rcx
+ movzx r10, (IA32_REGS ptr [rsi])._SS
+ xor rdi, rdi
+ mov edi, (IA32_REGS ptr [rsi])._ESP
+ add rdi, - sizeof (IA32_REGS) - sizeof (_STK16)
+ push rdi
+ imul rax, r10, 16
+ add rdi, rax
+ push sizeof (IA32_REGS) / 4
+ pop rcx
+ rep movsd
+ pop rbx ; rbx <- 16-bit stack offset
+ lea eax, @F ; return offset
+ stosd
+ mov eax, cs ; return segment
+ stosw
+ mov eax, edx ; THUNK Flags
+ stosw
+ sgdt fword ptr [rsp + 58h] ; save GDTR
+ mov rax, [rsp + 58h]
+ stosq
+ mov rax, cr0 ; save CR0
+ mov esi, eax ; esi <- CR0 to set
+ stosd
+ mov rax, cr4 ; save CR4
+ stosd
+ sidt fword ptr [rsp + 58h] ; save IDTR
+ and esi, 07ffffffeh ; clear PE & PG bits
+ mov rdi, r10 ; rdi <- 16-bit stack segment
+
+ shl r8, 16
+ push r8 ; far jmp address
+ lea eax, @16Bit
+ push rax
+ mov word ptr [rsp + 4], 8
+ lgdt _16Gdtr
+ retf
+@16Bit:
+ DB 66h
+ mov ecx, 0c0000080h
+ mov cr0, rsi ; disable PE & PG
+ rdmsr
+ and ah, NOT 1
+ wrmsr ; clear LME bit
+ mov rax, cr4
+ and al, NOT 30h ; clear PAE & PSE
+ mov cr4, rax
+ retf
+@@:
+ xor rax, rax
+ mov eax, ss
+ shl eax, 4
+ add eax, esp ; rax <- address of 16-bit stack
+ mov rsp, r15
+ lidt fword ptr [rsp + 58h] ; restore IDTR
+ mov ds, r12d
+ mov es, r13d
+ mov ss, r14d
+ pop gs
+ pop fs
+ ret
+_Thunk16 ENDP
+
+ ALIGN 10h
+
+_Code16Addr PROC
+_Code16Addr ENDP
+
+RealMode PROC
+ mov ss, edi
+ mov sp, bx ; set up 16-bit stack
+ DB 2eh, 0fh, 1, 1eh
+ DW _16Idtr - _Code16Addr ; lidt _16Idtr
+ DB 66h, 61h ; popad
+ DB 1fh ; pop ds
+ DB 7 ; pop es
+ pop fs
+ pop gs
+
+ add esp, 8 ; skip RFLAGS
+ DB 67h, 0f7h, 44h, 24h, 0eh, 1, 0 ; test [esp + 0eh], 1
+ jz @F
+ pushfq ; pushf, actually
+@@:
+ DB 0eh ; push cs
+ DB 68h ; push /iw
+ DW @FarCallRet - _Code16Addr
+ jz @F
+ DB 66h
+ jmp fword ptr [esp + 6]
+@@:
+ DB 66h
+ jmp fword ptr [esp + 4]
+@FarCallRet:
+ DB 66h
+ push 0 ; push a dword of zero
+ pushf ; pushfd, actually
+ push gs
+ push fs
+ DB 6 ; push es
+ DB 1eh ; push ds
+ DB 66h, 60h ; pushad
+ cli
+
+ DB 66h
+ lgdt (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedGdtr
+ DB 66h
+ mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr4
+ mov cr4, rax
+ DB 66h
+ mov ecx, 0c0000080h
+ rdmsr
+ or ah, 1
+ wrmsr ; set LME
+ DB 66h
+ mov eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr0
+ mov cr0, rax
+ DB 66h
+ jmp fword ptr (_STK16 ptr [esp + sizeof(IA32_REGS)]).RetEip
+
+RealMode ENDP
+
+_16Idtr FWORD (1 SHL 10) - 1
+
+_Code16End:
+
+ END
|