summaryrefslogtreecommitdiff
path: root/ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm')
-rw-r--r--ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm216
1 files changed, 216 insertions, 0 deletions
diff --git a/ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm b/ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm
new file mode 100644
index 0000000..89bb447
--- /dev/null
+++ b/ReferenceCode/Haswell/Library/ThunkLib/x64/Thunk16.asm
@@ -0,0 +1,216 @@
+;/*++
+; This file contains an 'Intel Peripheral Driver' and is
+; licensed for Intel CPUs and chipsets under the terms of your
+; license agreement with Intel or your vendor. This file may
+; be modified by the user, subject to additional terms of the
+; license agreement
+;--*/
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2006 - 2010 Intel Corporation. All rights reserved
+; This software and associated documentation (if any) is furnished
+; under a license and may only be used or copied in accordance
+; with the terms of the license. Except as permitted by such
+; license, no part of this software or documentation may be
+; reproduced, stored in a retrieval system, or transmitted in any
+; form or by any means without the express written consent of
+; Intel Corporation.
+;
+; 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
+
+_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 ;NOT 080000001h ; 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:
+ mov cr0, rsi ; disable PE & PG
+ DB 66h
+ mov ecx, 0c0000080h
+ 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