1 ;***************************************************************************** 2 ;* 3 ;* Copyright (c) 2006 - 2011, 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 22 .686p 23 24 EXTERNDEF C mCode16Size:DWORD 25 26 CONST SEGMENT FLAT "DATA" READONLY 27 28 mCode16Size DD _TEXT16SIZE 29 30 CONST ENDS 31 32 _DATA SEGMENT FLAT "DATA" 33 34 NullSegSel DQ 0 35 _16BitCsSel LABEL QWORD 36 DW -1 37 DW 0 38 DB 0 39 DB 9bh 40 DB 8fh ; 16-bit segment 41 DB 0 42 _16BitSsSel LABEL QWORD 43 DW -1 44 DW 0 45 DB 0 46 DB 93h 47 DB 8fh ; 16-bit segment 48 DB 0 49 50 _16Gdtr LABEL FWORD 51 DW $ - offset NullSegSel - 1 52 DD offset NullSegSel 53 54 _DATA ENDS 55 56 _TEXT SEGMENT FLAT "CODE" PARA 57 58 STACK_PARAM_SIZE EQU 16 59 60 IA32_REGS STRUC 4t 61 _EDI DD ? 62 _ESI DD ? 63 _EBP DD ? 64 _ESP DD ? 65 _EBX DD ? 66 _EDX DD ? 67 _ECX DD ? 68 _EAX DD ? 69 _DS DW ? 70 _ES DW ? 71 _FS DW ? 72 _GS DW ? 73 _EFLAGS DD ? 74 _EIP DD ? 75 _CS DW ? 76 _SS DW ? 77 IA32_REGS ENDS 78 79 _STK16 STRUC 1t 80 RetEip DD ? 81 RetCs DW ? 82 ThunkFlags DW ? 83 SavedEsp DD ? 84 SavedSs DW ? 85 SavedGdtr FWORD ? 86 SavedCr0 DD ? 87 SavedCr4 DD ? 88 _STK16 ENDS 89 90 ASSUME ds:_DATA 91 92 __Thunk16 PROC USES ebp ebx esi edi ds es fs gs 93 ASSUME esi:PTR IA32_REGS 94 mov esi, [esp + 36] 95 movzx edx, [esi]._SS 96 mov edi, [esi]._ESP 97 add edi, - sizeof (_STK16) - sizeof (IA32_REGS) 98 push edi ; save stack offset 99 imul eax, edx, 16 ; eax <- edx*16 100 add edi, eax ; edi <- linear address of 16-bit stack 101 push sizeof (IA32_REGS) / 4 102 pop ecx 103 rep movsd ; copy context to 16-bit stack 104 105 ; copy eflags to stack frame 106 mov eax, [esi - sizeof(IA32_REGS)]._EFLAGS 107 mov [edi - sizeof(IA32_REGS) - STACK_PARAM_SIZE - 4], eax 108 109 pop ebx ; ebx <- 16-bit stack offset 110 mov eax, offset @F ; return offset 111 stosd 112 mov eax, cs ; return segment 113 stosw 114 mov eax, [esp + 40] ; THUNK flags 115 stosw 116 mov eax, esp 117 stosd ; save esp 118 mov eax, ss ; save ss 119 stosw 120 sgdt fword ptr [edi] ; save GDTR 121 sidt fword ptr [esp + 36] ; save IDTR 122 mov esi, cr0 123 mov [edi + 6], esi ; save CR0 124 and esi, NOT 80000001h ; esi <- CR0 to set 125 mov eax, cr4 126 mov [edi + 10], eax ; save CR4 127 and al, NOT 30h ; clear PAE & PSE 128 mov edi, edx ; edi <- 16-bit stack segment 129 mov edx, [esp + 44] 130 shl edx, 16 131 push edx 132 pop edx 133 mov dx, _16BitSsSel - NullSegSel 134 lgdt _16Gdtr ; load 16-bit GDTR 135 DB 0eah 136 DD offset @16Bit 137 DW _16BitCsSel - NullSegSel ; jmp far 8:@16Bit 138 @16Bit: 139 mov ss, dx 140 mov cr0, esi ; disable protected mode 141 mov cr4, eax ; disable PAE & PSE 142 db 67h, 0FFh, 06Ch, 024h, 0FCh ; jmp dword ptr [esp-4] 143 @@: 144 xor eax, eax 145 mov ax, ss 146 shl eax, 4 147 add eax, esp ; eax <- address of 16-bit stack 148 lss esp, fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedEsp 149 lidt fword ptr [esp + 36] ; restore IDTR 150 ret 151 __Thunk16 ENDP 152 153 _TEXT ENDS 154 155 _TEXT16 SEGMENT USE16 "CODE" PARA 156 157 _Code16Addr PROC C 158 _Code16Addr ENDP 159 160 RealMode PROC 161 mov ss, di ; set up stack 162 mov esp, ebx 163 lidt fword ptr cs:[_16Idtr - _Code16Addr] 164 popad 165 pop ds 166 pop es 167 pop fs 168 pop gs 169 sub esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4 170 popfd 171 test (_STK16 ptr [esp + STACK_PARAM_SIZE + sizeof(IA32_REGS)]).ThunkFlags, 1 172 jz @F 173 pushf ; push Flags when it's INT# 174 @@: 175 push cs 176 ; push @FarCallRet - _Code16Addr 177 DB 68h ; push /iw 178 DW @FarCallRet - _Code16Addr 179 jz @F 180 jmp fword ptr [esp + 6 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8] 181 @@: 182 jmp fword ptr [esp + 4 + STACK_PARAM_SIZE + sizeof(IA32_REGS) - 8] 183 @FarCallRet: 184 add esp, (sizeof(IA32_REGS) - 12) + STACK_PARAM_SIZE + 4 185 pushfd 186 push gs 187 push fs 188 push es 189 push ds 190 pushad 191 cli 192 DB 66h 193 lgdt (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedGdtr 194 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr4 195 mov cr4, eax 196 mov eax, (_STK16 ptr [esp + sizeof (IA32_REGS)]).SavedCr0 197 mov cr0, eax ; restore CR0 198 jmp fword ptr (_STK16 ptr [esp + sizeof (IA32_REGS)]).RetEip 199 RealMode ENDP 200 201 _16Idtr FWORD (1 SHL 10) - 1 202 203 _TEXT16END: 204 205 _TEXT16SIZE = _TEXT16END - _Code16Addr 206 207 _TEXT16 ENDS 208 209 END 210