2d62d72aef5bc3b728a7124653e3da9f335a2d6c
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / Thunk16.asm
1 ;------------------------------------------------------------------------------
2 ;
3 ; Copyright (c) 2006, Intel Corporation
4 ; All rights reserved. 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 .model flat,C
24
25 .data
26
27 NullSegSel DQ 0
28 _16BitCsSel LABEL QWORD
29 DW -1
30 DW 0
31 DB 0
32 DB 9bh
33 DB 8fh ; 16-bit segment
34 DB 0
35 _16BitDsSel LABEL QWORD
36 DW -1
37 DW 0
38 DB 0
39 DB 93h
40 DB 8fh ; 16-bit segment
41 DB 0
42 GdtEnd LABEL QWORD
43
44 .const
45
46 _16Gdtr LABEL FWORD
47 DW offset GdtEnd - offset NullSegSel - 1
48 DD offset NullSegSel
49
50 _16Idtr FWORD (1 SHL 10) - 1
51
52 .code
53
54 IA32_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 _EFLAGS DD ?
68 _EIP DD ?
69 _CS DW ?
70 _SS DW ?
71 IA32_REGS ENDS
72
73 InternalAsmThunk16 PROC USES ebp ebx esi edi ds es fs gs
74 mov esi, [esp + 36] ; esi <- RegSet
75 push sizeof (IA32_REGS)
76 pop ecx
77 movzx edx, (IA32_REGS ptr [esi])._SS
78 mov edi, (IA32_REGS ptr [esi])._ESP
79 sub edi, ecx ; reserve space on realmode stack
80 push edi ; save stack offset
81 imul eax, edx, 16 ; eax <- edx * 16
82 add edi, eax ; edi <- linear address of 16-bit stack
83 rep movsb ; copy RegSet
84 mov esi, edx ; esi <- 16-bit stack segment
85 pop ebx ; ebx <- 16-bit stack offset
86 mov edi, [esp + 40] ; edi <- realmode patch
87 push cs ; save CS segment selector
88 push offset @BackToThunk ; offset to back from real mode
89 mov eax, offset @16Return
90 stosd
91 xor eax, eax
92 stosw ; set CS base to 0
93 mov eax, esp
94 stosd
95 mov eax, ss
96 stosd
97 mov eax, cr0
98 mov ecx, eax ; ecx <- CR0
99 and ecx, 7ffffffeh ; clear PE, PG bits
100 stosd
101 mov eax, cr4
102 mov ebp, eax
103 and ebp, 300h ; clear all but PCE and OSFXSR bits
104 stosd
105 sidt fword ptr [esp + 44] ; use parameter space to save IDTR
106 sgdt fword ptr [edi]
107 lidt _16Idtr
108 push 10h
109 pop eax
110 push 8
111 push offset @16Start
112 lgdt _16Gdtr
113 retf
114 @16Start: ; 16-bit starts here
115 mov ss, eax ; set SS to be a 16-bit segment
116 mov cr0, ecx
117 mov cr4, ebp
118 mov ss, esi ; set up 16-bit stack
119 mov sp, bx ; mov esp, ebx actually
120 popaw ; popad actually
121 pop ds
122 pop es
123 pop fs
124 pop gs
125 add sp, 4 ; skip _EFLAGS
126 DB 66h
127 retf ; transfer control to 16-bit code
128 @16Return:
129 pushf ; pushfd actually
130 push gs
131 push fs
132 push es
133 push ds
134 pushaw ; pushad actually
135 DB 67h, 66h
136 lds esi, fword ptr (IA32_REGS ptr [esp])._EIP
137 DB 67h, 66h
138 mov eax, [esi + 12]
139 mov cr4, eax ; restore CR4
140 DB 67h, 66h
141 lgdt fword ptr [esi + 16]
142 DB 67h, 66h
143 mov eax, [esi + 8]
144 mov cr0, eax ; restore CR0
145 xor ax, ax ; xor eax, eax actually
146 mov eax, ss
147 DB 67h
148 mov dword ptr (IA32_REGS ptr [esp])._SS, eax
149 shl ax, 4 ; shl eax, 4 actually
150 add ax, sp ; add eax, esp actually
151 add sp, sizeof (IA32_REGS) ; add esp, sizeof (IA32_REGS)
152 DB 67h, 66h
153 mov dword ptr (IA32_REGS ptr [esp - sizeof (IA32_REGS)])._ESP, esp
154 DB 67h, 66h
155 lss esp, fword ptr [esi] ; restore protected mode stack
156 DB 66h
157 retf ; go back to protected mode
158 @BackToThunk:
159 lidt fword ptr [esp + 36] ; restore protected mode IDTR
160 ret
161 InternalAsmThunk16 ENDP
162
163 END