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