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