]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
Skip restoration of DRx registers to support in-circuit emualators or debuggers set...
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / Ia32 / CpuAsm.asm
1 TITLE CpuAsm.asm:
2 ;------------------------------------------------------------------------------
3 ;*
4 ;* Copyright (c) 2006 - 2010, 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 ;
153 ; Fall through to join main routine code
154 ; at ErrorCodeAndVectorOnStack
155 ;
156 @@:
157 jmp @B
158
159 ErrorCodeAndVectorOnStack:
160 push ebp
161 mov ebp, esp
162
163 ;
164 ; Stack:
165 ; +---------------------+
166 ; + EFlags +
167 ; +---------------------+
168 ; + CS +
169 ; +---------------------+
170 ; + EIP +
171 ; +---------------------+
172 ; + Error Code +
173 ; +---------------------+
174 ; + Vector Number +
175 ; +---------------------+
176 ; + EBP +
177 ; +---------------------+ <-- EBP
178 ;
179
180 ;
181 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
182 ; is 16-byte aligned
183 ;
184 and esp, 0fffffff0h
185 sub esp, 12
186
187 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
188 push eax
189 push ecx
190 push edx
191 push ebx
192 lea ecx, [ebp + 6 * 4]
193 push ecx ; ESP
194 push dword ptr [ebp] ; EBP
195 push esi
196 push edi
197
198 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
199 mov eax, ss
200 push eax
201 movzx eax, word ptr [ebp + 4 * 4]
202 push eax
203 mov eax, ds
204 push eax
205 mov eax, es
206 push eax
207 mov eax, fs
208 push eax
209 mov eax, gs
210 push eax
211
212 ;; UINT32 Eip;
213 mov eax, [ebp + 3 * 4]
214 push eax
215
216 ;; UINT32 Gdtr[2], Idtr[2];
217 sub esp, 8
218 sidt [esp]
219 mov eax, [esp + 2]
220 xchg eax, [esp]
221 and eax, 0FFFFh
222 mov [esp+4], eax
223
224 sub esp, 8
225 sgdt [esp]
226 mov eax, [esp + 2]
227 xchg eax, [esp]
228 and eax, 0FFFFh
229 mov [esp+4], eax
230
231 ;; UINT32 Ldtr, Tr;
232 xor eax, eax
233 str ax
234 push eax
235 sldt ax
236 push eax
237
238 ;; UINT32 EFlags;
239 mov eax, [ebp + 5 * 4]
240 push eax
241
242 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
243 mov eax, cr4
244 or eax, 208h
245 mov cr4, eax
246 push eax
247 mov eax, cr3
248 push eax
249 mov eax, cr2
250 push eax
251 xor eax, eax
252 push eax
253 mov eax, cr0
254 push eax
255
256 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
257 mov eax, dr7
258 push eax
259 mov eax, dr6
260 push eax
261 mov eax, dr3
262 push eax
263 mov eax, dr2
264 push eax
265 mov eax, dr1
266 push eax
267 mov eax, dr0
268 push eax
269
270 ;; FX_SAVE_STATE_IA32 FxSaveState;
271 sub esp, 512
272 mov edi, esp
273 db 0fh, 0aeh, 07h ;fxsave [edi]
274
275 ;; UINT32 ExceptionData;
276 push dword ptr [ebp + 2 * 4]
277
278 ;; call into exception handler
279 mov eax, ExternalVectorTablePtr ; get the interrupt vectors base
280 or eax, eax ; NULL?
281 jz nullExternalExceptionHandler
282
283 mov ecx, [ebp + 4]
284 mov eax, [eax + ecx * 4]
285 or eax, eax ; NULL?
286 jz nullExternalExceptionHandler
287
288 ;; Prepare parameter and call
289 mov edx, esp
290 push edx
291 mov edx, dword ptr [ebp + 1 * 4]
292 push edx
293
294 ;
295 ; Call External Exception Handler
296 ;
297 call eax
298 add esp, 8
299
300 nullExternalExceptionHandler:
301
302 cli
303 ;; UINT32 ExceptionData;
304 add esp, 4
305
306 ;; FX_SAVE_STATE_IA32 FxSaveState;
307 mov esi, esp
308 db 0fh, 0aeh, 0eh ; fxrstor [esi]
309 add esp, 512
310
311 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
312 ;; Skip restoration of DRx registers to support in-circuit emualators
313 ;; or debuggers set breakpoint in interrupt/exception context
314 add esp, 4 * 6
315
316 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
317 pop eax
318 mov cr0, eax
319 add esp, 4 ; not for Cr1
320 pop eax
321 mov cr2, eax
322 pop eax
323 mov cr3, eax
324 pop eax
325 mov cr4, eax
326
327 ;; UINT32 EFlags;
328 pop dword ptr [ebp + 5 * 4]
329
330 ;; UINT32 Ldtr, Tr;
331 ;; UINT32 Gdtr[2], Idtr[2];
332 ;; Best not let anyone mess with these particular registers...
333 add esp, 24
334
335 ;; UINT32 Eip;
336 pop dword ptr [ebp + 3 * 4]
337
338 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
339 ;; NOTE - modified segment registers could hang the debugger... We
340 ;; could attempt to insulate ourselves against this possibility,
341 ;; but that poses risks as well.
342 ;;
343 pop gs
344 pop fs
345 pop es
346 pop ds
347 pop dword ptr [ebp + 4 * 4]
348 pop ss
349
350 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
351 pop edi
352 pop esi
353 add esp, 4 ; not for ebp
354 add esp, 4 ; not for esp
355 pop ebx
356 pop edx
357 pop ecx
358 pop eax
359
360 mov esp, ebp
361 pop ebp
362 add esp, 8
363 iretd
364
365 CommonInterruptEntry ENDP
366
367 END