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