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