]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
Clean up DEC files:
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / Ia32 / CpuAsm.S
CommitLineData
c2fd60f0 1#------------------------------------------------------------------------------\r
2#*\r
61ece967 3#* Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>\r
01a1c0fc 4#* This program and the accompanying materials\r
c2fd60f0 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#* CpuAsm.S\r
13#*\r
14#* Abstract:\r
15#*\r
16#------------------------------------------------------------------------------\r
17\r
18\r
19#.MMX\r
20#.XMM\r
21\r
22#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
23\r
24\r
25#\r
26# point to the external interrupt vector table\r
27#\r
28ExternalVectorTablePtr:\r
29 .byte 0, 0, 0, 0\r
30\r
31ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
32ASM_PFX(InitializeExternalVectorTablePtr):\r
33 movl 4(%esp), %eax\r
34 movl %eax, ExternalVectorTablePtr\r
35 ret\r
36\r
37#------------------------------------------------------------------------------\r
38# VOID\r
39# SetCodeSelector (\r
40# UINT16 Selector\r
41# );\r
42#------------------------------------------------------------------------------\r
43ASM_GLOBAL ASM_PFX(SetCodeSelector)\r
44ASM_PFX(SetCodeSelector):\r
45 movl 4(%esp), %ecx\r
46 subl $0x10, %esp \r
47 leal setCodeSelectorLongJump, %eax \r
48 movl %eax, (%esp)\r
49 movw %cx, 4(%esp)\r
50 .byte 0xFF, 0x2C, 0x24 # jmp *(%esp) note:(FWORD jmp) \r
51setCodeSelectorLongJump:\r
52 addl $0x10, %esp \r
53 ret\r
54\r
55#------------------------------------------------------------------------------\r
56# VOID\r
57# SetDataSelectors (\r
58# UINT16 Selector\r
59# );\r
60#------------------------------------------------------------------------------\r
61ASM_GLOBAL ASM_PFX(SetDataSelectors)\r
62ASM_PFX(SetDataSelectors):\r
63 movl 4(%esp), %ecx\r
64 movw %cx, %ss\r
65 movw %cx, %ds\r
66 movw %cx, %es\r
67 movw %cx, %fs\r
68 movw %cx, %gs\r
69 ret\r
70\r
71#---------------------------------------;\r
72# CommonInterruptEntry ;\r
73#---------------------------------------;\r
74# The follow algorithm is used for the common interrupt routine.\r
75\r
76ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
77ASM_PFX(CommonInterruptEntry):\r
78 cli\r
79 #\r
80 # All interrupt handlers are invoked through interrupt gates, so\r
81 # IF flag automatically cleared at the entry point\r
82 #\r
83\r
84 #\r
85 # Calculate vector number\r
86 #\r
87 # Get the return address of call, actually, it is the\r
88 # address of vector number.\r
89 #\r
90 xchgl (%esp), %ecx\r
91 movw (%ecx), %cx\r
92 andl $0x0FFFF, %ecx\r
93 cmpl $32, %ecx # Intel reserved vector for exceptions?\r
94 jae NoErrorCode\r
95 bt %ecx, ASM_PFX(mErrorCodeFlag)\r
96 jc HasErrorCode\r
97\r
98NoErrorCode:\r
99\r
100 #\r
101 # Stack:\r
102 # +---------------------+\r
103 # + EFlags +\r
104 # +---------------------+\r
105 # + CS +\r
106 # +---------------------+\r
107 # + EIP +\r
108 # +---------------------+\r
109 # + ECX +\r
110 # +---------------------+ <-- ESP\r
111 #\r
112 # Registers:\r
113 # ECX - Vector Number\r
114 #\r
115\r
116 #\r
117 # Put Vector Number on stack\r
118 #\r
119 pushl %ecx\r
120\r
121 #\r
122 # Put 0 (dummy) error code on stack, and restore ECX\r
123 #\r
124 xorl %ecx, %ecx # ECX = 0\r
125 xchgl 4(%esp), %ecx\r
126\r
127 jmp ErrorCodeAndVectorOnStack\r
128\r
129HasErrorCode:\r
130\r
131 #\r
132 # Stack:\r
133 # +---------------------+\r
134 # + EFlags +\r
135 # +---------------------+\r
136 # + CS +\r
137 # +---------------------+\r
138 # + EIP +\r
139 # +---------------------+\r
140 # + Error Code +\r
141 # +---------------------+\r
142 # + ECX +\r
143 # +---------------------+ <-- ESP\r
144 #\r
145 # Registers:\r
146 # ECX - Vector Number\r
147 #\r
148\r
149 #\r
150 # Put Vector Number on stack and restore ECX\r
151 #\r
152 xchgl (%esp), %ecx \r
153\r
154 #\r
155 # Fall through to join main routine code\r
156 # at ErrorCodeAndVectorOnStack\r
157 #\r
158CommonInterruptEntry_al_0000:\r
159 jmp CommonInterruptEntry_al_0000\r
160\r
161ErrorCodeAndVectorOnStack:\r
162 pushl %ebp\r
163 movl %esp, %ebp\r
164\r
165 #\r
166 # Stack:\r
167 # +---------------------+\r
168 # + EFlags +\r
169 # +---------------------+\r
170 # + CS +\r
171 # +---------------------+\r
172 # + EIP +\r
173 # +---------------------+\r
174 # + Error Code +\r
175 # +---------------------+\r
176 # + Vector Number +\r
177 # +---------------------+\r
178 # + EBP +\r
179 # +---------------------+ <-- EBP\r
180 #\r
181\r
182 #\r
183 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
184 # is 16-byte aligned\r
185 #\r
186 andl $0x0fffffff0, %esp \r
187 subl $12, %esp\r
188\r
189#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
190 pushl %eax\r
191 pushl %ecx\r
192 pushl %edx\r
193 pushl %ebx\r
194 leal 24(%ebp), %ecx\r
195 pushl %ecx # ESP\r
196 pushl (%ebp) # EBP\r
197 pushl %esi\r
198 pushl %edi\r
199\r
200#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
201 movl %ss, %eax\r
202 pushl %eax\r
203 movzwl 16(%ebp), %eax \r
204 pushl %eax\r
205 movl %ds, %eax\r
206 pushl %eax\r
207 movl %es, %eax\r
208 pushl %eax\r
209 movl %fs, %eax\r
210 pushl %eax\r
211 movl %gs, %eax\r
212 pushl %eax\r
213\r
214#; UINT32 Eip;\r
215 movl 12(%ebp), %eax\r
216 pushl %eax\r
217\r
218#; UINT32 Gdtr[2], Idtr[2];\r
219 subl $8, %esp\r
220 sidt (%esp)\r
221 movl 2(%esp), %eax\r
222 xchgl (%esp), %eax\r
223 andl $0x0FFFF, %eax \r
224 movl %eax, 4(%esp)\r
225\r
226 subl $8, %esp\r
227 sgdt (%esp)\r
228 movl 2(%esp), %eax\r
229 xchgl (%esp), %eax\r
230 andl $0x0FFFF, %eax \r
231 movl %eax, 4(%esp)\r
232\r
233#; UINT32 Ldtr, Tr;\r
234 xorl %eax, %eax\r
235 str %ax\r
236 pushl %eax\r
237 sldt %ax\r
238 pushl %eax\r
239\r
240#; UINT32 EFlags;\r
241 movl 20(%ebp), %eax\r
242 pushl %eax\r
243\r
244#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
245 movl %cr4, %eax\r
246 orl $0x208, %eax\r
247 movl %eax, %cr4\r
248 pushl %eax\r
249 movl %cr3, %eax\r
250 pushl %eax\r
251 movl %cr2, %eax\r
252 pushl %eax\r
253 xorl %eax, %eax\r
254 pushl %eax\r
255 movl %cr0, %eax\r
256 pushl %eax\r
257\r
258#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
259 movl %dr7, %eax\r
260 pushl %eax\r
c2fd60f0 261 movl %dr6, %eax\r
262 pushl %eax\r
c2fd60f0 263 movl %dr3, %eax\r
264 pushl %eax\r
265 movl %dr2, %eax\r
266 pushl %eax\r
267 movl %dr1, %eax\r
268 pushl %eax\r
269 movl %dr0, %eax\r
270 pushl %eax\r
271\r
272#; FX_SAVE_STATE_IA32 FxSaveState;\r
273 subl $512, %esp\r
274 movl %esp, %edi\r
275 .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]\r
276\r
277#; UINT32 ExceptionData;\r
278 pushl 8(%ebp)\r
279\r
280#; call into exception handler\r
281 movl ExternalVectorTablePtr, %eax # get the interrupt vectors base\r
282 orl %eax, %eax # NULL?\r
283 jz nullExternalExceptionHandler\r
284\r
285 mov 4(%ebp), %ecx\r
286 movl (%eax,%ecx,4), %eax\r
287 orl %eax, %eax # NULL?\r
288 jz nullExternalExceptionHandler\r
289\r
290#; Prepare parameter and call\r
291 movl %esp, %edx\r
292 pushl %edx\r
293 movl 4(%ebp), %edx\r
294 pushl %edx\r
295\r
296 #\r
297 # Call External Exception Handler\r
298 #\r
299 call *%eax\r
300 addl $8, %esp\r
301\r
302nullExternalExceptionHandler:\r
303\r
304 cli\r
305#; UINT32 ExceptionData;\r
306 addl $4, %esp\r
307\r
308#; FX_SAVE_STATE_IA32 FxSaveState;\r
309 movl %esp, %esi\r
310 .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
311 addl $512, %esp\r
312\r
313#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
61ece967 314#; Skip restoration of DRx registers to support in-circuit emualators\r
315#; or debuggers set breakpoint in interrupt/exception context\r
316 addl $24, %esp\r
c2fd60f0 317\r
318#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
319 popl %eax\r
320 movl %eax, %cr0\r
321 addl $4, %esp # not for Cr1\r
322 popl %eax\r
323 movl %eax, %cr2\r
324 popl %eax\r
325 movl %eax, %cr3\r
326 popl %eax\r
327 movl %eax, %cr4\r
328\r
329#; UINT32 EFlags;\r
330 popl 20(%ebp)\r
331\r
332#; UINT32 Ldtr, Tr;\r
333#; UINT32 Gdtr[2], Idtr[2];\r
334#; Best not let anyone mess with these particular registers...\r
335 addl $24, %esp\r
336\r
337#; UINT32 Eip;\r
338 popl 12(%ebp)\r
339\r
340#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
341#; NOTE - modified segment registers could hang the debugger... We\r
342#; could attempt to insulate ourselves against this possibility,\r
343#; but that poses risks as well.\r
344#;\r
345 popl %gs\r
346 popl %fs\r
347 popl %es\r
348 popl %ds\r
349 popl 16(%ebp)\r
350 popl %ss\r
351\r
352#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
353 popl %edi\r
354 popl %esi\r
355 addl $4, %esp # not for ebp\r
356 addl $4, %esp # not for esp\r
357 popl %ebx\r
358 popl %edx\r
359 popl %ecx\r
360 popl %eax\r
361\r
362 movl %ebp, %esp\r
363 popl %ebp\r
364 addl $8, %esp\r
365 iretl\r
366\r
367\r
368#END\r
369\r