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