Clean up DEC files:
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / X64 / CpuAsm.asm
1 TITLE CpuAsm.asm:
2 ;------------------------------------------------------------------------------
3 ;*
4 ;* Copyright (c) 2008 - 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 .code
20
21 EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
22
23 ;
24 ; point to the external interrupt vector table
25 ;
26 ExternalVectorTablePtr QWORD 0
27
28 InitializeExternalVectorTablePtr PROC PUBLIC
29 mov ExternalVectorTablePtr, rcx
30 ret
31 InitializeExternalVectorTablePtr ENDP
32
33 ;------------------------------------------------------------------------------
34 ; VOID
35 ; SetCodeSelector (
36 ; UINT16 Selector
37 ; );
38 ;------------------------------------------------------------------------------
39 SetCodeSelector PROC PUBLIC
40 sub rsp, 0x10
41 lea rax, setCodeSelectorLongJump
42 mov [rsp], rax
43 mov [rsp+4], cx
44 jmp fword ptr [rsp]
45 setCodeSelectorLongJump:
46 add rsp, 0x10
47 ret
48 SetCodeSelector ENDP
49
50 ;------------------------------------------------------------------------------
51 ; VOID
52 ; SetDataSelectors (
53 ; UINT16 Selector
54 ; );
55 ;------------------------------------------------------------------------------
56 SetDataSelectors PROC PUBLIC
57 mov ss, cx
58 mov ds, cx
59 mov es, cx
60 mov fs, cx
61 mov gs, cx
62 ret
63 SetDataSelectors ENDP
64
65 ;---------------------------------------;
66 ; CommonInterruptEntry ;
67 ;---------------------------------------;
68 ; The follow algorithm is used for the common interrupt routine.
69
70 CommonInterruptEntry PROC PUBLIC
71 cli
72 ;
73 ; All interrupt handlers are invoked through interrupt gates, so
74 ; IF flag automatically cleared at the entry point
75 ;
76 ;
77 ; Calculate vector number
78 ;
79 xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.
80 movzx ecx, word ptr [rcx]
81 cmp ecx, 32 ; Intel reserved vector for exceptions?
82 jae NoErrorCode
83 bt mErrorCodeFlag, ecx
84 jc @F
85
86 NoErrorCode:
87
88 ;
89 ; Push a dummy error code on the stack
90 ; to maintain coherent stack map
91 ;
92 push [rsp]
93 mov qword ptr [rsp + 8], 0
94 @@:
95 push rbp
96 mov rbp, rsp
97
98 ;
99 ; Stack:
100 ; +---------------------+ <-- 16-byte aligned ensured by processor
101 ; + Old SS +
102 ; +---------------------+
103 ; + Old RSP +
104 ; +---------------------+
105 ; + RFlags +
106 ; +---------------------+
107 ; + CS +
108 ; +---------------------+
109 ; + RIP +
110 ; +---------------------+
111 ; + Error Code +
112 ; +---------------------+
113 ; + RCX / Vector Number +
114 ; +---------------------+
115 ; + RBP +
116 ; +---------------------+ <-- RBP, 16-byte aligned
117 ;
118
119
120 ;
121 ; Since here the stack pointer is 16-byte aligned, so
122 ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
123 ; is 16-byte aligned
124 ;
125
126 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
127 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
128 push r15
129 push r14
130 push r13
131 push r12
132 push r11
133 push r10
134 push r9
135 push r8
136 push rax
137 push qword ptr [rbp + 8] ; RCX
138 push rdx
139 push rbx
140 push qword ptr [rbp + 48] ; RSP
141 push qword ptr [rbp] ; RBP
142 push rsi
143 push rdi
144
145 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
146 movzx rax, word ptr [rbp + 56]
147 push rax ; for ss
148 movzx rax, word ptr [rbp + 32]
149 push rax ; for cs
150 mov rax, ds
151 push rax
152 mov rax, es
153 push rax
154 mov rax, fs
155 push rax
156 mov rax, gs
157 push rax
158
159 mov [rbp + 8], rcx ; save vector number
160
161 ;; UINT64 Rip;
162 push qword ptr [rbp + 24]
163
164 ;; UINT64 Gdtr[2], Idtr[2];
165 xor rax, rax
166 push rax
167 push rax
168 sidt [rsp]
169 xchg rax, [rsp + 2]
170 xchg rax, [rsp]
171 xchg rax, [rsp + 8]
172
173 xor rax, rax
174 push rax
175 push rax
176 sgdt [rsp]
177 xchg rax, [rsp + 2]
178 xchg rax, [rsp]
179 xchg rax, [rsp + 8]
180
181 ;; UINT64 Ldtr, Tr;
182 xor rax, rax
183 str ax
184 push rax
185 sldt ax
186 push rax
187
188 ;; UINT64 RFlags;
189 push qword ptr [rbp + 40]
190
191 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
192 mov rax, cr8
193 push rax
194 mov rax, cr4
195 or rax, 208h
196 mov cr4, rax
197 push rax
198 mov rax, cr3
199 push rax
200 mov rax, cr2
201 push rax
202 xor rax, rax
203 push rax
204 mov rax, cr0
205 push rax
206
207 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
208 mov rax, dr7
209 push rax
210 mov rax, dr6
211 push rax
212 mov rax, dr3
213 push rax
214 mov rax, dr2
215 push rax
216 mov rax, dr1
217 push rax
218 mov rax, dr0
219 push rax
220
221 ;; FX_SAVE_STATE_X64 FxSaveState;
222 sub rsp, 512
223 mov rdi, rsp
224 db 0fh, 0aeh, 07h ;fxsave [rdi]
225
226 ;; UINT32 ExceptionData;
227 push qword ptr [rbp + 16]
228
229 ;; call into exception handler
230 mov rcx, [rbp + 8]
231 mov rax, ExternalVectorTablePtr ; get the interrupt vectors base
232 mov rax, [rax + rcx * 8]
233 or rax, rax ; NULL?
234
235 je nonNullValue;
236
237 ;; Prepare parameter and call
238 ; mov rcx, [rbp + 8]
239 mov rdx, rsp
240 ;
241 ; Per X64 calling convention, allocate maximum parameter stack space
242 ; and make sure RSP is 16-byte aligned
243 ;
244 sub rsp, 4 * 8 + 8
245 call rax
246 add rsp, 4 * 8 + 8
247
248 nonNullValue:
249 cli
250 ;; UINT64 ExceptionData;
251 add rsp, 8
252
253 ;; FX_SAVE_STATE_X64 FxSaveState;
254
255 mov rsi, rsp
256 db 0fh, 0aeh, 0Eh ; fxrstor [rsi]
257 add rsp, 512
258
259 ;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
260 ;; Skip restoration of DRx registers to support in-circuit emualators
261 ;; or debuggers set breakpoint in interrupt/exception context
262 add rsp, 8 * 6
263
264 ;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
265 pop rax
266 mov cr0, rax
267 add rsp, 8 ; not for Cr1
268 pop rax
269 mov cr2, rax
270 pop rax
271 mov cr3, rax
272 pop rax
273 mov cr4, rax
274 pop rax
275 mov cr8, rax
276
277 ;; UINT64 RFlags;
278 pop qword ptr [rbp + 40]
279
280 ;; UINT64 Ldtr, Tr;
281 ;; UINT64 Gdtr[2], Idtr[2];
282 ;; Best not let anyone mess with these particular registers...
283 add rsp, 48
284
285 ;; UINT64 Rip;
286 pop qword ptr [rbp + 24]
287
288 ;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
289 pop rax
290 ; mov gs, rax ; not for gs
291 pop rax
292 ; mov fs, rax ; not for fs
293 ; (X64 will not use fs and gs, so we do not restore it)
294 pop rax
295 mov es, rax
296 pop rax
297 mov ds, rax
298 pop qword ptr [rbp + 32] ; for cs
299 pop qword ptr [rbp + 56] ; for ss
300
301 ;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
302 ;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
303 pop rdi
304 pop rsi
305 add rsp, 8 ; not for rbp
306 pop qword ptr [rbp + 48] ; for rsp
307 pop rbx
308 pop rdx
309 pop rcx
310 pop rax
311 pop r8
312 pop r9
313 pop r10
314 pop r11
315 pop r12
316 pop r13
317 pop r14
318 pop r15
319
320 mov rsp, rbp
321 pop rbp
322 add rsp, 16
323 iretq
324
325 CommonInterruptEntry ENDP
326
327 END
328