AMD64andLegacy.mac revision af0b37c347057e87a85cfbc869b9e68432de1bae
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
c626bd8465f241db74519c3c8dbe59ea620a9e34vboxsync; Copyright (C) 2006-2012 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.
1b68cc0f95e7b0033b20dfc4fdbc260b7a2cef68vboxsync; @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
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, [rdx + CPUM.fApicDisVectors]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov r8, [rdx + CPUM.pvApicBase]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_nolint0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and dword [r8 + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncgth64_nolint0:
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jnc gth64_nolint1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync 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:
9b828870d7acf28326746e3850098e579c590a44vboxsync %ifdef VBOX_WITH_STATISTICS
9b828870d7acf28326746e3850098e579c590a44vboxsync ; Switcher stats.
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync STAM64_PROFILE_ADV_STOP r8
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncENDPROC vmmR0ToRawMode
6cac05f856d982151579a9d445a109960c2c07d2vboxsync%else ; VBOX_WITH_HYBRID_32BIT_KERNEL
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; The C interface.
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncBEGINPROC vmmR0ToRawMode
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %ifdef DEBUG_STUFF
6cac05f856d982151579a9d445a109960c2c07d2vboxsync COM32_S_NEWLINE
6cac05f856d982151579a9d445a109960c2c07d2vboxsync COM32_S_CHAR '^'
6cac05f856d982151579a9d445a109960c2c07d2vboxsync %ifdef VBOX_WITH_STATISTICS
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Switcher stats.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov edx, 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync STAM_PROFILE_ADV_START edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Thunk to/from 64 bit when invoking the worker routine.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.cpum
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov edx, 0ffffffffh
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_32BIT, 1, .vmmR0ToRawModeReturn - NAME(Start)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffffffh
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_64BIT_CS, 1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffh
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync FIXUP FIX_HC_32BIT, 1, NAME(vmmR0ToRawModeAsm) - NAME(Start)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync push 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync.vmmR0ToRawModeReturn:
9b828870d7acf28326746e3850098e579c590a44vboxsync ; This selector reloading is probably not necessary, but we do it anyway to be quite sure
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; the CPU has the right idea about the selectors.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ds
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ds, edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, es
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov es, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, ss
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync Missing implementation!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync %ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Switcher stats.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM_PROFILE_ADV_STOP edx
9b828870d7acf28326746e3850098e579c590a44vboxsyncENDPROC vmmR0ToRawMode
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%endif ;!VBOX_WITH_HYBRID_32BIT_KERNEL
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 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:
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; - current CS and DS selectors are wide open
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; *****************************************************************************
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC vmmR0ToRawModeAsm
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Store the offset from CPUM to CPUMCPU in r8
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
9b828870d7acf28326746e3850098e579c590a44vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r8 ], r8 - scratch
9b828870d7acf28326746e3850098e579c590a44vboxsync ; mov [rdx + r8 + CPUMCPU.Host.r9 ], r9 - scratch
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r10], r10
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r11], r11
9b828870d7acf28326746e3850098e579c590a44vboxsync mov [rdx + r8 + CPUMCPU.Host.r12], r12
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r13], r13
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r14], r14
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.r15], r15
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; selectors.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.ds], ds
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.es], es
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.fs], fs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.gs], gs
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + r8 + CPUMCPU.Host.ss], ss
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov rbx, rdx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_FS_BASE
274fa6f604b8c189c2872bf928f5557680e4a887vboxsync mov [rbx + r8 + CPUMCPU.Host.FSbase], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.FSbase + 4], edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K8_GS_BASE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + r8 + CPUMCPU.Host.GSbase], eax
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync 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]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Block Local APIC NMI vectors
ccd08a3ae2b154ad27cd2bb21a9360bc33aeb552vboxsync mov rbx, [rdx + CPUM.pvApicBase]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or rbx, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz htg_noapic
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xor edi, edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nolint0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x01
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_LINT0], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT0] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_nolint0:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nolint1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x02
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_LINT1], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_LINT1] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_nolint1:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_PC]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_nopc
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x04
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_PC], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_PC] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_VERSION]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync shr eax, 16
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jb htg_notherm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_THMR]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, (APIC_REG_LVT_MASKED | APIC_REG_LVT_MODE_MASK)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync cmp ecx, APIC_REG_LVT_MODE_NMI
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jne htg_notherm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or edi, 0x08
c64777b77514bdc924249d2f9900be25079b0d84vboxsync or eax, APIC_REG_LVT_MASKED
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rbx + APIC_REG_LVT_THMR], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + APIC_REG_LVT_THMR] ; write completion
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_notherm:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov [rdx + CPUM.fApicDisVectors], edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%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.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; save MSR_IA32_SYSENTER_CS register.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rbx, rdx ; save edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ecx, MSR_IA32_SYSENTER_CS
6cac05f856d982151579a9d445a109960c2c07d2vboxsync rdmsr ; edx:eax <- MSR[ecx]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs], eax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4], edx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor eax, eax ; load 0:0 to cause #GP upon sysenter
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor edx, edx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rdx, rbx ; restore edx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jmp short htg_no_sysenter
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsyncALIGNCODE(16)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_no_sysenter:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;; handle use flags.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and esi, ~CPUM_USED_FPU ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.fUseFlags], esi
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; debug registers.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jz htg_debug_regs_no
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync jmp htg_debug_regs_save
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsynchtg_debug_regs_no:
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync DEBUG_CHAR('a') ; trashes esi
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; control registers.
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr0
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr0], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;mov rax, cr2 ; assume host os don't stuff things in cr2. (safe)
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;mov [rdx + r8 + CPUMCPU.Host.cr2], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr3
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr3], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov rax, cr4
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov [rdx + r8 + CPUMCPU.Host.cr4], rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ;; Start switching to VMM context.
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Change CR0 and CR4 so we can correctly emulate FPU/MMX/SSE[23] exceptions
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Also disable WP. (eax==cr4 now)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; Note! X86_CR4_PSE and X86_CR4_PAE are important if the host thinks so :-)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync and rax, X86_CR4_MCE | X86_CR4_PSE | X86_CR4_PAE
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov ecx, [rdx + r8 + CPUMCPU.Guest.cr4]
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync DEBUG_CHAR('b') ; trashes esi
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ;; @todo Switcher cleanup: Determine base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; in CPUMCPU.Hyper.cr4 (which isn't currently being used). That should
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; simplify this operation a bit (and improve locality of the data).
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; CR4.AndMask and CR4.OrMask are set in CPUMR3Init based on the presence of
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync ; FXSAVE support on the host CPU
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ecx, [rdx + CPUM.CR4.AndMask]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, ecx
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync or eax, [rdx + CPUM.CR4.OrMask]
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync mov cr4, rax
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync DEBUG_CHAR('c') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov eax, [rdx + r8 + CPUMCPU.Guest.cr0]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync and eax, X86_CR0_EM
6cac05f856d982151579a9d445a109960c2c07d2vboxsync or eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov cr0, rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('0') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Load new gdt so we can do far jump to guest code after cr3 reload.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync lgdt [rdx + r8 + CPUMCPU.Hyper.gdtr]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('1') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; Store the hypervisor cr3 for later loading
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov ebp, [rdx + r8 + CPUMCPU.Hyper.cr3]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;; Load Intermediate memory context.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_INTER_AMD64_CR3, 1
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov eax, 0ffffffffh
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov cr3, rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('2') ; trashes esi
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ;; 1. Switch to compatibility mode, placing ourselves in identity mapped code.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp far [NAME(fpIDEnterTarget) wrt rip]
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; 16:32 Pointer to IDEnterTarget.
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncNAME(fpIDEnterTarget):
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_ID_32BIT, 0, NAME(IDEnterTarget) - NAME(Start)
6cac05f856d982151579a9d445a109960c2c07d2vboxsync FIXUP FIX_HYPER_CS, 0
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; Detour for saving the host DR7 and DR6.
6cac05f856d982151579a9d445a109960c2c07d2vboxsync; esi and rdx must be preserved.
6cac05f856d982151579a9d445a109960c2c07d2vboxsynchtg_debug_regs_save:
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncDEBUG_S_CHAR('s');
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rax, dr7 ; not sure, but if I read the docs right this will trap if GD is set. FIXME!!!
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr7], rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync xor eax, eax ; clear everything. (bit 12? is read as 1...)
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov dr7, rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rax, dr6 ; just in case we save the state register too.
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr6], rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync ; save host DR0-3?
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync test esi, CPUM_USE_DEBUG_REGS
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync jz near htg_debug_regs_no
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsyncDEBUG_S_CHAR('S');
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rax, dr0
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr0], rax
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov rbx, dr1
6ba6cd69eba9efb4a3838ccf50235e68e8458f1avboxsync mov [rdx + r8 + CPUMCPU.Host.dr1], rbx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rcx, dr2
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr2], rcx
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov rax, dr3
6cac05f856d982151579a9d445a109960c2c07d2vboxsync mov [rdx + r8 + CPUMCPU.Host.dr3], rax
6cac05f856d982151579a9d445a109960c2c07d2vboxsync jmp htg_debug_regs_no
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; We're now on identity mapped pages in 32-bit compatibility mode.
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncALIGNCODE(16)
6cac05f856d982151579a9d445a109960c2c07d2vboxsyncGLOBALNAME IDEnterTarget
6cac05f856d982151579a9d445a109960c2c07d2vboxsync DEBUG_CHAR('3')
6cac05f856d982151579a9d445a109960c2c07d2vboxsync ; 2. Deactivate long mode by turning off paging.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ebx, cr0
4ad0e04fb2a93fb4980de2644f7ccca9e8869083vboxsync and ebx, ~X86_CR0_PG
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('4')
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync ; 3. Load intermediate page table.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov edx, 0ffffffffh
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync mov cr3, edx
3809172d0a0ce1c648e7a1f8dc94e1570266b5abvboxsync ; 4. Disable long mode.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We also use the chance to disable syscall/sysret and fast fxsave/fxrstor.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_K6_EFER
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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;mov eax, 0ffff0000h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;.delay_loop:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync;jnz .delay_loop
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3 and do far jump to load cs.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, ebp ; ebp set above
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('0')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate guest IDT
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync ; Setup the stack.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('3')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ax, [edx + CPUMCPU.Hyper.ss.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esp, [edx + CPUMCPU.Hyper.esp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('4')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_TSS_GDTE_DW2, 2
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and dword [0ffffffffh], ~0200h ; clear busy flag (2nd type2 bit)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('5')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ltr word [edx + CPUMCPU.Hyper.tr.Sel]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('6')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Activate the ldt (now we can safely crash).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('7')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; Use flags.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov esi, [edx + CPUMCPU.fUseFlags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; debug registers
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jnz htg_debug_regs_guest
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_guest_done:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('9')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; General registers (sans edx).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.eax]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ebx, [edx + CPUMCPU.Hyper.ebx]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ecx, [edx + CPUMCPU.Hyper.ecx]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov ebp, [edx + CPUMCPU.Hyper.ebp]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov esi, [edx + CPUMCPU.Hyper.esi]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov edi, [edx + CPUMCPU.Hyper.edi]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('!')
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ;; Return to the VMM code which either called the switcher or
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync ;; the code set up to run by HC.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push dword [edx + CPUMCPU.Hyper.eflags]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync push dword [edx + CPUMCPU.Hyper.eip]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [edx + CPUMCPU.Hyper.edx] ; !! edx is no longer pointing to CPUMCPU here !!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eip='
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync iret ; Use iret to make debugging and TF/RF work.
ee2aeb0cd5535f38ee098713a9cebb74dc1c2e30vboxsync; Detour for saving host DR0-3 and loading hypervisor debug registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; esi and edx must be preserved.
c64777b77514bdc924249d2f9900be25079b0d84vboxsynchtg_debug_regs_guest:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('D')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('R')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('x')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load hyper DR0-7
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, [edx + CPUMCPU.Hyper.dr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr0, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, [edx + CPUMCPU.Hyper.dr + 8*1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr1, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*2]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr2, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, [edx + CPUMCPU.Hyper.dr + 8*3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr3, ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov eax, [edx + CPUMCPU.Hyper.dr + 8*6]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, 0ffff0ff0h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr6, ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [edx + CPUMCPU.Hyper.dr + 8*7]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp htg_debug_regs_guest_done
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncENDPROC 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)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC 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
4a296be15f381ac7f3506e4eb2861627d062fee3vboxsync pop edi ; argument count.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_PRINT ';eax='
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_DWORD_REG eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR ';'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync call eax ; do call
c64777b77514bdc924249d2f9900be25079b0d84vboxsync add esp, edi ; cleanup stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; return to the host context (eax = C returncode).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM32_S_CHAR '`'
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.to_host_again:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync call NAME(vmmRCToHostAsm)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, VERR_VMM_SWITCHER_IPE_1
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp .to_host_again
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncENDPROC vmmRCCallTrampoline
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; The C interface.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsyncBEGINPROC vmmRCToHost
c8968199d271abe749c08bcea0512f7239250cdcvboxsync%ifdef DEBUG_STUFF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync COM_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('b')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('a')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('c')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('k')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('!')
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync COM_NEWLINE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [esp + 4]
37fb67be7d1d328213aeda3f56ab5aacd37416d1vboxsync jmp NAME(vmmRCToHostAsm)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncENDPROC vmmRCToHost
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; vmmRCToHostAsmNoReturn
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync; This is an entry point used by TRPM when dealing with raw-mode traps,
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; i.e. traps in the hypervisor code. This will not return and saves no
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; state, because the caller has already saved the state.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param eax Return code.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsyncBEGINPROC vmmRCToHostAsmNoReturn
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_S_CHAR('%')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%ifdef VBOX_WITH_STATISTICS
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync mov edx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync STAM32_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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
af0b37c347057e87a85cfbc869b9e68432de1baevboxsync; host context so desires.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @param eax Return code.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; @uses eax, edx, ecx (or it may use them in the future)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncALIGNCODE(16)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncBEGINPROC vmmRCToHostAsm
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('%')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%ifdef VBOX_WITH_STATISTICS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_STOP edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync STAM32_PROFILE_ADV_START edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Load the CPUM pointer.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_GC_CPUMCPU_OFF, 1, 0
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Save register context.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop dword [edx + CPUMCPU.Hyper.edx]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync pop dword [edx + CPUMCPU.Hyper.eip] ; call return from stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.esp], esp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.eax], eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ebx], ebx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ecx], ecx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.esi], esi
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov dword [edx + CPUMCPU.Hyper.edi], edi
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dword [edx + CPUMCPU.Hyper.ebp], ebp
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; special registers which may change.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncvmmRCToHostAsm_SaveNoGeneralRegs:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync%ifdef STRICT_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test ecx, X86_EFL_IF
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz .if_clear_out
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, 0c0ffee01h
c64777b77514bdc924249d2f9900be25079b0d84vboxsync.if_clear_out:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; FPU context is saved before restore of host saving (another) branch.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ;; Load Intermediate memory context.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edi, eax ; save return code in EDI (careful with COM_DWORD_REG from here on!)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov eax, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('?')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;; 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
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('2')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 2. Enable PAE.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync%ifdef SWITCHER_TO_PAE
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; - already enabled
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, cr4
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or ecx, X86_CR4_PAE
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr4, ecx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 3. Load long mode intermediate CR3.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_INTER_AMD64_CR3, 1
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, 0ffffffffh
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr3, ecx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('3')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 4. Enable long mode.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ebp, edx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov ecx, MSR_K6_EFER
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or eax, MSR_K6_EFER_LME
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov edx, ebp
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('4')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; 5. Enable paging.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync or ebx, X86_CR0_PG
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov cr0, ebx
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('5')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Jump from compatibility mode to 64-bit mode.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync FIXUP FIX_ID_FAR32_TO_64BIT_MODE, 1, NAME(IDExit64Mode) - NAME(Start)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp 0ffffh:0fffffffeh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; We're in 64-bit mode (ds, ss, es, fs, gs are all bogus).
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Move on to the HC mapping.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncALIGNCODE(16)
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncNAME(IDExit64Mode):
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync DEBUG_CHAR('6')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync jmp [NAME(pHCExitTarget) wrt rip]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync; 64-bit jump target
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncNAME(pHCExitTarget):
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncFIXUP FIX_HC_64BIT, 0, NAME(HCExitTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncdq 0ffffffffffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync; 64-bit pCpum address.
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncNAME(pCpumHC):
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncFIXUP FIX_HC_64BIT_CPUM, 0
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsyncdq 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')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Clear high dword of the CPUMCPU pointer
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rdx, 0ffffffffh
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; load final cr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync 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]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; Load the CPUMCPU offset.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync ; activate host gdt and idt
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync lgdt [rdx + r8 + CPUMCPU.Host.gdtr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync DEBUG_CHAR('0')
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync lidt [rdx + r8 + CPUMCPU.Host.idtr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync DEBUG_CHAR('1')
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; Restore TSS selector; must mark it as not busy before using ltr (!)
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync%if 1 ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and al, 0F8h ; mask away TI and RPL bits, get descriptor offset.
3942acfaf590eaef4740d7b8a5311bb91e2bed0dvboxsync add rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2] ; eax <- GDTR.address + descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and dword [rax + 4], ~0200h ; clear busy flag (2nd type2 bit)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ltr word [rdx + r8 + CPUMCPU.Host.tr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and al, 0F8h ; mask away TI and RPL bits, get descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync add rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2] ; eax <- GDTR.address + descriptor offset.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, [rax + 4] ; ecx <- 2nd descriptor dword
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ebx, ecx ; save original value
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and ecx, ~0200h ; clear busy flag (2nd type2 bit)
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync mov [rax + 4], ccx ; not using xchg here is paranoia..
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync ltr word [rdx + r8 + CPUMCPU.Host.tr]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync xchg [rax + 4], ebx ; using xchg is paranoia too...
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; activate ldt
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_CHAR('2')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync lldt [rdx + r8 + CPUMCPU.Host.ldtr]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Restore segment registers
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.ds]
4a1a50ee161eb0a0f907d9d1585581f3bb43bed2vboxsync mov ds, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.es]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov es, eax
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.fs]
c1980cd3f410c88b8f92f464c56ed987a15f44c1vboxsync mov fs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.gs]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov gs, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore stack
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rdx + r8 + CPUMCPU.Host.ss]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ss, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync FIXUP FIX_NO_SYSENTER_JMP, 0, gth_sysenter_no - NAME(Start) ; this will insert a jmp gth_sysenter_no if host doesn't use sysenter.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore MSR_IA32_SYSENTER_CS register.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, rdx ; save edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov ecx, MSR_IA32_SYSENTER_CS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, [rbx + r8 + CPUMCPU.Host.SysEnter.cs]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov edx, [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync wrmsr ; MSR[ecx] <- edx:eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdx, rbx ; restore edx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp short gth_sysenter_no
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.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; Would've liked to have these higher up in case of crashes, but
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; the fpu stuff must be done before we restore cr0.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.cr4]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test rcx, X86_CR4_PCIDE
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz gth_no_pcide
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync and rax, ~0xfff ; clear the PCID in cr3
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.cr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr3, rax ; reload it with the right PCID.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_restored_cr4
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_no_pcide:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr4, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_restored_cr4:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.cr0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov cr0, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ;mov rcx, [rdx + r8 + CPUMCPU.Host.cr2] ; assumes this is waste of time.
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync ;mov cr2, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore debug registers (if modified) (esi must still be fUseFlags!)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; (must be done after cr4 reload because of the debug extension.)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS | CPUM_USE_DEBUG_REGS_HOST
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_debug_regs_restore
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_debug_regs_no:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; restore general registers.
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov eax, edi ; restore return code. eax = return code !!
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rax, [rdx + r8 + CPUMCPU.Host.rax] - scratch + return code
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.rbx]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rcx, [rdx + r8 + CPUMCPU.Host.rcx] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov rdx, [rdx + r8 + CPUMCPU.Host.rdx] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rdi, [rdx + r8 + CPUMCPU.Host.rdi]
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync mov rsi, [rdx + r8 + CPUMCPU.Host.rsi]
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
e07a7480bb140d8cebbb6599980c7da0a12a6c4avboxsync mov rbp, [rdx + r8 + CPUMCPU.Host.rbp]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; mov r8, [rdx + r8 + CPUMCPU.Host.r8 ] - scratch
42c1972c22e09797b4b24afbd0ec114ed076c37cvboxsync ; mov r9, [rdx + r8 + CPUMCPU.Host.r9 ] - scratch
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r10, [rdx + r8 + CPUMCPU.Host.r10]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r11, [rdx + r8 + CPUMCPU.Host.r11]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r12, [rdx + r8 + CPUMCPU.Host.r12]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r13, [rdx + r8 + CPUMCPU.Host.r13]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r14, [rdx + r8 + CPUMCPU.Host.r14]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov r15, [rdx + r8 + CPUMCPU.Host.r15]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; 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')
c64777b77514bdc924249d2f9900be25079b0d84vboxsync xor eax, eax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, rax ; paranoia or not?
c64777b77514bdc924249d2f9900be25079b0d84vboxsync test esi, CPUM_USE_DEBUG_REGS
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jz short gth_debug_regs_dr7
c64777b77514bdc924249d2f9900be25079b0d84vboxsync DEBUG_S_CHAR('r')
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync mov rax, [rdx + r8 + CPUMCPU.Host.dr0]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr0, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.dr1]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr1, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.dr2]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr2, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rax, [rdx + r8 + CPUMCPU.Host.dr3]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr3, rax
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncgth_debug_regs_dr7:
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rbx, [rdx + r8 + CPUMCPU.Host.dr6]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr6, rbx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov rcx, [rdx + r8 + CPUMCPU.Host.dr7]
c64777b77514bdc924249d2f9900be25079b0d84vboxsync mov dr7, rcx
c64777b77514bdc924249d2f9900be25079b0d84vboxsync jmp gth_debug_regs_no
c64777b77514bdc924249d2f9900be25079b0d84vboxsyncENDPROC 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)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offR0ToRawMode, dd NAME(vmmR0ToRawMode) - NAME(Start)
c931fade4656c734f88a44f9237c897cdd0ebdeevboxsync at VMMSWITCHERDEF.offRCToHost, dd NAME(vmmRCToHost) - NAME(Start)
23795b52925e0506e39a546334af089b8f93c50avboxsync at VMMSWITCHERDEF.offRCCallTrampoline, dd NAME(vmmRCCallTrampoline) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offRCToHostAsm, dd NAME(vmmRCToHostAsm) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offRCToHostAsmNoReturn, dd NAME(vmmRCToHostAsmNoReturn) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync ; disasm help
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbHCCode0, dd NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offHCCode1, dd NAME(HCExitTarget) - NAME(Start)
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync at VMMSWITCHERDEF.cbHCCode1, dd NAME(End) - NAME(HCExitTarget)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.offIDCode0, dd NAME(IDEnterTarget) - NAME(Start)
c64777b77514bdc924249d2f9900be25079b0d84vboxsync at VMMSWITCHERDEF.cbIDCode0, dd NAME(JmpGCTarget) - NAME(IDEnterTarget)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.cbIDCode1, dd NAME(HCExitTarget) - NAME(IDExitTarget)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.offGCCode, dd NAME(JmpGCTarget) - NAME(Start)
4a64ab8cc32b5b6d329a51b36b23fa50c6ada410vboxsync at VMMSWITCHERDEF.cbGCCode, dd NAME(IDExitTarget) - NAME(JmpGCTarget)