• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1;*****************************************************************************
2;*
3;*   Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
4;*   This program and the accompanying materials
5;*   are licensed and made available under the terms and conditions of the BSD License
6;*   which accompanies this distribution.  The full text of the license may be found at
7;*   http://opensource.org/licenses/bsd-license.php
8;*
9;*   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10;*   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11;*
12;*   Module Name:
13;*
14;*    Thunk.asm
15;*
16;*   Abstract:
17;*
18;*    Real mode thunk
19;*
20;*****************************************************************************
21
22EXTERNDEF   mCode16Size:QWORD
23
24    .const
25
26mCode16Size     DQ      _Code16End - _Code16Addr
27
28    .data
29
30NullSegSel      DQ      0
31_16CsSegSel     LABEL   QWORD
32                DW      -1
33                DW      0
34                DB      0
35                DB      9bh
36                DB      8fh             ; 16-bit segment
37                DB      0
38_16DsSegSel     LABEL   QWORD
39                DW      -1
40                DW      0
41                DB      0
42                DB      93h
43                DB      8fh             ; 16-bit segment
44                DB      0
45
46_16Gdtr         LABEL   FWORD
47                DW      $ - offset NullSegSel - 1
48                DQ      offset NullSegSel
49
50    .code
51
52STACK_PARAM_SIZE  EQU  16
53
54IA32_REGS   STRUC   4t
55_EDI        DD      ?
56_ESI        DD      ?
57_EBP        DD      ?
58_ESP        DD      ?
59_EBX        DD      ?
60_EDX        DD      ?
61_ECX        DD      ?
62_EAX        DD      ?
63_DS         DW      ?
64_ES         DW      ?
65_FS         DW      ?
66_GS         DW      ?
67_RFLAGS     DQ      ?
68_EIP        DD      ?
69_CS         DW      ?
70_SS         DW      ?
71IA32_REGS   ENDS
72
73_STK16      STRUC   1t
74RetEip      DD      ?
75RetCs       DW      ?
76ThunkFlags  DW      ?
77SavedGdtr   FWORD   ?
78Resvd1      DW      ?
79SavedCr0    DD      ?
80SavedCr4    DD      ?
81_STK16      ENDS
82
83_Thunk16    PROC    USES    rbp rbx rsi rdi r12 r13 r14 r15
84
85    push    fs
86    push    gs
87
88    mov     r12d, ds
89    mov     r13d, es
90    mov     r14d, ss
91    mov     r15, rsp
92    mov     rsi, rcx
93    movzx   r10, (IA32_REGS ptr [rsi])._SS
94    xor     rdi, rdi
95    mov     edi, (IA32_REGS ptr [rsi])._ESP
96    add     rdi, - sizeof (IA32_REGS) - sizeof (_STK16)
97    push    rdi
98    imul    rax, r10, 16
99    add     rdi, rax
100    push    sizeof (IA32_REGS) / 4
101    pop     rcx
102    rep     movsd
103
104    ; copy eflags to stack frame
105    mov     rax, (IA32_REGS ptr [rsi - sizeof(IA32_REGS)])._RFLAGS
106    mov     [rdi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 8], rax
107
108    pop     rbx                         ; rbx <- 16-bit stack offset
109    lea     eax, @F                     ; return offset
110    stosd
111    mov     eax, cs                     ; return segment
112    stosw
113    mov     eax, edx                    ; THUNK Flags
114    stosw
115    sgdt    fword ptr [rsp + 58h]       ; save GDTR
116    mov     rax, [rsp + 58h]
117    stosq
118    mov     rax, cr0                    ; save CR0
119    mov     esi, eax                    ; esi <- CR0 to set
120    stosd
121    mov     rax, cr4                    ; save CR4
122    stosd
123    sidt    fword ptr [rsp + 58h]       ; save IDTR
124    and     esi, 07ffffffeh             ; clear PE & PG bits
125    mov     rdi, r10                    ; rdi <- 16-bit stack segment
126
127    shl     r8, 16
128    push    r8                          ; far jmp address
129    lea     eax, @16Bit
130    push    rax
131    mov     word ptr [rsp + 4], 8
132    lgdt    _16Gdtr
133    retf
134@16Bit:
135    DB      66h
136    mov     ecx, 0c0000080h
137    mov     cr0, rsi                    ; disable PE & PG
138    rdmsr
139    and     ah, NOT 1
140    wrmsr                               ; clear LME bit
141    mov     rax, cr4
142    and     al, NOT 30h                 ; clear PAE & PSE
143    mov     cr4, rax
144    retf
145@@:
146    xor     rax, rax
147    mov     ax, ss
148    shl     eax, 4
149    add     eax, esp                    ; rax <- address of 16-bit stack
150    mov     rsp, r15
151    lidt    fword ptr [rsp + 58h]       ; restore IDTR
152    mov     ds, r12d
153    mov     es, r13d
154    mov     ss, r14d
155    pop     gs
156    pop     fs
157    ret
158_Thunk16    ENDP
159
160    ALIGN   10h
161
162_Code16Addr PROC
163_Code16Addr ENDP
164
165RealMode    PROC
166    mov     ss, edi
167    mov     sp, bx                      ; set up 16-bit stack
168    DB      2eh, 0fh, 1, 1eh
169    DW      _16Idtr - _Code16Addr       ; lidt _16Idtr
170    DB      66h, 61h                    ; popad
171    DB      1fh                         ; pop ds
172    DB      7                           ; pop es
173    pop     fs
174    pop     gs
175    sub     esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
176
177    DB      66h, 9Dh                    ; popfd
178    add     esp, 4                      ; skip high part of RFLAGS
179    DB      67h, 0f7h, 44h, 24h         ; test    (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1
180    DB      (STACK_PARAM_SIZE + sizeof(IA32_REGS) + 6)
181    DB      1, 0
182    jz      @F
183    pushfq                              ; pushf, actually, when it's INT#
184@@:
185    DB      0eh                         ; push cs
186    DB      68h                         ; push /iw
187    DW      @FarCallRet - _Code16Addr
188    jz      @F
189    DB      66h
190    jmp     fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
191@@:
192    DB      66h
193    jmp     fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8]
194@FarCallRet:
195    add     esp, (sizeof(IA32_REGS) - 16) + STACK_PARAM_SIZE + 8
196    DB      66h
197    push    0                           ; push a dword of zero
198    pushf                               ; pushfd, actually
199    push    gs
200    push    fs
201    DB      6                           ; push es
202    DB      1eh                         ; push ds
203    DB      66h, 60h                    ; pushad
204    cli
205
206    DB      66h
207    lgdt    (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedGdtr
208    DB      66h
209    mov     eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr4
210    mov     cr4, rax
211    DB      66h
212    mov     ecx, 0c0000080h
213    rdmsr
214    or      ah, 1
215    wrmsr                               ; set LME
216    DB      66h
217    mov     eax, (_STK16 ptr [esp + sizeof(IA32_REGS)]).SavedCr0
218    mov     cr0, rax
219    DB      66h
220    jmp     fword ptr (_STK16 ptr [esp + sizeof(IA32_REGS)]).RetEip
221
222RealMode    ENDP
223
224_16Idtr     FWORD   (1 SHL 10) - 1
225
226_Code16End:
227
228    END
229