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