AMD64andLegacy.mac revision af0b37c347057e87a85cfbc869b9e68432de1bae
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; $Id$
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;; @file
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c626bd8465f241db74519c3c8dbe59ea620a9e34vboxsync; Copyright (C) 2006-2012 Oracle Corporation
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; available from http://www.virtualbox.org. This file is free software;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; you can redistribute it and/or modify it under the terms of the GNU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; General Public License (GPL) as published by the Free Software
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;%define DEBUG_STUFF 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;%define STRICT_IF 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;*******************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;* Header Files *
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;*******************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%include "VBox/asmdefs.mac"
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync%include "VBox/apic.mac"
2d97f8baccdd684bc0a8a15eb86bbe9ff2b85374vboxsync%include "iprt/x86.mac"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync%include "VBox/vmm/cpum.mac"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync%include "VBox/vmm/stam.mac"
43747b1f0bc8302a238fb35e55857a5e9aa1933dvboxsync%include "VBox/vmm/vm.mac"
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%include "VBox/err.mac"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%include "CPUMInternal.mac"
0c437bb10c61b229407a7517efde04dfe3b1e4a1vboxsync%include "VMMSwitcher.mac"
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Start the fixup records
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; We collect the fixups in the .data section as we go along
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; It is therefore VITAL that no-one is using the .data section
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; for anything else between 'Start' and 'End'.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINDATA
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME Fixups
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINCODE
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME Start
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 64
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
1b68cc0f95e7b0033b20dfc4fdbc260b7a2cef68vboxsync; @param pVM GCC: rdi MSC:rcx The VM handle.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_CHAR '^'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; The ordinary version of the code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef STRICT_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pushf
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test eax, X86_EFL_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz .if_clear_in
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0c0ffee00h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ret
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.if_clear_in:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; make r9 = pVM and rdx = pCpum.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; rax, rcx and r8 are scratch here after.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef RT_OS_WINDOWS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r9, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r9, rdi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lea rdx, [r9 + VM.cpum]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lea r8, [r9 + VM.StatSwitcherToGC]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM64_PROFILE_ADV_START r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Call worker (far return).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, cs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push rax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync call NAME(vmmR0ToRawModeAsm)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
9b828870d7acf28326746e3850098e579c590a44vboxsync ; Unblock Local APIC NMI vectors
9b828870d7acf28326746e3850098e579c590a44vboxsync ; Do this here to ensure the host CS is already restored
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, [rdx + CPUM.fApicDisVectors]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r8, [rdx + CPUM.pvApicBase]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr ecx, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_nolint0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and dword [r8 + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_nolint0:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr ecx, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_nolint1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and dword [r8 + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_nolint1:
9b828870d7acf28326746e3850098e579c590a44vboxsync shr ecx, 1
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nopc
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_nopc:
9b828870d7acf28326746e3850098e579c590a44vboxsync shr ecx, 1
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_notherm
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_notherm:
9b828870d7acf28326746e3850098e579c590a44vboxsync %endif
9b828870d7acf28326746e3850098e579c590a44vboxsync
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef VBOX_WITH_STATISTICS
9b828870d7acf28326746e3850098e579c590a44vboxsync ;
9b828870d7acf28326746e3850098e579c590a44vboxsync ; Switcher stats.
9b828870d7acf28326746e3850098e579c590a44vboxsync ;
9b828870d7acf28326746e3850098e579c590a44vboxsync lea r8, [r9 + VM.StatSwitcherToGC]
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync STAM64_PROFILE_ADV_STOP r8
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync %endif
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ret
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncENDPROC vmmR0ToRawMode
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync%else ; VBOX_WITH_HYBRID_32BIT_KERNEL
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncBITS 32
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; The C interface.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync;
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncBEGINPROC vmmR0ToRawMode
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %ifdef DEBUG_STUFF
6cac05f856d982151579a9d445a109960c2c07d2vboxsync COM32_S_NEWLINE
6cac05f856d982151579a9d445a109960c2c07d2vboxsync COM32_S_CHAR '^'
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %endif
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %ifdef VBOX_WITH_STATISTICS
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Switcher stats.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov edx, 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync STAM_PROFILE_ADV_START edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %endif
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Thunk to/from 64 bit when invoking the worker routine.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.cpum
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov edx, 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync push 0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync push cs
6cac05f856d982151579a9d445a109960c2c07d2vboxsync push 0
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_32BIT, 1, .vmmR0ToRawModeReturn - NAME(Start)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffffffh
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_64BIT_CS, 1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffh
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_32BIT, 1, NAME(vmmR0ToRawModeAsm) - NAME(Start)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync retf
6cac05f856d982151579a9d445a109960c2c07d2vboxsync.vmmR0ToRawModeReturn:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
9b828870d7acf28326746e3850098e579c590a44vboxsync ;
9b828870d7acf28326746e3850098e579c590a44vboxsync ; This selector reloading is probably not necessary, but we do it anyway to be quite sure
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; the CPU has the right idea about the selectors.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ds
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ds, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, es
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov es, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ss
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Missing implementation!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM_PROFILE_ADV_STOP edx
9b828870d7acf28326746e3850098e579c590a44vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ret
9b828870d7acf28326746e3850098e579c590a44vboxsyncENDPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 64
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif ;!VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Phase one of the switch from host to guest context (host MMU context)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; INPUT:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - edx virtual address of CPUM structure (valid in host context)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; USES/DESTROYS:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - eax, ecx, edx, r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; ASSUMPTION:
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; - current CS and DS selectors are wide open
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC vmmR0ToRawModeAsm
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Store the offset from CPUM to CPUMCPU in r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Save CPU host context
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Skip eax, edx and ecx as these are not preserved over calls.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; general registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov [rdx + r8 + CPUMCPU.Host.rax], rax - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.rbx], rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov [rdx + r8 + CPUMCPU.Host.rcx], rcx - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov [rdx + r8 + CPUMCPU.Host.rdx], rdx - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.rdi], rdi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.rsi], rsi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.rsp], rsp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.rbp], rbp
9b828870d7acf28326746e3850098e579c590a44vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r8 ], r8 - scratch
9b828870d7acf28326746e3850098e579c590a44vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r9 ], r9 - scratch
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r10], r10
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r11], r11
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r12], r12
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r13], r13
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r14], r14
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r15], r15
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; selectors.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.ds], ds
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.es], es
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.fs], fs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.gs], gs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.ss], ss
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; MSRs
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov rbx, rdx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_FS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync mov [rbx + r8 + CPUMCPU.Host.FSbase], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.FSbase + 4], edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_GS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.GSbase], eax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov [rbx + r8 + CPUMCPU.Host.GSbase + 4], edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.efer], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.efer + 4], edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; special registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync sldt [rdx + r8 + CPUMCPU.Host.ldtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync sidt [rdx + r8 + CPUMCPU.Host.idtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync sgdt [rdx + r8 + CPUMCPU.Host.gdtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync str [rdx + r8 + CPUMCPU.Host.tr] ; yasm BUG, generates sldt. YASMCHECK!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; flags
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pushf
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop qword [rdx + r8 + CPUMCPU.Host.rflags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Block Local APIC NMI vectors
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync mov rbx, [rdx + CPUM.pvApicBase]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or rbx, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz htg_noapic
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xor edi, edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nolint0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x01
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_LINT0], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_nolint0:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nolint1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x02
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_LINT1], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_nolint1:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_PC]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nopc
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x04
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_PC], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_PC] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_nopc:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_VERSION]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync shr eax, 16
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp al, 5
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jb htg_notherm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_THMR]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_notherm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x08
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_THMR], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_THMR] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_notherm:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + CPUM.fApicDisVectors], edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_noapic:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif ; VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; save MSR_IA32_SYSENTER_CS register.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rbx, rdx ; save edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_SYSENTER_CS
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr ; edx:eax <- MSR[ecx]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4], edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor eax, eax ; load 0:0 to cause #GP upon sysenter
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor edx, edx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync wrmsr
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rdx, rbx ; restore edx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jmp short htg_no_sysenter
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsyncALIGNCODE(16)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_no_sysenter:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;; handle use flags.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and esi, ~CPUM_USED_FPU ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.fUseFlags], esi
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; debug registers.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jz htg_debug_regs_no
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jmp htg_debug_regs_save
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_debug_regs_no:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync DEBUG_CHAR('a') ; trashes esi
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; control registers.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr0
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr0], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;mov rax, cr2 ; assume host os don't stuff things in cr2. (safe)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;mov [rdx + r8 + CPUMCPU.Host.cr2], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr3
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr3], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr4
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr4], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;;
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;; Start switching to VMM context.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;;
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Change CR0 and CR4 so we can correctly emulate FPU/MMX/SSE[23] exceptions
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Also disable WP. (eax==cr4 now)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Note! X86_CR4_PSE and X86_CR4_PAE are important if the host thinks so :-)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ;
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and rax, X86_CR4_MCE | X86_CR4_PSE | X86_CR4_PAE
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ecx, [rdx + r8 + CPUMCPU.Guest.cr4]
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync DEBUG_CHAR('b') ; trashes esi
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ;; @todo Switcher cleanup: Determine base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; in CPUMCPU.Hyper.cr4 (which isn't currently being used). That should
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; simplify this operation a bit (and improve locality of the data).
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; CR4.AndMask and CR4.OrMask are set in CPUMR3Init based on the presence of
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; FXSAVE support on the host CPU
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, [rdx + CPUM.CR4.AndMask]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, ecx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, [rdx + CPUM.CR4.OrMask]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov cr4, rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync DEBUG_CHAR('c') ; trashes esi
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov eax, [rdx + r8 + CPUMCPU.Guest.cr0]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, X86_CR0_EM
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov cr0, rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('0') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Load new gdt so we can do far jump to guest code after cr3 reload.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync lgdt [rdx + r8 + CPUMCPU.Hyper.gdtr]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('1') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Store the hypervisor cr3 for later loading
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebp, [rdx + r8 + CPUMCPU.Hyper.cr3]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;; Load Intermediate memory context.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_INTER_AMD64_CR3, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov eax, 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov cr3, rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('2') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;; 1. Switch to compatibility mode, placing ourselves in identity mapped code.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp far [NAME(fpIDEnterTarget) wrt rip]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; 16:32 Pointer to IDEnterTarget.
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncNAME(fpIDEnterTarget):
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_ID_32BIT, 0, NAME(IDEnterTarget) - NAME(Start)
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncdd 0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HYPER_CS, 0
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncdd 0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync;;
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; Detour for saving the host DR7 and DR6.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; esi and rdx must be preserved.
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_debug_regs_save:
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncDEBUG_S_CHAR('s');
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rax, dr7 ; not sure, but if I read the docs right this will trap if GD is set. FIXME!!!
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr7], rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor eax, eax ; clear everything. (bit 12? is read as 1...)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov dr7, rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rax, dr6 ; just in case we save the state register too.
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr6], rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; save host DR0-3?
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync test esi, CPUM_USE_DEBUG_REGS
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jz near htg_debug_regs_no
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsyncDEBUG_S_CHAR('S');
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rax, dr0
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr0], rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rbx, dr1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr1], rbx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rcx, dr2
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr2], rcx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rax, dr3
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr3], rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp htg_debug_regs_no
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; We're now on identity mapped pages in 32-bit compatibility mode.
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncBITS 32
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncALIGNCODE(16)
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncGLOBALNAME IDEnterTarget
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('3')
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; 2. Deactivate long mode by turning off paging.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ebx, cr0
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ebx, ~X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync ; 3. Load intermediate page table.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov edx, 0ffffffffh
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov cr3, edx
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync ; 4. Disable long mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We also use the chance to disable syscall/sysret and fast fxsave/fxrstor.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('5')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and eax, ~(MSR_K6_EFER_LME | MSR_K6_EFER_SCE | MSR_K6_EFER_FFXSR)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifndef SWITCHER_TO_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 4b. Disable PAE.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and eax, ~X86_CR4_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync%else
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 5. Enable paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or ebx, X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short just_a_jump
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncjust_a_jump:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('7')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 6. Jump to guest code mapping of the code and load the Hypervisor CS.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_ID_2_GC_NEAR_REL, 1, NAME(JmpGCTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp near NAME(JmpGCTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; When we arrive at this label we're at the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; guest code mapping of the switching code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME JmpGCTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('-')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;mov eax, 0ffff0000h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;.delay_loop:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;nop
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;dec eax
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync;nop
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;jnz .delay_loop
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3 and do far jump to load cs.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, ebp ; ebp set above
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('0')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; We're in VMM MMU context and VMM CS is loaded.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Setup the rest of the VMM state.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load selectors
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('1')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HYPER_DS, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ds, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov es, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xor eax, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov gs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov fs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load pCpum into EDX
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate guest IDT
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync lidt [edx + CPUMCPU.Hyper.idtr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync ; Setup the stack.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ax, [edx + CPUMCPU.Hyper.ss.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, ax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esp, [edx + CPUMCPU.Hyper.esp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_TSS_GDTE_DW2, 2
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and dword [0ffffffffh], ~0200h ; clear busy flag (2nd type2 bit)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('5')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ltr word [edx + CPUMCPU.Hyper.tr.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate the ldt (now we can safely crash).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lldt [edx + CPUMCPU.Hyper.ldtr.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('7')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esi, [edx + CPUMCPU.fUseFlags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; debug registers
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jnz htg_debug_regs_guest
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_guest_done:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('9')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; General registers (sans edx).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.eax]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ebx, [edx + CPUMCPU.Hyper.ebx]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ecx, [edx + CPUMCPU.Hyper.ecx]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ebp, [edx + CPUMCPU.Hyper.ebp]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov esi, [edx + CPUMCPU.Hyper.esi]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov edi, [edx + CPUMCPU.Hyper.edi]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('!')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ;; Return to the VMM code which either called the switcher or
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ;; the code set up to run by HC.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push dword [edx + CPUMCPU.Hyper.eflags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push cs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push dword [edx + CPUMCPU.Hyper.eip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [edx + CPUMCPU.Hyper.edx] ; !! edx is no longer pointing to CPUMCPU here !!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eip='
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [esp + 8]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_DWORD_REG eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR ';'
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToGC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iret ; Use iret to make debugging and TF/RF work.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
ee2aeb0cd5535f38ee098713a9cebb74dc1c2e30vboxsync; Detour for saving host DR0-3 and loading hypervisor debug registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; esi and edx must be preserved.
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_guest:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('D')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('R')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('x')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load hyper DR0-7
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, [edx + CPUMCPU.Hyper.dr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, [edx + CPUMCPU.Hyper.dr + 8*1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr1, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*2]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr2, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, [edx + CPUMCPU.Hyper.dr + 8*3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr3, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov eax, [edx + CPUMCPU.Hyper.dr + 8*6]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, 0ffff0ff0h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr6, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*7]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp htg_debug_regs_guest_done
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncENDPROC vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Trampoline for doing a call when starting the hyper visor execution.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Push any arguments to the routine.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Push the argument frame size (cArg * 4).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Push the call target (_cdecl convention).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Push the address of this routine.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR 'c'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR 't'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '!'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; call routine
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop eax ; call address
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync pop edi ; argument count.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eax='
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_DWORD_REG eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR ';'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync call eax ; do call
c64777b77514bdc924249d2f9900be25079b0d84vboxsync add esp, edi ; cleanup stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; return to the host context (eax = C returncode).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '`'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.to_host_again:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync call NAME(vmmRCToHostAsm)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, VERR_VMM_SWITCHER_IPE_1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp .to_host_again
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncENDPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsyncBEGINPROC vmmRCToHost
c8968199d271abe749c08bcea0512f7239250cdcvboxsync%ifdef DEBUG_STUFF
c8968199d271abe749c08bcea0512f7239250cdcvboxsync push esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('b')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('a')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('c')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('k')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('!')
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync COM_NEWLINE
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync pop esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [esp + 4]
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync jmp NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHost
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; vmmRCToHostAsmNoReturn
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync; This is an entry point used by TRPM when dealing with raw-mode traps,
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; i.e. traps in the hypervisor code. This will not return and saves no
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; state, because the caller has already saved the state.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param eax Return code.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncBEGINPROC vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%ifdef VBOX_WITH_STATISTICS
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp vmmRCToHostAsm_SaveNoGeneralRegs
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHostAsmNoReturn
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; This is an entry point used by TRPM to return to host context when an
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; interrupt occured or an guest trap needs handling in host context. It
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; is also used by the C interface above.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; The hypervisor context is saved and it will return to the caller if
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync; host context so desires.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param eax Return code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @uses eax, edx, ecx (or it may use them in the future)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('%')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP edx
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync%endif
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Load the CPUM pointer.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Save register context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop dword [edx + CPUMCPU.Hyper.edx]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop dword [edx + CPUMCPU.Hyper.eip] ; call return from stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.esp], esp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.eax], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ebx], ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ecx], ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.esi], esi
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov dword [edx + CPUMCPU.Hyper.edi], edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ebp], ebp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; special registers which may change.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncvmmRCToHostAsm_SaveNoGeneralRegs:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef STRICT_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pushf
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test ecx, X86_EFL_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz .if_clear_out
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0c0ffee01h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cli
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.if_clear_out:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; str [edx + CPUMCPU.Hyper.tr] - double fault only, and it won't be right then either.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync sldt [edx + CPUMCPU.Hyper.ldtr.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; No need to save CRx here. They are set dynamically according to Guest/Host requirements.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; FPU context is saved before restore of host saving (another) branch.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Load Intermediate memory context.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('?')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; We're now in intermediate memory context!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 0. Jump to identity mapped location
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_2_ID_NEAR_REL, 1, NAME(IDExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp near NAME(IDExitTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We're now on identity mapped pages!
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME IDExitTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('1')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 1. Disable paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ebx, ~X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('2')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 2. Enable PAE.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%ifdef SWITCHER_TO_PAE
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; - already enabled
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%else
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, cr4
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or ecx, X86_CR4_PAE
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr4, ecx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 3. Load long mode intermediate CR3.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_INTER_AMD64_CR3, 1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr3, ecx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('3')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 4. Enable long mode.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ebp, edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, MSR_K6_EFER
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync rdmsr
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or eax, MSR_K6_EFER_LME
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync wrmsr
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, ebp
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('4')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 5. Enable paging.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or ebx, X86_CR0_PG
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr0, ebx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('5')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Jump from compatibility mode to 64-bit mode.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_ID_FAR32_TO_64BIT_MODE, 1, NAME(IDExit64Mode) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp 0ffffh:0fffffffeh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We're in 64-bit mode (ds, ss, es, fs, gs are all bogus).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Move on to the HC mapping.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBITS 64
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncNAME(IDExit64Mode):
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('6')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp [NAME(pHCExitTarget) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; 64-bit jump target
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncNAME(pHCExitTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT, 0, NAME(HCExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit pCpum address.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pCpumHC):
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncFIXUP FIX_HC_64BIT_CPUM, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncdq 0ffffffffffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; When we arrive here we're at the host context
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mapping of the switcher code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME HCExitTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('9')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Clear high dword of the CPUMCPU pointer
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rdx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rsi, [rdx + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rsi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('@')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Restore Host context.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load CPUM pointer into edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, [NAME(pCpumHC) wrt rip]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Load the CPUMCPU offset.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; activate host gdt and idt
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync lgdt [rdx + r8 + CPUMCPU.Host.gdtr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync DEBUG_CHAR('0')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync lidt [rdx + r8 + CPUMCPU.Host.idtr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync DEBUG_CHAR('1')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%if 1 ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and al, 0F8h ; mask away TI and RPL bits, get descriptor offset.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync add rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2] ; eax <- GDTR.address + descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and dword [rax + 4], ~0200h ; clear busy flag (2nd type2 bit)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ltr word [rdx + r8 + CPUMCPU.Host.tr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and al, 0F8h ; mask away TI and RPL bits, get descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync add rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2] ; eax <- GDTR.address + descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, [rax + 4] ; ecx <- 2nd descriptor dword
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, ecx ; save original value
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, ~0200h ; clear busy flag (2nd type2 bit)
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync mov [rax + 4], ccx ; not using xchg here is paranoia..
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync ltr word [rdx + r8 + CPUMCPU.Host.tr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync xchg [rax + 4], ebx ; using xchg is paranoia too...
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; activate ldt
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lldt [rdx + r8 + CPUMCPU.Host.ldtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore segment registers
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.ds]
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync mov ds, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.es]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov es, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.fs]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov fs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.gs]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov gs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.ss]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_NO_SYSENTER_JMP, 0, gth_sysenter_no - NAME(Start) ; this will insert a jmp gth_sysenter_no if host doesn't use sysenter.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore MSR_IA32_SYSENTER_CS register.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, rdx ; save edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_IA32_SYSENTER_CS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.SysEnter.cs]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr ; MSR[ecx] <- edx:eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx ; restore edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short gth_sysenter_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_sysenter_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; @todo AMD syscall
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore FPU if guest has used it.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USED_FPU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rcx, ~(X86_CR0_TS | X86_CR0_EM)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync fxsave [rdx + r8 + CPUMCPU.Guest.fpu]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync fxrstor [rdx + r8 + CPUMCPU.Host.fpu]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_fpu_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Control registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Would've liked to have these higher up in case of crashes, but
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; the fpu stuff must be done before we restore cr0.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.cr4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test rcx, X86_CR4_PCIDE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz gth_no_pcide
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rax, ~0xfff ; clear the PCID in cr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax ; reload it with the right PCID.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_restored_cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_no_pcide:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_restored_cr4:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.cr0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov rcx, [rdx + r8 + CPUMCPU.Host.cr2] ; assumes this is waste of time.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync ;mov cr2, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore debug registers (if modified) (esi must still be fUseFlags!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; (must be done after cr4 reload because of the debug extension.)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_debug_regs_restore
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_debug_regs_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore MSRs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, rdx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_FS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.FSbase]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.FSbase + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_GS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.GSbase]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.GSbase + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.efer]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.efer + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore general registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, edi ; restore return code. eax = return code !!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rax, [rdx + r8 + CPUMCPU.Host.rax] - scratch + return code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.rbx]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rcx, [rdx + r8 + CPUMCPU.Host.rcx] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rdx, [rdx + r8 + CPUMCPU.Host.rdx] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdi, [rdx + r8 + CPUMCPU.Host.rdi]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov rsi, [rdx + r8 + CPUMCPU.Host.rsi]
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync mov rbp, [rdx + r8 + CPUMCPU.Host.rbp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov r8, [rdx + r8 + CPUMCPU.Host.r8 ] - scratch
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; mov r9, [rdx + r8 + CPUMCPU.Host.r9 ] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r10, [rdx + r8 + CPUMCPU.Host.r10]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r11, [rdx + r8 + CPUMCPU.Host.r11]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r12, [rdx + r8 + CPUMCPU.Host.r12]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r13, [rdx + r8 + CPUMCPU.Host.r13]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r14, [rdx + r8 + CPUMCPU.Host.r14]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r15, [rdx + r8 + CPUMCPU.Host.r15]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; finally restore flags. (probably not required)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push qword [rdx + r8 + CPUMCPU.Host.rflags]
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync popf
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_CHAR '4'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db 048h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync retf
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Detour for restoring the host debug registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; edx and edi must be preserved.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_debug_regs_restore:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('d')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xor eax, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, rax ; paranoia or not?
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_debug_regs_dr7
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('r')
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync mov rax, [rdx + r8 + CPUMCPU.Host.dr0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr0, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.dr1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr1, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.dr2]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr2, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.dr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_debug_regs_dr7:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.dr6]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr6, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.dr7]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncENDPROC vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME End
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The description string (in the text section).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(Description):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db SWITCHER_DESCRIPTION
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db 0
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncextern NAME(Relocate)
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; End the fixup records.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINDATA
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db FIX_THE_END ; final entry.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME FixupsEnd
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The switcher definition structure.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNDATA(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME Def
c64777b77514bdc924249d2f9900be25079b0d84vboxsync istruc VMMSWITCHERDEF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.pvCode, RTCCPTR_DEF NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.pvFixups, RTCCPTR_DEF NAME(Fixups)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.pszDesc, RTCCPTR_DEF NAME(Description)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.pfnRelocate, RTCCPTR_DEF NAME(Relocate)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.enmType, dd SWITCHER_TYPE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbCode, dd NAME(End) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offR0ToRawMode, dd NAME(vmmR0ToRawMode) - NAME(Start)
c931fade4656c734f88a44f9237c897cdd0ebdeevboxsync at VMMSWITCHERDEF.offRCToHost, dd NAME(vmmRCToHost) - NAME(Start)
23795b52925e0506e39a546334af089b8f93c50avboxsync at VMMSWITCHERDEF.offRCCallTrampoline, dd NAME(vmmRCCallTrampoline) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offRCToHostAsm, dd NAME(vmmRCToHostAsm) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offRCToHostAsmNoReturn, dd NAME(vmmRCToHostAsmNoReturn) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; disasm help
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offHCCode0, dd 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbHCCode0, dd NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offHCCode1, dd NAME(HCExitTarget) - NAME(Start)
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync at VMMSWITCHERDEF.cbHCCode1, dd NAME(End) - NAME(HCExitTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offIDCode0, dd NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbIDCode0, dd NAME(JmpGCTarget) - NAME(IDEnterTarget)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.cbIDCode1, dd NAME(HCExitTarget) - NAME(IDExitTarget)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.offGCCode, dd NAME(JmpGCTarget) - NAME(Start)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.cbGCCode, dd NAME(IDExitTarget) - NAME(JmpGCTarget)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync iend
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync