]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/Ia32/Thunk16.S
Import some basic libraries instances for Mde Packages.
[mirror_edk2.git] / MdePkg / Library / BaseLib / Ia32 / Thunk16.S
CommitLineData
e1f414b6 1//\r
2// Include common header file for this module.\r
3//\r
4#include "CommonHeader.h"\r
5\r
6#------------------------------------------------------------------------------\r
7#\r
8# Copyright (c) 2006, Intel Corporation\r
9# All rights reserved. This program and the accompanying materials\r
10# are licensed and made available under the terms and conditions of the BSD License\r
11# which accompanies this distribution. The full text of the license may be found at\r
12# http://opensource.org/licenses/bsd-license.php\r
13#\r
14# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
15# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
16#\r
17# Module Name:\r
18#\r
19# Thunk16.S\r
20#\r
21# Abstract:\r
22#\r
23# Real mode thunk\r
24#\r
25#------------------------------------------------------------------------------\r
26\r
27.globl ASM_PFX(m16Start), ASM_PFX(m16Size), ASM_PFX(mThunk16Attr), ASM_PFX(m16Gdt), ASM_PFX(m16GdtrBase), ASM_PFX(mTransition)\r
28.globl ASM_PFX(InternalAsmThunk16)\r
29\r
30ASM_PFX(m16Start):\r
31\r
32SavedGdt: .space 6\r
33\r
34ASM_PFX(BackFromUserCode):\r
35 push %ss\r
36 push %cs\r
37 .byte 0x66\r
38 call L_Base1 # push eip\r
39L_Base1:\r
40 pushfw # pushfd actually\r
41 cli # disable interrupts\r
42 push %gs\r
43 push %fs\r
44 push %es\r
45 push %ds\r
46 pushaw # pushad actually\r
47 .byte 0x66, 0xba # mov edx, imm32\r
48ASM_PFX(ThunkAttr): .space 4\r
49 testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15, %dl\r
50 jz 1f\r
51 movl $0x15cd2401, %eax # mov ax, 2401h & int 15h\r
52 cli # disable interrupts\r
53 jnc 2f\r
541:\r
55 testb $THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL, %dl\r
56 jz 2f\r
57 inb $0x92, %al\r
58 orb $2, %al\r
59 outb %al, $0x92 # deactivate A20M#\r
602:\r
61 movl %ss, %eax\r
62 .byte 0x67, 0x66, 0x8d, 0x6c, 0x24, 0x34, 0x66\r
63 mov %ebp, 0xffffffd8(%esi)\r
64 mov 0xfffffff8(%esi), %ebx\r
65 shlw $4, %ax # shl eax, 4\r
66 addw %ax, %bp # add ebp, eax\r
67 .byte 0x66, 0xb8 # mov eax, imm32\r
68SavedCr4: .space 4\r
69 movl %eax, %cr4\r
70 lgdtw %cs:0xfffffff2(%edi)\r
71 .byte 0x66, 0xb8 # mov eax, imm32\r
72SavedCr0: .space 4\r
73 movl %eax, %cr0\r
74 .byte 0xb8 # mov ax, imm16\r
75SavedSs: .space 2\r
76 movl %eax, %ss\r
77 .byte 0x66, 0xbc # mov esp, imm32\r
78SavedEsp: .space 4\r
79 .byte 0x66\r
80 lret # return to protected mode\r
81\r
82_EntryPoint: .long ASM_PFX(ToUserCode) - ASM_PFX(m16Start)\r
83 .word 0x8\r
84_16Idtr: .word 0x3ff\r
85 .long 0\r
86_16Gdtr: .word GdtEnd - _NullSegDesc - 1\r
87_16GdtrBase: .long _NullSegDesc\r
88\r
89ASM_PFX(ToUserCode):\r
90 movl %ss, %edx\r
91 movl %ecx, %ss # set new segment selectors\r
92 movl %ecx, %ds\r
93 movl %ecx, %es\r
94 movl %ecx, %fs\r
95 movl %ecx, %gs\r
96 movl %eax, %cr0\r
97 movl %ebp, %cr4 # real mode starts at next instruction\r
98 movl %esi, %ss # set up 16-bit stack segment\r
99 xchgw %bx, %sp # set up 16-bit stack pointer\r
100 .byte 0x66\r
101 call L_Base # push eip\r
102L_Base:\r
103 popw %bp # ebp <- offset L_Base\r
104 addr16 pushl 36(%si)\r
105 .byte 0x36\r
106 lea 0xc(%esi), %eax\r
107 push %eax\r
108 lret\r
109\r
110L_RealMode:\r
111 mov %edx, %cs:0xffffffc5(%esi)\r
112 mov %bx, %cs:0xffffffcb(%esi)\r
113 lidtw %cs:0xffffffd7(%esi)\r
114 popaw # popad actually\r
115 pop %ds\r
116 pop %es\r
117 pop %fs\r
118 pop %gs\r
119 popfw # popfd\r
120 lretw # transfer control to user code\r
121\r
122_NullSegDesc: .quad 0\r
123_16CsDesc:\r
124 .word -1\r
125 .word 0\r
126 .byte 0\r
127 .byte 0x9b\r
128 .byte 0x8f # 16-bit segment, 4GB limit\r
129 .byte 0\r
130_16DsDesc:\r
131 .word -1\r
132 .word 0\r
133 .byte 0\r
134 .byte 0x93\r
135 .byte 0x8f # 16-bit segment, 4GB limit\r
136 .byte 0\r
137GdtEnd:\r
138\r
139#\r
140# @param RegSet Pointer to a IA32_DWORD_REGS structure\r
141# @param Transition Pointer to the transition code\r
142# @return The address of the 16-bit stack after returning from user code\r
143#\r
144ASM_PFX(InternalAsmThunk16):\r
145 push %ebp\r
146 push %ebx\r
147 push %esi\r
148 push %edi\r
149 push %ds\r
150 push %es\r
151 push %fs\r
152 push %gs\r
153 movl 36(%esp), %esi # esi <- RegSet\r
154 movzwl 0x32(%esi), %edx\r
155 mov 0xc(%esi), %edi\r
156 add $0xffffffc8, %edi\r
157 movl %edi, %ebx # ebx <- stack offset\r
158 imul $0x10, %edx, %eax\r
159 push $0xd\r
160 addl %eax, %edi # edi <- linear address of 16-bit stack\r
161 pop %ecx\r
162 rep\r
163 movsl # copy RegSet\r
164 movl 40(%esp), %eax # eax <- address of transition code\r
165 movl %edx, %esi # esi <- 16-bit stack segment\r
166 lea 0x5e(%eax), %edx\r
167 movl %eax, %ecx\r
168 andl $0xf, %ecx\r
169 shll $12, %eax\r
170 lea 0x6(%ecx), %ecx\r
171 movw %cx, %ax\r
172 stosl # [edi] <- return address of user code\r
173 sgdtl 0xffffffa2(%edx)\r
174 sidtl 0x24(%esp)\r
175 movl %cr0, %eax\r
176 movl %eax, (%edx) # save CR0 in SavedCr0\r
177 andl $0x7ffffffe, %eax # clear PE, PG bits\r
178 movl %cr4, %ebp\r
179 mov %ebp, 0xfffffff1(%edx)\r
180 andl $0x300, %ebp # clear all but PCE and OSFXSR bits\r
181 pushl $0x10\r
182 pop %ecx # ecx <- selector for data segments\r
183 lgdtl 0x20(%edx)\r
184 pushfl\r
185 lcall *0x14(%edx)\r
186 popfl\r
187 lidtl 0x24(%esp)\r
188 lea 0xffffffcc(%ebp), %eax\r
189 pop %gs\r
190 pop %fs\r
191 pop %es\r
192 pop %ds\r
193 pop %edi\r
194 pop %esi\r
195 pop %ebx\r
196 pop %ebp\r
197 ret\r
198\r
199 .const:\r
200\r
201ASM_PFX(m16Size): .word _InternalAsmThunk16 - ASM_PFX(m16Start)\r
202ASM_PFX(mThunk16Attr): .word _ThunkAttr - ASM_PFX(m16Start)\r
203ASM_PFX(m16Gdt): .word _NullSegDesc - ASM_PFX(m16Start)\r
204ASM_PFX(m16GdtrBase): .word _16GdtrBase - ASM_PFX(m16Start)\r
205ASM_PFX(mTransition): .word _EntryPoint - ASM_PFX(m16Start)\r