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