CPUMR0A.asm revision 8fcaf889c8c3502cb99f4090a83aea7d878b2f48
52676b598e9afd834db7f3e62a983044038e92bevboxsync; $Id$
52676b598e9afd834db7f3e62a983044038e92bevboxsync;; @file
52676b598e9afd834db7f3e62a983044038e92bevboxsync; CPUM - Guest Context Assembly Routines.
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; Copyright (C) 2006-2007 Sun Microsystems, Inc.
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
52676b598e9afd834db7f3e62a983044038e92bevboxsync; available from http://www.virtualbox.org. This file is free software;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; you can redistribute it and/or modify it under the terms of the GNU
52676b598e9afd834db7f3e62a983044038e92bevboxsync; General Public License (GPL) as published by the Free Software
52676b598e9afd834db7f3e62a983044038e92bevboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
52676b598e9afd834db7f3e62a983044038e92bevboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
52676b598e9afd834db7f3e62a983044038e92bevboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
52676b598e9afd834db7f3e62a983044038e92bevboxsync; Clara, CA 95054 USA or visit http://www.sun.com if you need
52676b598e9afd834db7f3e62a983044038e92bevboxsync; additional information or have any questions.
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync;*******************************************************************************
52676b598e9afd834db7f3e62a983044038e92bevboxsync;* Header Files *
52676b598e9afd834db7f3e62a983044038e92bevboxsync;*******************************************************************************
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/asmdefs.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/vm.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/err.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/stam.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "CPUMInternal.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/x86.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync%include "VBox/cpum.mac"
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync%ifdef IN_RING3
52676b598e9afd834db7f3e62a983044038e92bevboxsync %error "The jump table doesn't link on leopard."
52676b598e9afd834db7f3e62a983044038e92bevboxsync%endif
52676b598e9afd834db7f3e62a983044038e92bevboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;*******************************************************************************
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;* External Symbols *
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;*******************************************************************************
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncextern NAME(SUPR0AbsIs64bit)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncextern NAME(SUPR0Abs64bitKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncextern NAME(SUPR0Abs64bitKernelSS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncextern NAME(SUPR0Abs64bitKernelDS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncextern NAME(SUPR0AbsKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;*******************************************************************************
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;* Global Variables *
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;*******************************************************************************
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBEGINDATA
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync;;
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync; needing to clobber a register. (This trick doesn't quite work for PE btw.
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync; but that's not relevant atm.)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncGLOBALNAME g_fCPUMIs64bitHost
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync dd NAME(SUPR0AbsIs64bit)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsyncBEGINCODE
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync;;
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync; Saves the host FPU/XMM state and restores the guest state.
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync;
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync; @returns 0
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync;
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncalign 16
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncBEGINPROC cpumR0SaveHostRestoreGuestFPUState
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%ifdef RT_ARCH_AMD64
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync %ifdef RT_OS_WINDOWS
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xDX, rcx
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync %else
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xDX, rdi
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync %endif
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%else
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xDX, dword [esp + 4]
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%endif
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync pushf ; The darwin kernel can get upset or upset things if an
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync ; Switch the state.
dcd6dbbce6129153995caa1e77b258639f6bc030vboxsync or dword [xDX + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xAX, cr0 ; Make sure its safe to access the FPU state.
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xCX, xAX ; save old CR0
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync and xAX, ~(X86_CR0_TS | X86_CR0_EM)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov cr0, xAX ;; @todo optimize this.
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync jz .legacy_mode
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync.legacy_mode:
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync fxsave [xDX + CPUMCPU.Host.fpu] ; ASSUMES that all VT-x/AMD-V boxes sports fxsave/fxrstor (safe assumption)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync fxrstor [xDX + CPUMCPU.Guest.fpu]
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync.done:
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync popf
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync xor eax, eax
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync ret
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncALIGNCODE(16)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncBITS 64
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync.sixtyfourbit_mode:
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync and edx, 0ffffffffh
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync fxsave [rdx + CPUMCPU.Host.fpu]
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync fxrstor [rdx + CPUMCPU.Guest.fpu]
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync jmp far [.fpret wrt rip]
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync.fpret: ; 16:32 Pointer to .the_end.
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync dd .done, NAME(SUPR0AbsKernelCS)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncBITS 32
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync%endif
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsyncENDPROC cpumR0SaveHostRestoreGuestFPUState
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%ifndef RT_ARCH_AMD64
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%ifdef VBOX_WITH_64_BITS_GUESTS
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync;;
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync; Saves the host FPU/XMM state
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync;
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync; @returns 0
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync;
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsyncalign 16
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsyncBEGINPROC cpumR0SaveHostFPUState
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync mov xDX, dword [esp + 4]
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync ; Switch the state.
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync or dword [xDX + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync mov xAX, cr0 ; Make sure its safe to access the FPU state.
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync mov xCX, xAX ; save old CR0
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync and xAX, ~(X86_CR0_TS | X86_CR0_EM)
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync mov cr0, xAX ;; @todo optimize this.
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync fxsave [xDX + CPUMCPU.Host.fpu] ; ASSUMES that all VT-x/AMD-V boxes sports fxsave/fxrstor (safe assumption)
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync xor eax, eax
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync ret
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsyncENDPROC cpumR0SaveHostFPUState
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%endif
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%endif
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync%endif
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync;;
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync; Saves the guest FPU/XMM state and restores the host state.
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; @returns 0
52676b598e9afd834db7f3e62a983044038e92bevboxsync; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsyncalign 16
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBEGINPROC cpumR0SaveGuestRestoreHostFPUState
52676b598e9afd834db7f3e62a983044038e92bevboxsync%ifdef RT_ARCH_AMD64
52676b598e9afd834db7f3e62a983044038e92bevboxsync %ifdef RT_OS_WINDOWS
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, rcx
52676b598e9afd834db7f3e62a983044038e92bevboxsync %else
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, rdi
52676b598e9afd834db7f3e62a983044038e92bevboxsync %endif
52676b598e9afd834db7f3e62a983044038e92bevboxsync%else
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, dword [esp + 4]
52676b598e9afd834db7f3e62a983044038e92bevboxsync%endif
52676b598e9afd834db7f3e62a983044038e92bevboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync ; Only restore FPU if guest has used it.
52676b598e9afd834db7f3e62a983044038e92bevboxsync ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
52676b598e9afd834db7f3e62a983044038e92bevboxsync test dword [xDX + CPUMCPU.fUseFlags], CPUM_USED_FPU
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jz short .fpu_not_used
52676b598e9afd834db7f3e62a983044038e92bevboxsync
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync pushf ; The darwin kernel can get upset or upset things if an
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov xAX, cr0 ; Make sure it's safe to access the FPU state.
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xCX, xAX ; save old CR0
52676b598e9afd834db7f3e62a983044038e92bevboxsync and xAX, ~(X86_CR0_TS | X86_CR0_EM)
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov cr0, xAX ;; @todo optimize this.
52676b598e9afd834db7f3e62a983044038e92bevboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jz .legacy_mode
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync db 0xea ; jmp far .sixtyfourbit_mode
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.legacy_mode:
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
3bf5a39c9314b43d8fe91e4ed18b977e2f87659dvboxsync fxsave [xDX + CPUMCPU.Guest.fpu] ; ASSUMES that all VT-x/AMD-V boxes sports fxsave/fxrstor (safe assumption)
52676b598e9afd834db7f3e62a983044038e92bevboxsync fxrstor [xDX + CPUMCPU.Host.fpu]
52676b598e9afd834db7f3e62a983044038e92bevboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.done:
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync mov cr0, xCX ; and restore old CR0 again ;; @todo optimize this.
52676b598e9afd834db7f3e62a983044038e92bevboxsync and dword [xDX + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync popf
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.fpu_not_used:
52676b598e9afd834db7f3e62a983044038e92bevboxsync xor eax, eax
52676b598e9afd834db7f3e62a983044038e92bevboxsync ret
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncALIGNCODE(16)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBITS 64
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.sixtyfourbit_mode:
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync and edx, 0ffffffffh
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync fxsave [rdx + CPUMCPU.Guest.fpu]
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync fxrstor [rdx + CPUMCPU.Host.fpu]
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jmp far [.fpret wrt rip]
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.fpret: ; 16:32 Pointer to .the_end.
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync dd .done, NAME(SUPR0AbsKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBITS 32
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncENDPROC cpumR0SaveGuestRestoreHostFPUState
52676b598e9afd834db7f3e62a983044038e92bevboxsync
90f2027a781d66b7498ed1e5684e087e4d9d3b1bvboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync;;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; Sets the host's FPU/XMM state
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsync; @returns 0
52676b598e9afd834db7f3e62a983044038e92bevboxsync; @param pCPUMCPU x86:[esp+4] GCC:rdi MSC:rcx CPUMCPU pointer
52676b598e9afd834db7f3e62a983044038e92bevboxsync;
52676b598e9afd834db7f3e62a983044038e92bevboxsyncalign 16
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBEGINPROC cpumR0RestoreHostFPUState
52676b598e9afd834db7f3e62a983044038e92bevboxsync%ifdef RT_ARCH_AMD64
52676b598e9afd834db7f3e62a983044038e92bevboxsync %ifdef RT_OS_WINDOWS
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, rcx
52676b598e9afd834db7f3e62a983044038e92bevboxsync %else
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, rdi
52676b598e9afd834db7f3e62a983044038e92bevboxsync %endif
52676b598e9afd834db7f3e62a983044038e92bevboxsync%else
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xDX, dword [esp + 4]
52676b598e9afd834db7f3e62a983044038e92bevboxsync%endif
52676b598e9afd834db7f3e62a983044038e92bevboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync ; Restore FPU if guest has used it.
52676b598e9afd834db7f3e62a983044038e92bevboxsync ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
52676b598e9afd834db7f3e62a983044038e92bevboxsync test dword [xDX + CPUMCPU.fUseFlags], CPUM_USED_FPU
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jz short .fpu_not_used
52676b598e9afd834db7f3e62a983044038e92bevboxsync
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync pushf ; The darwin kernel can get upset or upset things if an
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xAX, cr0
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov xCX, xAX ; save old CR0
52676b598e9afd834db7f3e62a983044038e92bevboxsync and xAX, ~(X86_CR0_TS | X86_CR0_EM)
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov cr0, xAX
52676b598e9afd834db7f3e62a983044038e92bevboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jz .legacy_mode
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync db 0xea ; jmp far .sixtyfourbit_mode
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.legacy_mode:
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync fxrstor [xDX + CPUMCPU.Host.fpu]
52676b598e9afd834db7f3e62a983044038e92bevboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.done:
52676b598e9afd834db7f3e62a983044038e92bevboxsync mov cr0, xCX ; and restore old CR0 again
52676b598e9afd834db7f3e62a983044038e92bevboxsync and dword [xDX + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
fe479db82741c317766a2b9035cbd92f3f5a745cvboxsync popf
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.fpu_not_used:
52676b598e9afd834db7f3e62a983044038e92bevboxsync xor eax, eax
52676b598e9afd834db7f3e62a983044038e92bevboxsync ret
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncALIGNCODE(16)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBITS 64
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.sixtyfourbit_mode:
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync and edx, 0ffffffffh
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync fxrstor [rdx + CPUMCPU.Host.fpu]
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync jmp far [.fpret wrt rip]
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync.fpret: ; 16:32 Pointer to .the_end.
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync dd .done, NAME(SUPR0AbsKernelCS)
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncBITS 32
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync%endif
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsyncENDPROC cpumR0RestoreHostFPUState
a41a001e5a4dd3f39faab90b412243ced6d59394vboxsync
52676b598e9afd834db7f3e62a983044038e92bevboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
409950536f73e7c9a387f7d548122ae6bffae950vboxsync;;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync; DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
409950536f73e7c9a387f7d548122ae6bffae950vboxsync;
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncALIGNCODE(16)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBEGINPROC cpumR0SaveDRx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef RT_ARCH_AMD64
409950536f73e7c9a387f7d548122ae6bffae950vboxsync %ifdef ASM_CALL64_GCC
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xCX, rdi
409950536f73e7c9a387f7d548122ae6bffae950vboxsync %endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%else
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xCX, dword [esp + 4]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
409950536f73e7c9a387f7d548122ae6bffae950vboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
409950536f73e7c9a387f7d548122ae6bffae950vboxsync jz .legacy_mode
409950536f73e7c9a387f7d548122ae6bffae950vboxsync db 0xea ; jmp far .sixtyfourbit_mode
409950536f73e7c9a387f7d548122ae6bffae950vboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.legacy_mode:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ; Do the job.
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xAX, dr0
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xDX, dr1
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [xCX], xAX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [xCX + 8 * 1], xDX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xAX, dr2
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xDX, dr3
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [xCX + 8 * 2], xAX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [xCX + 8 * 3], xDX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.done:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ret
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncALIGNCODE(16)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBITS 64
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.sixtyfourbit_mode:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync and ecx, 0ffffffffh
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov rax, dr0
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov rdx, dr1
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov r8, dr2
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov r9, dr3
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [rcx], rax
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [rcx + 8 * 1], rdx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [rcx + 8 * 2], r8
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov [rcx + 8 * 3], r9
409950536f73e7c9a387f7d548122ae6bffae950vboxsync jmp far [.fpret wrt rip]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.fpret: ; 16:32 Pointer to .the_end.
409950536f73e7c9a387f7d548122ae6bffae950vboxsync dd .done, NAME(SUPR0AbsKernelCS)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBITS 32
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncENDPROC cpumR0SaveDRx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync;;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync; DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
409950536f73e7c9a387f7d548122ae6bffae950vboxsync;
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncALIGNCODE(16)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBEGINPROC cpumR0LoadDRx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef RT_ARCH_AMD64
409950536f73e7c9a387f7d548122ae6bffae950vboxsync %ifdef ASM_CALL64_GCC
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xCX, rdi
409950536f73e7c9a387f7d548122ae6bffae950vboxsync %endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%else
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xCX, dword [esp + 4]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
409950536f73e7c9a387f7d548122ae6bffae950vboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
409950536f73e7c9a387f7d548122ae6bffae950vboxsync jz .legacy_mode
409950536f73e7c9a387f7d548122ae6bffae950vboxsync db 0xea ; jmp far .sixtyfourbit_mode
409950536f73e7c9a387f7d548122ae6bffae950vboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.legacy_mode:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ; Do the job.
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ;
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xAX, [xCX]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xDX, [xCX + 8 * 1]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr0, xAX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr1, xDX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xAX, [xCX + 8 * 2]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov xDX, [xCX + 8 * 3]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr2, xAX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr3, xDX
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.done:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync ret
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncALIGNCODE(16)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBITS 64
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.sixtyfourbit_mode:
409950536f73e7c9a387f7d548122ae6bffae950vboxsync and ecx, 0ffffffffh
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov rax, [rcx]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov rdx, [rcx + 8 * 1]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov r8, [rcx + 8 * 2]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov r9, [rcx + 8 * 3]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr0, rax
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr1, rdx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr2, r8
409950536f73e7c9a387f7d548122ae6bffae950vboxsync mov dr3, r9
409950536f73e7c9a387f7d548122ae6bffae950vboxsync jmp far [.fpret wrt rip]
409950536f73e7c9a387f7d548122ae6bffae950vboxsync.fpret: ; 16:32 Pointer to .the_end.
409950536f73e7c9a387f7d548122ae6bffae950vboxsync dd .done, NAME(SUPR0AbsKernelCS)
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncBITS 32
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif
409950536f73e7c9a387f7d548122ae6bffae950vboxsyncENDPROC cpumR0LoadDRx
409950536f73e7c9a387f7d548122ae6bffae950vboxsync
409950536f73e7c9a387f7d548122ae6bffae950vboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
8fcaf889c8c3502cb99f4090a83aea7d878b2f48vboxsync