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