c64777b77514bdc924249d2f9900be25079b0d84vboxsync; $Id$
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;; @file
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c626bd8465f241db74519c3c8dbe59ea620a9e34vboxsync; Copyright (C) 2006-2014 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 r8d, [rdx + CPUM.offCPUMCPU0]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, [rdx + r8 + CPUMCPU.fApicDisVectors]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync test ecx, ecx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jz gth64_apic_done
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp byte [rdx + r8 + CPUMCPU.fX2Apic], 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync je gth64_x2apic
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
c7cb9c421f9eb85ddbb0ff0ffc7c1402bfff4b4fvboxsync ; Legacy xAPIC mode:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r8, [rdx + r8 + CPUMCPU.pvApicBase]
9b828870d7acf28326746e3850098e579c590a44vboxsync shr ecx, 1
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nolint0
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_nolint0:
9b828870d7acf28326746e3850098e579c590a44vboxsync shr ecx, 1
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nolint1
9b828870d7acf28326746e3850098e579c590a44vboxsync 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:
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync shr ecx, 1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jnc gth64_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and dword [r8 + APIC_REG_LVT_CMCI], ~APIC_REG_LVT_MASKED
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsyncgth64_nocmci:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync shr ecx, 1
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync jnc gth64_noeilvt0
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync and dword [r8 + APIC_REG_EILVT0], ~APIC_REG_LVT_MASKED
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsyncgth64_noeilvt0:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync shr ecx, 1
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync jnc gth64_noeilvt1
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync and dword [r8 + APIC_REG_EILVT1], ~APIC_REG_LVT_MASKED
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsyncgth64_noeilvt1:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync shr ecx, 1
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync jnc gth64_noeilvt2
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync and dword [r8 + APIC_REG_EILVT2], ~APIC_REG_LVT_MASKED
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsyncgth64_noeilvt2:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync shr ecx, 1
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync jnc gth64_noeilvt3
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync and dword [r8 + APIC_REG_EILVT3], ~APIC_REG_LVT_MASKED
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsyncgth64_noeilvt3:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp gth64_apic_done
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
c7cb9c421f9eb85ddbb0ff0ffc7c1402bfff4b4fvboxsync ; x2APIC mode:
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_x2apic:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r8, rax ; save rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r10, rcx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr r10d, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_x2_nolint0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT0 >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_x2_nolint0:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr r10d, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_x2_nolint1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT1 >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_x2_nolint1:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr r10d, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_x2_nopc
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_PC >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_x2_nopc:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr r10d, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_x2_notherm
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_x2_notherm:
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync shr r10d, 1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jnc gth64_x2_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync rdmsr
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and eax, ~APIC_REG_LVT_MASKED
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync wrmsr
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsyncgth64_x2_nocmci:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rax, r8 ; restore rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_apic_done:
9b828870d7acf28326746e3850098e579c590a44vboxsync %endif
9b828870d7acf28326746e3850098e579c590a44vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lea r8, [r9 + VM.StatSwitcherToGC]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM64_PROFILE_ADV_STOP r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ret
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%else ; VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 32
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawMode
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '^'
9b828870d7acf28326746e3850098e579c590a44vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Thunk to/from 64 bit when invoking the worker routine.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.cpum
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push cs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_HC_32BIT, 1, .vmmR0ToRawModeReturn - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_64BIT_CS, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_HC_32BIT, 1, NAME(vmmR0ToRawModeAsm) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync retf
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync.vmmR0ToRawModeReturn:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
9b828870d7acf28326746e3850098e579c590a44vboxsync Missing implementation!
9b828870d7acf28326746e3850098e579c590a44vboxsync %endif
9b828870d7acf28326746e3850098e579c590a44vboxsync
9b828870d7acf28326746e3850098e579c590a44vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM_PROFILE_ADV_STOP edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ret
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 64
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%endif ;!VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; 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:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - current CS and DS selectors are wide open
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Store the offset from CPUM to CPUMCPU in r8
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r8 ], r8 - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r9 ], r9 - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r10], r10
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r11], r11
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, rdx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_FS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; Block Local APIC NMI vectors
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp byte [rdx + r8 + CPUMCPU.fX2Apic], 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync je htg_x2apic
c7cb9c421f9eb85ddbb0ff0ffc7c1402bfff4b4fvboxsync
31250b8efa089fa62e6f4613ae71de0b3957d739vboxsync ; Legacy xAPIC mode. No write completion required when writing to the
31250b8efa089fa62e6f4613ae71de0b3957d739vboxsync ; LVT registers as we have mapped the APIC page non-cacheable and the
31250b8efa089fa62e6f4613ae71de0b3957d739vboxsync ; MMIO is CPU-local.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rbx, [rdx + r8 + CPUMCPU.pvApicBase]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or rbx, rbx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jz htg_apic_done
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor edi, edi ; fApicDisVectors
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov ecx, eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jne htg_nolint0
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or edi, 0x01
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, APIC_REG_LVT_MASKED
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + APIC_REG_LVT_LINT0], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_nolint0:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov ecx, eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jne htg_nolint1
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or edi, 0x02
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, APIC_REG_LVT_MASKED
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + APIC_REG_LVT_LINT1], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_nolint1:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_PC]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov ecx, eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jne htg_nopc
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or edi, 0x04
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, APIC_REG_LVT_MASKED
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + APIC_REG_LVT_PC], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_nopc:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_VERSION]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync shr eax, 16
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync push rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync cmp al, 5
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jb htg_notherm
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync je htg_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov eax, [rbx + APIC_REG_LVT_CMCI]
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ecx, eax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jne htg_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync or edi, 0x10
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync or eax, APIC_REG_LVT_MASKED
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rbx + APIC_REG_LVT_CMCI], eax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsynchtg_nocmci:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_THMR]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov ecx, eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jne htg_notherm
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or edi, 0x08
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, APIC_REG_LVT_MASKED
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + APIC_REG_LVT_THMR], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_notherm:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync pop rax
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync test ah, ah
48eb91b3fb1dfa50f67016efe43472c3f7058bc2vboxsync jns htg_noeilvt
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync ; AMD Extended LVT registers
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync mov esi, [rbx + 0x400]
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync shr esi, 16
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync and esi, 0xff
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync jz htg_noeilvt
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync mov ebp, 0x20
e153d6933f9a73d7071afc4b501b4c1489243818vboxsynchtg_tsteilvtx:
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync mov eax, [rbx + APIC_REG_EILVT0]
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync mov ecx, eax
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync jne htg_noeilvtx
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync or edi, ebp
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync or eax, APIC_REG_LVT_MASKED
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync mov [rbx + APIC_REG_EILVT0], eax
e153d6933f9a73d7071afc4b501b4c1489243818vboxsynchtg_noeilvtx:
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync add rbx, 0x10 ; clobbers rbx!
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync shl ebp, 1
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync dec esi
e153d6933f9a73d7071afc4b501b4c1489243818vboxsync jnz htg_tsteilvtx
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsync
80df0ee26f97f8e12c6bb0506d4d901ce7a76357vboxsynchtg_noeilvt:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.fApicDisVectors], edi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp htg_apic_done
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
c7cb9c421f9eb85ddbb0ff0ffc7c1402bfff4b4fvboxsync ; x2APIC mode:
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_x2apic:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r15, rdx ; save rdx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor edi, edi ; fApicDisVectors
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT0 >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebx, eax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp ebx, APIC_REG_LVT_MODE_NMI
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jne htg_x2_nolint0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or edi, 0x01
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_x2_nolint0:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_LINT1 >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebx, eax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp ebx, APIC_REG_LVT_MODE_NMI
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jne htg_x2_nolint1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or edi, 0x02
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_x2_nolint1:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_PC >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebx, eax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp ebx, APIC_REG_LVT_MODE_NMI
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jne htg_x2_nopc
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or edi, 0x04
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_x2_nopc:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_VERSION >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync shr eax, 16
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp al, 5
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jb htg_x2_notherm
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync je htg_x2_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_CMCI >> 4)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync rdmsr
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ebx, eax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync cmp ebx, APIC_REG_LVT_MODE_NMI
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jne htg_x2_nocmci
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync or edi, 0x10
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync or eax, APIC_REG_LVT_MASKED
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync wrmsr
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsynchtg_x2_nocmci:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_X2APIC_START + (APIC_REG_LVT_THMR >> 4)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebx, eax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and ebx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync cmp ebx, APIC_REG_LVT_MODE_NMI
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jne htg_x2_notherm
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or edi, 0x08
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsync wrmsr
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_x2_notherm:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rdx, r15
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.fApicDisVectors], edi
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_apic_done:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif ; VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync
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.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; save MSR_IA32_SYSENTER_CS register.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, rdx ; save edx
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov ecx, MSR_IA32_SYSENTER_CS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr ; edx:eax <- MSR[ecx]
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs], eax
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4], edx
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync xor eax, eax ; load 0:0 to cause #GP upon sysenter
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync xor edx, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx ; restore edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short htg_no_sysenter
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_no_sysenter:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; handle use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and esi, ~CPUM_USED_FPU ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.fUseFlags], esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; debug registers.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test esi, CPUM_USE_DEBUG_REGS_HYPER | CPUM_USE_DEBUG_REGS_HOST
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jnz htg_debug_regs_save
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('a') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; control registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.cr0], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov rax, cr2 ; assume host os don't stuff things in cr2. (safe)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov [rdx + r8 + CPUMCPU.Host.cr2], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, cr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.cr3], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.cr4], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Start switching to VMM context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Change CR0 and CR4 so we can correctly emulate FPU/MMX/SSE[23] exceptions
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Also disable WP. (eax==cr4 now)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Note! X86_CR4_PSE and X86_CR4_PAE are important if the host thinks so :-)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rax, X86_CR4_MCE | X86_CR4_PSE | X86_CR4_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, [rdx + r8 + CPUMCPU.Guest.cr4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('b') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; @todo Switcher cleanup: Determine base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; in CPUMCPU.Hyper.cr4 (which isn't currently being used). That should
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; simplify this operation a bit (and improve locality of the data).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; CR4.AndMask and CR4.OrMask are set in CPUMR3Init based on the presence of
b213616e0471f3407de0b025f3fac4727c4f10f4vboxsync ; FXSAVE and XSAVE support on the host CPU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, [rdx + CPUM.CR4.AndMask]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, [rdx + CPUM.CR4.OrMask]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('c') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Guest.cr0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and eax, X86_CR0_EM
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('0') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load new gdt so we can do far jump to guest code after cr3 reload.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync lgdt [rdx + r8 + CPUMCPU.Hyper.gdtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('1') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync ; Store the hypervisor cr3 for later loading
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebp, [rdx + r8 + CPUMCPU.Hyper.cr3]
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Load Intermediate memory context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_INTER_AMD64_CR3, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 1. Switch to compatibility mode, placing ourselves in identity mapped code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp far [NAME(fpIDEnterTarget) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 16:32 Pointer to IDEnterTarget.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(fpIDEnterTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_ID_32BIT, 0, NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdd 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HYPER_CS, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdd 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Detour for saving the host DR7 and DR6.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; esi and rdx must be preserved.
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_save:
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncDEBUG_S_CHAR('s');
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, dr7 ; not sure, but if I read the docs right this will trap if GD is set. FIXME!!!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr7], rax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ecx, X86_DR7_INIT_VAL
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync cmp eax, ecx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync je .htg_debug_regs_dr7_disabled
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov dr7, rcx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync.htg_debug_regs_dr7_disabled:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, dr6 ; just in case we save the state register too.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr6], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; save host DR0-3?
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test esi, CPUM_USE_DEBUG_REGS_HYPER
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jz htg_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncDEBUG_S_CHAR('S');
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, dr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr0], rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, dr1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr1], rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, dr2
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr2], rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, dr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.dr3], rax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync or dword [rdx + r8 + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HOST
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp htg_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; We're now on identity mapped pages in 32-bit compatibility mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 32
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME IDEnterTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 2. Deactivate long mode by turning off paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ebx, ~X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
ee2aeb0cd5535f38ee098713a9cebb74dc1c2e30vboxsync ; 3. Load intermediate page table.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%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 ; load final cr3 and do far jump to load cs.
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync 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
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate guest IDT
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync lidt [edx + CPUMCPU.Hyper.idtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Setup the stack.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync mov ax, [edx + CPUMCPU.Hyper.ss.Sel]
c8968199d271abe749c08bcea0512f7239250cdcvboxsync mov ss, ax
c8968199d271abe749c08bcea0512f7239250cdcvboxsync mov esp, [edx + CPUMCPU.Hyper.esp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_TSS_GDTE_DW2, 2
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and dword [0ffffffffh], ~0200h ; clear busy flag (2nd type2 bit)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('5')
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync ltr word [edx + CPUMCPU.Hyper.tr.Sel]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate the ldt (now we can safely crash).
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync lldt [edx + CPUMCPU.Hyper.ldtr.Sel]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('7')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Use flags.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov esi, [edx + CPUMCPU.fUseFlags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; debug registers
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test esi, CPUM_USE_DEBUG_REGS_HYPER
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jnz htg_debug_regs_guest
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsynchtg_debug_regs_guest_done:
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('9')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; General registers (sans edx).
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, [edx + CPUMCPU.Hyper.eax]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebx, [edx + CPUMCPU.Hyper.ebx]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, [edx + CPUMCPU.Hyper.ecx]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebp, [edx + CPUMCPU.Hyper.ebp]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov esi, [edx + CPUMCPU.Hyper.esi]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edi, [edx + CPUMCPU.Hyper.edi]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('!')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Return to the VMM code which either called the switcher or
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; the code set up to run by HC.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync push dword [edx + CPUMCPU.Hyper.eflags]
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync push cs
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync push dword [edx + CPUMCPU.Hyper.eip]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, [edx + CPUMCPU.Hyper.edx] ; !! edx is no longer pointing to CPUMCPU here !!
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eip='
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync push eax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, [esp + 8]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_DWORD_REG eax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync pop eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR ';'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef VBOX_WITH_STATISTICS
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync push eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToGC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_STOP eax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync pop eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync iret ; Use iret to make debugging and TF/RF work.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 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
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebx, [edx + CPUMCPU.Hyper.dr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr0, ebx
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ecx, [edx + CPUMCPU.Hyper.dr + 8*1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr1, ecx
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*2]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr2, eax
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebx, [edx + CPUMCPU.Hyper.dr + 8*3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr3, ebx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ecx, X86_DR6_INIT_VAL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr6, ecx
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*7]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync or dword [edx + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HYPER
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp htg_debug_regs_guest_done
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC 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)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; return to the host context (eax = C returncode).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '`'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync.to_host_again:
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync call NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, VERR_VMM_SWITCHER_IPE_1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp .to_host_again
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHost
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('b')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('a')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('c')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('k')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('!')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [esp + 4]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHost
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; 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;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; @param eax Return code.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%ifdef VBOX_WITH_STATISTICS
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_STOP edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp vmmRCToHostAsm_SaveNoGeneralRegs
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHostAsmNoReturn
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;;
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmRCToHostAsm
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync;
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
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; 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)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHostAsm
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync push edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load the CPUM pointer.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Save register context.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync pop dword [edx + CPUMCPU.Hyper.edx]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync pop dword [edx + CPUMCPU.Hyper.eip] ; call return from stack
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov dword [edx + CPUMCPU.Hyper.esp], esp
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov dword [edx + CPUMCPU.Hyper.eax], eax
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov dword [edx + CPUMCPU.Hyper.ebx], ebx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov dword [edx + CPUMCPU.Hyper.ecx], ecx
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov dword [edx + CPUMCPU.Hyper.esi], esi
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov dword [edx + CPUMCPU.Hyper.edi], edi
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov dword [edx + CPUMCPU.Hyper.ebp], ebp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; special registers which may change.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncvmmRCToHostAsm_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
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; str [edx + CPUMCPU.Hyper.tr] - double fault only, and it won't be right then either.
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync sldt [edx + CPUMCPU.Hyper.ldtr.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; No need to save CRx here. They are set dynamically according to Guest/Host requirements.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; FPU context is saved before restore of host saving (another) branch.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ; Disable debug registers if active so they cannot trigger while switching.
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync test dword [edx + CPUMCPU.fUseFlags], CPUM_USED_DEBUG_REGS_HYPER
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jz .gth_disabled_dr7
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, X86_DR7_INIT_VAL
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov dr7, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync.gth_disabled_dr7:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Load Intermediate memory context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 2. Enable PAE.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef SWITCHER_TO_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; - already enabled
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%else
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or ecx, X86_CR4_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 3. Load long mode intermediate CR3.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_INTER_AMD64_CR3, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 4. Enable long mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebp, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync rdmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, MSR_K6_EFER_LME
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ebp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 5. Enable paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or ebx, X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('5')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync ; Jump from compatibility mode to 64-bit mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_ID_FAR32_TO_64BIT_MODE, 1, NAME(IDExit64Mode) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp 0ffffh:0fffffffeh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We're in 64-bit mode (ds, ss, es, fs, gs are all bogus).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Move on to the HC mapping.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBITS 64
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(IDExit64Mode):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp [NAME(pHCExitTarget) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit jump target
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pHCExitTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT, 0, NAME(HCExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit pCpum address.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pCpumHC):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT_CPUM, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
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
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; Clear high dword of the CPUMCPU pointer
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync and rdx, 0ffffffffh
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov rsi, [rdx + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rsi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('@')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Restore Host context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load CPUM pointer into edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, [NAME(pCpumHC) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load the CPUMCPU offset.
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; activate host gdt and idt
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lgdt [rdx + r8 + CPUMCPU.Host.gdtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('0')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lidt [rdx + r8 + CPUMCPU.Host.idtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('1')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%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.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync mov ebx, ecx ; save original value
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, ~0200h ; clear busy flag (2nd type2 bit)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rax + 4], ccx ; not using xchg here is paranoia..
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ltr word [rdx + r8 + CPUMCPU.Host.tr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xchg [rax + 4], ebx ; using xchg is paranoia too...
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; activate ldt
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lldt [rdx + r8 + CPUMCPU.Host.ldtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore segment registers
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.ds]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ds, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.es]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov es, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.fs]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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.
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync mov rbx, rdx ; save edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_IA32_SYSENTER_CS
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync mov eax, [rbx + r8 + CPUMCPU.Host.SysEnter.cs]
4a25fdc1810f28c7813f2fd13ab04ce25b60f30bvboxsync 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
ff308c5c63cf562048295f83638429a925415a10vboxsync jz gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rcx, ~(X86_CR0_TS | X86_CR0_EM)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
ff308c5c63cf562048295f83638429a925415a10vboxsync mov r10, rdx ; Save rdx.
ff308c5c63cf562048295f83638429a925415a10vboxsync
ff308c5c63cf562048295f83638429a925415a10vboxsync mov eax, [r10 + r8 + CPUMCPU.Guest.fXStateMask]
ff308c5c63cf562048295f83638429a925415a10vboxsync mov r9, [r10 + r8 + CPUMCPU.Guest.pXStateR0]
ff308c5c63cf562048295f83638429a925415a10vboxsync or eax, eax
ff308c5c63cf562048295f83638429a925415a10vboxsync jz gth_fpu_guest_fxsave
ff308c5c63cf562048295f83638429a925415a10vboxsync mov edx, [r10 + r8 + CPUMCPU.Guest.fXStateMask + 4]
ff308c5c63cf562048295f83638429a925415a10vboxsync xsave [r9]
ff308c5c63cf562048295f83638429a925415a10vboxsync jmp gth_fpu_host
ff308c5c63cf562048295f83638429a925415a10vboxsyncgth_fpu_guest_fxsave:
ff308c5c63cf562048295f83638429a925415a10vboxsync fxsave [r9]
ff308c5c63cf562048295f83638429a925415a10vboxsync
ff308c5c63cf562048295f83638429a925415a10vboxsyncgth_fpu_host:
ff308c5c63cf562048295f83638429a925415a10vboxsync mov eax, [r10 + r8 + CPUMCPU.Host.fXStateMask]
ff308c5c63cf562048295f83638429a925415a10vboxsync mov r9, [r10 + r8 + CPUMCPU.Host.pXStateR0]
ff308c5c63cf562048295f83638429a925415a10vboxsync or eax, eax
ff308c5c63cf562048295f83638429a925415a10vboxsync jz gth_fpu_host_fxrstor
ff308c5c63cf562048295f83638429a925415a10vboxsync mov edx, [r10 + r8 + CPUMCPU.Host.fXStateMask + 4]
ff308c5c63cf562048295f83638429a925415a10vboxsync xrstor [r9] ; We saved 32-bit state, so only restore 32-bit.
ff308c5c63cf562048295f83638429a925415a10vboxsync jmp gth_fpu_done
ff308c5c63cf562048295f83638429a925415a10vboxsyncgth_fpu_host_fxrstor:
ff308c5c63cf562048295f83638429a925415a10vboxsync fxrstor [r9] ; We saved 32-bit state, so only restore 32-bit.
ff308c5c63cf562048295f83638429a925415a10vboxsync
ff308c5c63cf562048295f83638429a925415a10vboxsyncgth_fpu_done:
ff308c5c63cf562048295f83638429a925415a10vboxsync mov rdx, r10 ; Restore rdx.
ff308c5c63cf562048295f83638429a925415a10vboxsync jmp gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_fpu_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Control registers.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync ; 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]
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync test rcx, X86_CR4_PCIDE
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync jz gth_no_pcide
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync and rax, ~0xfff ; clear the PCID in cr3
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync mov cr3, rax
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync mov cr4, rcx
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync mov cr3, rax ; reload it with the right PCID.
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync jmp gth_restored_cr4
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsyncgth_no_pcide:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rcx
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsyncgth_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.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov cr2, rcx
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
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ; Restore debug registers (if modified). (ESI must still be fUseFlags! Must be done late, at least after CR4!)
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test esi, CPUM_USE_DEBUG_REGS_HOST | CPUM_USED_DEBUG_REGS_HOST | CPUM_USE_DEBUG_REGS_HYPER
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jnz gth_debug_regs_restore
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsyncgth_debug_regs_done:
d08565193a56acd57fd770cf3eb8c3fcbe3af70bvboxsync and dword [rdx + r8 + CPUMCPU.fUseFlags], ~(CPUM_USED_DEBUG_REGS_HOST | CPUM_USED_DEBUG_REGS_HYPER)
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ; 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]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rsi, [rdx + r8 + CPUMCPU.Host.rsi]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbp, [rdx + r8 + CPUMCPU.Host.rbp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov r8, [rdx + r8 + CPUMCPU.Host.r8 ] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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')
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov rax, dr7 ; Some DR7 paranoia first...
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ecx, X86_DR7_INIT_VAL
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync cmp rax, rcx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync je .gth_debug_skip_dr7_disabling
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov dr7, rcx
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync.gth_debug_skip_dr7_disabling:
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test esi, CPUM_USED_DEBUG_REGS_HOST
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jz .gth_debug_regs_dr7
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('r')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync.gth_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
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ; We clear the USED flags in the main code path.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jmp gth_debug_regs_done
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME End
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The description string (in the text section).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(Description):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db SWITCHER_DESCRIPTION
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncextern NAME(Relocate)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;
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)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync at VMMSWITCHERDEF.offR0ToRawMode, dd NAME(vmmR0ToRawMode) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync at VMMSWITCHERDEF.offRCToHost, dd NAME(vmmRCToHost) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync at VMMSWITCHERDEF.offRCCallTrampoline, dd NAME(vmmRCCallTrampoline) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync at VMMSWITCHERDEF.offRCToHostAsm, dd NAME(vmmRCToHostAsm) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync 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)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbIDCode1, dd NAME(HCExitTarget) - NAME(IDExitTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offGCCode, dd NAME(JmpGCTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbGCCode, dd NAME(IDExitTarget) - NAME(JmpGCTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iend
c64777b77514bdc924249d2f9900be25079b0d84vboxsync