Clean up DEC files:
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / X64 / CpuAsm.asm
CommitLineData
a47463f2 1 TITLE CpuAsm.asm: \r
2;------------------------------------------------------------------------------\r
3;*\r
61ece967 4;* Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>\r
01a1c0fc 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
a47463f2 210 mov rax, dr6\r
211 push rax\r
a47463f2 212 mov rax, dr3\r
213 push rax\r
214 mov rax, dr2\r
215 push rax\r
216 mov rax, dr1\r
217 push rax\r
218 mov rax, dr0\r
219 push rax\r
220\r
221;; FX_SAVE_STATE_X64 FxSaveState;\r
222 sub rsp, 512\r
223 mov rdi, rsp\r
224 db 0fh, 0aeh, 07h ;fxsave [rdi]\r
225\r
226;; UINT32 ExceptionData;\r
227 push qword ptr [rbp + 16]\r
228\r
229;; call into exception handler\r
230 mov rcx, [rbp + 8]\r
231 mov rax, ExternalVectorTablePtr ; get the interrupt vectors base\r
232 mov rax, [rax + rcx * 8] \r
233 or rax, rax ; NULL?\r
234\r
235 je nonNullValue;\r
236\r
237;; Prepare parameter and call\r
238; mov rcx, [rbp + 8]\r
239 mov rdx, rsp\r
240 ;\r
241 ; Per X64 calling convention, allocate maximum parameter stack space\r
242 ; and make sure RSP is 16-byte aligned\r
243 ;\r
244 sub rsp, 4 * 8 + 8\r
245 call rax\r
246 add rsp, 4 * 8 + 8\r
247\r
248nonNullValue:\r
249 cli\r
250;; UINT64 ExceptionData;\r
251 add rsp, 8\r
252\r
253;; FX_SAVE_STATE_X64 FxSaveState;\r
254\r
255 mov rsi, rsp\r
256 db 0fh, 0aeh, 0Eh ; fxrstor [rsi]\r
257 add rsp, 512\r
258\r
259;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
61ece967 260;; Skip restoration of DRx registers to support in-circuit emualators\r
261;; or debuggers set breakpoint in interrupt/exception context\r
262 add rsp, 8 * 6\r
a47463f2 263\r
264;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
265 pop rax\r
266 mov cr0, rax\r
267 add rsp, 8 ; not for Cr1\r
268 pop rax\r
269 mov cr2, rax\r
270 pop rax\r
271 mov cr3, rax\r
272 pop rax\r
273 mov cr4, rax\r
274 pop rax\r
275 mov cr8, rax\r
276\r
277;; UINT64 RFlags;\r
278 pop qword ptr [rbp + 40]\r
279\r
280;; UINT64 Ldtr, Tr;\r
281;; UINT64 Gdtr[2], Idtr[2];\r
282;; Best not let anyone mess with these particular registers...\r
283 add rsp, 48\r
284\r
285;; UINT64 Rip;\r
286 pop qword ptr [rbp + 24]\r
287\r
288;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
289 pop rax\r
290 ; mov gs, rax ; not for gs\r
291 pop rax\r
292 ; mov fs, rax ; not for fs\r
293 ; (X64 will not use fs and gs, so we do not restore it)\r
294 pop rax\r
295 mov es, rax\r
296 pop rax\r
297 mov ds, rax\r
298 pop qword ptr [rbp + 32] ; for cs\r
299 pop qword ptr [rbp + 56] ; for ss\r
300\r
301;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
302;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
303 pop rdi\r
304 pop rsi\r
305 add rsp, 8 ; not for rbp\r
306 pop qword ptr [rbp + 48] ; for rsp\r
307 pop rbx\r
308 pop rdx\r
309 pop rcx\r
310 pop rax\r
311 pop r8\r
312 pop r9\r
313 pop r10\r
314 pop r11\r
315 pop r12\r
316 pop r13\r
317 pop r14\r
318 pop r15\r
319\r
320 mov rsp, rbp\r
321 pop rbp\r
322 add rsp, 16\r
323 iretq\r
324\r
325CommonInterruptEntry ENDP\r
326\r
327END\r
328\r