AMD64andLegacy.mac revision c1980cd3f410c88b8f92f464c56ed987a15f44c1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync; Copyright (C) 2006-2013 Oracle Corporation
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;%define DEBUG_STUFF 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;%define STRICT_IF 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;*******************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;* Header Files *
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'.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME Fixups
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME Start
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param pVM GCC: rdi MSC:rcx The VM handle.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_CHAR '^'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; The ordinary version of the code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef STRICT_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test eax, X86_EFL_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz .if_clear_in
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0c0ffee00h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.if_clear_in:
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 mov r9, rdi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lea rdx, [r9 + VM.cpum]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM64_PROFILE_ADV_START r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Call worker (far return).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, cs
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync call NAME(vmmR0ToRawModeAsm)
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
9b828870d7acf28326746e3850098e579c590a44vboxsync mov ecx, [rdx + CPUM.fApicDisVectors]
9b828870d7acf28326746e3850098e579c590a44vboxsync mov r8, [rdx + CPUM.pvApicBase]
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nolint0
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_nolint0:
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nolint1
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_nolint1:
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_nopc
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsync jnc gth64_notherm
9b828870d7acf28326746e3850098e579c590a44vboxsync and dword [r8 + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
9b828870d7acf28326746e3850098e579c590a44vboxsyncgth64_notherm:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM64_PROFILE_ADV_STOP r8
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmR0ToRawMode
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%else ; VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawMode
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '^'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Thunk to/from 64 bit when invoking the worker routine.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.cpum
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_HC_32BIT, 1, .vmmR0ToRawModeReturn - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_64BIT_CS, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_HC_32BIT, 1, NAME(vmmR0ToRawModeAsm) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync.vmmR0ToRawModeReturn:
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 mov edx, ds
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ds, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, es
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov es, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ss
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, edx
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
9b828870d7acf28326746e3850098e579c590a44vboxsync Missing implementation!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM_PROFILE_ADV_STOP edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmR0ToRawMode
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync%endif ;!VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Phase one of the switch from host to guest context (host MMU context)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - edx virtual address of CPUM structure (valid in host context)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - eax, ecx, edx, r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; ASSUMPTION:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; - current CS and DS selectors are wide open
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Store the offset from CPUM to CPUMCPU in r8
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Save CPU host context
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Skip eax, edx and ecx as these are not preserved over calls.
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 mov rbx, rdx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_FS_BASE
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 mov [rbx + r8 + CPUMCPU.Host.GSbase], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.GSbase + 4], edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
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 pop qword [rdx + r8 + CPUMCPU.Host.rflags]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; Block Local APIC NMI vectors
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rbx, [rdx + CPUM.pvApicBase]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or rbx, rbx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jz htg_noapic
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync xor edi, edi
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
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0] ; write completion
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
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1] ; write completion
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
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_PC] ; write completion
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_VERSION]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync shr eax, 16
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jb htg_notherm
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
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov eax, [rbx + APIC_REG_LVT_THMR] ; write completion
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_notherm:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + CPUM.fApicDisVectors], edi
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%endif ; VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
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 mov rdx, rbx ; restore edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short htg_no_sysenter
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_no_sysenter:
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 ; 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 ; 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 ;; Start switching to VMM context.
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 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 ; CR4.AndMask and CR4.OrMask are set in CPUMR3Init based on the presence of
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; FXSAVE support on the host CPU
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 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 ; 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
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync ; Store the hypervisor cr3 for later loading
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov ebp, [rdx + r8 + CPUMCPU.Hyper.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Load Intermediate memory context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_INTER_AMD64_CR3, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2') ; trashes esi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 1. Switch to compatibility mode, placing ourselves in identity mapped code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp far [NAME(fpIDEnterTarget) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 16:32 Pointer to IDEnterTarget.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(fpIDEnterTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_ID_32BIT, 0, NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HYPER_CS, 0
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
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; We're now on identity mapped pages in 32-bit compatibility mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME IDEnterTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
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')
ee2aeb0cd5535f38ee098713a9cebb74dc1c2e30vboxsync ; 3. Load intermediate page table.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, edx
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 DEBUG_CHAR('5')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and eax, ~(MSR_K6_EFER_LME | MSR_K6_EFER_SCE | MSR_K6_EFER_FFXSR)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifndef SWITCHER_TO_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 4b. Disable PAE.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and eax, ~X86_CR4_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, eax
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 ;; 6. Jump to guest code mapping of the code and load the Hypervisor CS.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_ID_2_GC_NEAR_REL, 1, NAME(JmpGCTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp near NAME(JmpGCTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; When we arrive at this label we're at the
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; guest code mapping of the switching code.
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 ;; We're in VMM MMU context and VMM CS is loaded.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Setup the rest of the VMM state.
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')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Setup the stack.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync mov ax, [edx + CPUMCPU.Hyper.ss.Sel]
c8968199d271abe749c08bcea0512f7239250cdcvboxsync mov esp, [edx + CPUMCPU.Hyper.esp]
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 ; Activate the ldt (now we can safely crash).
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('7')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Use flags.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov esi, [edx + CPUMCPU.fUseFlags]
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')
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 ;; Return to the VMM code which either called the switcher or
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; the code set up to run by HC.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync push dword [edx + CPUMCPU.Hyper.eflags]
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync push dword [edx + CPUMCPU.Hyper.eip]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, [edx + CPUMCPU.Hyper.edx] ; !! edx is no longer pointing to CPUMCPU here !!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eip='
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, [esp + 8]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_DWORD_REG eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR ';'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToGC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_STOP eax
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync iret ; Use iret to make debugging and TF/RF work.
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
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmR0ToRawModeAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; Trampoline for doing a call when starting the hyper visor execution.
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.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR 'c'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR 't'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '!'
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 call eax ; do call
c64777b77514bdc924249d2f9900be25079b0d84vboxsync add esp, edi ; cleanup stack
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; return to the host context (eax = C returncode).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '`'
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync.to_host_again:
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync call NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, VERR_VMM_SWITCHER_IPE_1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp .to_host_again
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHost
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
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 mov eax, [esp + 4]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHost
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmRCToHostAsmNoReturn
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; @param eax Return code.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
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 FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp vmmRCToHostAsm_SaveNoGeneralRegs
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; vmmRCToHostAsm
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.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; The hypervisor context is saved and it will return to the caller if
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; host context so desires.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param eax Return code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @uses eax, edx, ecx (or it may use them in the future)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncBEGINPROC vmmRCToHostAsm
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
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 FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Load the CPUM pointer.
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
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 ; special registers which may change.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncvmmRCToHostAsm_SaveNoGeneralRegs:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef STRICT_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test ecx, X86_EFL_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz .if_clear_out
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0c0ffee01h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.if_clear_out:
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; str [edx + CPUMCPU.Hyper.tr] - double fault only, and it won't be right then either.
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.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ; Disable debug registers if active so they cannot trigger while switching.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync test dword [edi + 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 ;; Load Intermediate memory context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('?')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; We're now in intermediate memory context!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 0. Jump to identity mapped location
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_2_ID_NEAR_REL, 1, NAME(IDExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp near NAME(IDExitTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We're now on identity mapped pages!
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME IDExitTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('1')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 1. Disable paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ebx, ~X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 2. Enable PAE.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef SWITCHER_TO_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; - already enabled
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or ecx, X86_CR4_PAE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, ecx
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 ; 4. Enable long mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebp, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, MSR_K6_EFER_LME
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ebp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 5. Enable paging.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or ebx, X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('5')
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 ; We're in 64-bit mode (ds, ss, es, fs, gs are all bogus).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Move on to the HC mapping.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(IDExit64Mode):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp [NAME(pHCExitTarget) wrt rip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit jump target
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pHCExitTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT, 0, NAME(HCExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit pCpum address.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pCpumHC):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT_CPUM, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; When we arrive here we're at the host context
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mapping of the switcher code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME HCExitTarget
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('9')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; Clear high dword of the CPUMCPU pointer
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync and rdx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov rsi, [rdx + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rsi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('@')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Restore Host context.
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 ; 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 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 ; 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 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_sysenter_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; @todo AMD syscall
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore FPU if guest has used it.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USED_FPU
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, cr0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rcx, ~(X86_CR0_TS | X86_CR0_EM)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync fxsave [rdx + r8 + CPUMCPU.Guest.fpu]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync fxrstor [rdx + r8 + CPUMCPU.Host.fpu]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short gth_fpu_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
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 ; 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 mov ecx, MSR_K8_GS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.GSbase]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.GSbase + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.efer]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.efer + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx
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:
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync and dword [edx + CPUMCPU.fUseFlags], ~(CPUM_USED_DEBUG_REGS_HOST | CPUM_USED_DEBUG_REGS_HYPER)
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 ; finally restore flags. (probably not required)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push qword [rdx + r8 + CPUMCPU.Host.rflags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM64_S_CHAR '4'
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
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 ; We clear the USED flags in the main code path.
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync jmp gth_debug_regs_done
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME End
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The description string (in the text section).
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(Description):
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db SWITCHER_DESCRIPTION
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncextern NAME(Relocate)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; End the fixup records.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync db FIX_THE_END ; final entry.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncGLOBALNAME FixupsEnd
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.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)