VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/CPUMR0A.asm@ 39333

Last change on this file since 39333 was 37955, checked in by vboxsync, 13 years ago

Moved VBox/x86.h/mac to iprt/x86.h/mac.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.3 KB
Line 
1; $Id: CPUMR0A.asm 37955 2011-07-14 12:23:02Z vboxsync $
2;; @file
3; CPUM - Guest Context Assembly Routines.
4;
5
6;
7; Copyright (C) 2006-2007 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17
18;*******************************************************************************
19;* Header Files *
20;*******************************************************************************
21%include "VBox/asmdefs.mac"
22%include "VBox/vmm/vm.mac"
23%include "VBox/err.mac"
24%include "VBox/vmm/stam.mac"
25%include "CPUMInternal.mac"
26%include "iprt/x86.mac"
27%include "VBox/vmm/cpum.mac"
28
29%ifdef IN_RING3
30 %error "The jump table doesn't link on leopard."
31%endif
32
33;*******************************************************************************
34;* Defined Constants And Macros *
35;*******************************************************************************
36;; The offset of the XMM registers in X86FXSTATE.
37; Use define because I'm too lazy to convert the struct.
38%define XMM_OFF_IN_X86FXSTATE 160
39
40
41;*******************************************************************************
42;* External Symbols *
43;*******************************************************************************
44%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
45extern NAME(SUPR0AbsIs64bit)
46extern NAME(SUPR0Abs64bitKernelCS)
47extern NAME(SUPR0Abs64bitKernelSS)
48extern NAME(SUPR0Abs64bitKernelDS)
49extern NAME(SUPR0AbsKernelCS)
50%endif
51
52
53;*******************************************************************************
54;* Global Variables *
55;*******************************************************************************
56%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
57BEGINDATA
58;;
59; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
60; needing to clobber a register. (This trick doesn't quite work for PE btw.
61; but that's not relevant atm.)
62GLOBALNAME g_fCPUMIs64bitHost
63 dd NAME(SUPR0AbsIs64bit)
64%endif
65
66
67BEGINCODE
68
69
70;;
71; Saves the host FPU/XMM state and restores the guest state.
72;
73; @returns 0
74; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
75;
76align 16
77BEGINPROC cpumR0SaveHostRestoreGuestFPUState
78%ifdef RT_ARCH_AMD64
79 %ifdef RT_OS_WINDOWS
80 mov xDX, rcx
81 %else
82 mov xDX, rdi
83 %endif
84%else
85 mov xDX, dword [esp + 4]
86%endif
87 pushf ; The darwin kernel can get upset or upset things if an
88 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
89
90 ; Switch the state.
91 or dword [xDX + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
92
93 mov xAX, cr0 ; Make sure its safe to access the FPU state.
94 mov xCX, xAX ; save old CR0
95 and xAX, ~(X86_CR0_TS | X86_CR0_EM)
96 mov cr0, xAX ;; @todo optimize this.
97
98%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
99 cmp byte [NAME(g_fCPUMIs64bitHost)], 0
100 jz .legacy_mode
101 db 0xea ; jmp far .sixtyfourbit_mode
102 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
103.legacy_mode:
104%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
105
106 fxsave [xDX + CPUMCPU.Host.fpu] ; ASSUMES that all VT-x/AMD-V boxes sports fxsave/fxrstor (safe assumption)
107 fxrstor [xDX + CPUMCPU.Guest.fpu]
108
109%ifdef VBOX_WITH_KERNEL_USING_XMM
110 ; Restore the non-volatile xmm registers. ASSUMING 64-bit windows
111 lea r11, [xDX + CPUMCPU.Host.fpu + XMM_OFF_IN_X86FXSTATE]
112 movdqa xmm6, [r11 + 060h]
113 movdqa xmm7, [r11 + 070h]
114 movdqa xmm8, [r11 + 080h]
115 movdqa xmm9, [r11 + 090h]
116 movdqa xmm10, [r11 + 0a0h]
117 movdqa xmm11, [r11 + 0b0h]
118 movdqa xmm12, [r11 + 0c0h]
119 movdqa xmm13, [r11 + 0d0h]
120 movdqa xmm14, [r11 + 0e0h]
121 movdqa xmm15, [r11 + 0f0h]
122%endif
123
124.done:
125 mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
126 popf
127 xor eax, eax
128 ret
129
130%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
131ALIGNCODE(16)
132BITS 64
133.sixtyfourbit_mode:
134 and edx, 0ffffffffh
135 fxsave [rdx + CPUMCPU.Host.fpu]
136 fxrstor [rdx + CPUMCPU.Guest.fpu]
137 jmp far [.fpret wrt rip]
138.fpret: ; 16:32 Pointer to .the_end.
139 dd .done, NAME(SUPR0AbsKernelCS)
140BITS 32
141%endif
142ENDPROC cpumR0SaveHostRestoreGuestFPUState
143
144
145%ifndef RT_ARCH_AMD64
146%ifdef VBOX_WITH_64_BITS_GUESTS
147%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
148;;
149; Saves the host FPU/XMM state
150;
151; @returns 0
152; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
153;
154align 16
155BEGINPROC cpumR0SaveHostFPUState
156 mov xDX, dword [esp + 4]
157 pushf ; The darwin kernel can get upset or upset things if an
158 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
159
160 ; Switch the state.
161 or dword [xDX + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
162
163 mov xAX, cr0 ; Make sure its safe to access the FPU state.
164 mov xCX, xAX ; save old CR0
165 and xAX, ~(X86_CR0_TS | X86_CR0_EM)
166 mov cr0, xAX ;; @todo optimize this.
167
168 fxsave [xDX + CPUMCPU.Host.fpu] ; ASSUMES that all VT-x/AMD-V boxes support fxsave/fxrstor (safe assumption)
169
170 mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
171 popf
172 xor eax, eax
173 ret
174ENDPROC cpumR0SaveHostFPUState
175%endif
176%endif
177%endif
178
179
180;;
181; Saves the guest FPU/XMM state and restores the host state.
182;
183; @returns 0
184; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
185;
186align 16
187BEGINPROC cpumR0SaveGuestRestoreHostFPUState
188%ifdef RT_ARCH_AMD64
189 %ifdef RT_OS_WINDOWS
190 mov xDX, rcx
191 %else
192 mov xDX, rdi
193 %endif
194%else
195 mov xDX, dword [esp + 4]
196%endif
197
198 ; Only restore FPU if guest has used it.
199 ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
200 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USED_FPU
201 jz short .fpu_not_used
202
203 pushf ; The darwin kernel can get upset or upset things if an
204 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
205
206 mov xAX, cr0 ; Make sure it's safe to access the FPU state.
207 mov xCX, xAX ; save old CR0
208 and xAX, ~(X86_CR0_TS | X86_CR0_EM)
209 mov cr0, xAX ;; @todo optimize this.
210
211%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
212 cmp byte [NAME(g_fCPUMIs64bitHost)], 0
213 jz .legacy_mode
214 db 0xea ; jmp far .sixtyfourbit_mode
215 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
216.legacy_mode:
217%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
218
219 fxsave [xDX + CPUMCPU.Guest.fpu] ; ASSUMES that all VT-x/AMD-V boxes support fxsave/fxrstor (safe assumption)
220 fxrstor [xDX + CPUMCPU.Host.fpu]
221
222.done:
223 mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
224 and dword [xDX + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
225 popf
226.fpu_not_used:
227 xor eax, eax
228 ret
229
230%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
231ALIGNCODE(16)
232BITS 64
233.sixtyfourbit_mode:
234 and edx, 0ffffffffh
235 fxsave [rdx + CPUMCPU.Guest.fpu]
236 fxrstor [rdx + CPUMCPU.Host.fpu]
237 jmp far [.fpret wrt rip]
238.fpret: ; 16:32 Pointer to .the_end.
239 dd .done, NAME(SUPR0AbsKernelCS)
240BITS 32
241%endif
242ENDPROC cpumR0SaveGuestRestoreHostFPUState
243
244
245;;
246; Sets the host's FPU/XMM state
247;
248; @returns 0
249; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
250;
251align 16
252BEGINPROC cpumR0RestoreHostFPUState
253%ifdef RT_ARCH_AMD64
254 %ifdef RT_OS_WINDOWS
255 mov xDX, rcx
256 %else
257 mov xDX, rdi
258 %endif
259%else
260 mov xDX, dword [esp + 4]
261%endif
262
263 ; Restore FPU if guest has used it.
264 ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
265 test dword [xDX + CPUMCPU.fUseFlags], CPUM_USED_FPU
266 jz short .fpu_not_used
267
268 pushf ; The darwin kernel can get upset or upset things if an
269 cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
270
271 mov xAX, cr0
272 mov xCX, xAX ; save old CR0
273 and xAX, ~(X86_CR0_TS | X86_CR0_EM)
274 mov cr0, xAX
275
276%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
277 cmp byte [NAME(g_fCPUMIs64bitHost)], 0
278 jz .legacy_mode
279 db 0xea ; jmp far .sixtyfourbit_mode
280 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
281.legacy_mode:
282%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
283
284 fxrstor [xDX + CPUMCPU.Host.fpu]
285
286.done:
287 mov cr0, xCX ; and restore old CR0 again
288 and dword [xDX + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
289 popf
290.fpu_not_used:
291 xor eax, eax
292 ret
293
294%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
295ALIGNCODE(16)
296BITS 64
297.sixtyfourbit_mode:
298 and edx, 0ffffffffh
299 fxrstor [rdx + CPUMCPU.Host.fpu]
300 jmp far [.fpret wrt rip]
301.fpret: ; 16:32 Pointer to .the_end.
302 dd .done, NAME(SUPR0AbsKernelCS)
303BITS 32
304%endif
305ENDPROC cpumR0RestoreHostFPUState
306
307
308%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
309;;
310; DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
311;
312ALIGNCODE(16)
313BEGINPROC cpumR0SaveDRx
314%ifdef RT_ARCH_AMD64
315 %ifdef ASM_CALL64_GCC
316 mov xCX, rdi
317 %endif
318%else
319 mov xCX, dword [esp + 4]
320%endif
321 pushf ; Just to be on the safe side.
322 cli
323%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
324 cmp byte [NAME(g_fCPUMIs64bitHost)], 0
325 jz .legacy_mode
326 db 0xea ; jmp far .sixtyfourbit_mode
327 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
328.legacy_mode:
329%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
330
331 ;
332 ; Do the job.
333 ;
334 mov xAX, dr0
335 mov xDX, dr1
336 mov [xCX], xAX
337 mov [xCX + 8 * 1], xDX
338 mov xAX, dr2
339 mov xDX, dr3
340 mov [xCX + 8 * 2], xAX
341 mov [xCX + 8 * 3], xDX
342
343.done:
344 popf
345 ret
346
347%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
348ALIGNCODE(16)
349BITS 64
350.sixtyfourbit_mode:
351 and ecx, 0ffffffffh
352
353 mov rax, dr0
354 mov rdx, dr1
355 mov r8, dr2
356 mov r9, dr3
357 mov [rcx], rax
358 mov [rcx + 8 * 1], rdx
359 mov [rcx + 8 * 2], r8
360 mov [rcx + 8 * 3], r9
361 jmp far [.fpret wrt rip]
362.fpret: ; 16:32 Pointer to .the_end.
363 dd .done, NAME(SUPR0AbsKernelCS)
364BITS 32
365%endif
366ENDPROC cpumR0SaveDRx
367
368
369;;
370; DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
371;
372ALIGNCODE(16)
373BEGINPROC cpumR0LoadDRx
374%ifdef RT_ARCH_AMD64
375 %ifdef ASM_CALL64_GCC
376 mov xCX, rdi
377 %endif
378%else
379 mov xCX, dword [esp + 4]
380%endif
381 pushf ; Just to be on the safe side.
382 cli
383%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
384 cmp byte [NAME(g_fCPUMIs64bitHost)], 0
385 jz .legacy_mode
386 db 0xea ; jmp far .sixtyfourbit_mode
387 dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
388.legacy_mode:
389%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
390
391 ;
392 ; Do the job.
393 ;
394 mov xAX, [xCX]
395 mov xDX, [xCX + 8 * 1]
396 mov dr0, xAX
397 mov dr1, xDX
398 mov xAX, [xCX + 8 * 2]
399 mov xDX, [xCX + 8 * 3]
400 mov dr2, xAX
401 mov dr3, xDX
402
403.done:
404 popf
405 ret
406
407%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
408ALIGNCODE(16)
409BITS 64
410.sixtyfourbit_mode:
411 and ecx, 0ffffffffh
412
413 mov rax, [rcx]
414 mov rdx, [rcx + 8 * 1]
415 mov r8, [rcx + 8 * 2]
416 mov r9, [rcx + 8 * 3]
417 mov dr0, rax
418 mov dr1, rdx
419 mov dr2, r8
420 mov dr3, r9
421 jmp far [.fpret wrt rip]
422.fpret: ; 16:32 Pointer to .the_end.
423 dd .done, NAME(SUPR0AbsKernelCS)
424BITS 32
425%endif
426ENDPROC cpumR0LoadDRx
427
428%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
429
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette