AMD64andLegacy.mac revision 43747b1f0bc8302a238fb35e55857a5e9aa1933d
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync; VMM - World Switchers, template for AMD64 to PAE and 32-bit.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; Copyright (C) 2006-2007 Oracle Corporation
d63de4508a08b11f57c307a15eda3cd95485bf2cvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
d63de4508a08b11f57c307a15eda3cd95485bf2cvboxsync; available from http://www.virtualbox.org. This file is free software;
d63de4508a08b11f57c307a15eda3cd95485bf2cvboxsync; you can redistribute it and/or modify it under the terms of the GNU
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; General Public License (GPL) as published by the Free Software
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync;%define DEBUG_STUFF 1
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync;%define STRICT_IF 1
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync;*******************************************************************************
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync;* Header Files *
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync;*******************************************************************************
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; Start the fixup records
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; We collect the fixups in the .data section as we go along
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; It is therefore VITAL that no-one is using the .data section
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; for anything else between 'Start' and 'End'.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncGLOBALNAME Fixups
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncGLOBALNAME Start
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
cb172d105a87f41489b1553fbd99ec97932609ffvboxsync; The C interface.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync; @param pVM GCC: rdi MSC:rcx The VM handle.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncBEGINPROC vmmR0HostToGuest
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync%ifdef DEBUG_STUFF
2c691730ab202620fe427110841aa4e0075b7ccavboxsync COM64_S_NEWLINE
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync COM64_S_CHAR '^'
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; The ordinary version of the code.
b1212d1cdc6c9396aa851ef0a5388edce69806advboxsync %ifdef STRICT_IF
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync test eax, X86_EFL_IF
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync jz .if_clear_in
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync mov eax, 0c0ffee00h
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync.if_clear_in:
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; make r9 = pVM and rdx = pCpum.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; rax, rcx and r8 are scratch here after.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync %ifdef RT_OS_WINDOWS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov r9, rcx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov r9, rdi
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync lea rdx, [r9 + VM.cpum]
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync %ifdef VBOX_WITH_STATISTICS
08879243dd70cdd8c01c3a5941c82c96c45a7e32vboxsync ; Switcher stats.
0a987c833e0517dc4efefc14229d96dec62e0965vboxsync STAM64_PROFILE_ADV_START r8
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; Call worker (far return).
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov eax, cs
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync call NAME(vmmR0HostToGuestAsm)
4c07a936250bec9628653237718068d59914cdcevboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
4c07a936250bec9628653237718068d59914cdcevboxsync ; Unblock Local APIC NMI vectors
4c07a936250bec9628653237718068d59914cdcevboxsync ; Do this here to ensure the host CS is already restored
4c07a936250bec9628653237718068d59914cdcevboxsync mov ecx, [rdx + CPUM.fApicDisVectors]
4c07a936250bec9628653237718068d59914cdcevboxsync mov r8, [rdx + CPUM.pvApicBase]
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync jnc gth64_nolint0
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync and dword [r8 + APIC_REG_LVT_LINT0], ~APIC_REG_LVT_MASKED
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsyncgth64_nolint0:
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync jnc gth64_nolint1
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync and dword [r8 + APIC_REG_LVT_LINT1], ~APIC_REG_LVT_MASKED
8632da57318dd02e08198ceb832c636dc7da6a30vboxsyncgth64_nolint1:
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync jnc gth64_nopc
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync and dword [r8 + APIC_REG_LVT_PC], ~APIC_REG_LVT_MASKED
e361162aaa3f264085c651f9ea83f70d0ff3e431vboxsync jnc gth64_notherm
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync and dword [r8 + APIC_REG_LVT_THMR], ~APIC_REG_LVT_MASKED
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncgth64_notherm:
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync %ifdef VBOX_WITH_STATISTICS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; Switcher stats.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync STAM64_PROFILE_ADV_STOP r8
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncENDPROC vmmR0HostToGuest
0700964a23df46033c8149ee10ce643cd3677061vboxsync%else ; VBOX_WITH_HYBRID_32BIT_KERNEL
0700964a23df46033c8149ee10ce643cd3677061vboxsync; The C interface.
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsyncBEGINPROC vmmR0HostToGuest
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync %ifdef DEBUG_STUFF
0bd6dc6980372bcbc72756dfd401df65640b13a7vboxsync COM32_S_NEWLINE
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync COM32_S_CHAR '^'
0bd6dc6980372bcbc72756dfd401df65640b13a7vboxsync %ifdef VBOX_WITH_STATISTICS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; Switcher stats.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
c215a948010614887014a258c1751602d8bf7781vboxsync mov edx, 0ffffffffh
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync STAM_PROFILE_ADV_START edx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; Thunk to/from 64 bit when invoking the worker routine.
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync FIXUP FIX_HC_VM_OFF, 1, VM.cpum
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov edx, 0ffffffffh
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FIXUP FIX_HC_32BIT, 1, .vmmR0HostToGuestReturn - NAME(Start)
08879243dd70cdd8c01c3a5941c82c96c45a7e32vboxsync push 0ffffffffh
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FIXUP FIX_HC_64BIT_CS, 1
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync push 0ffffh
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync FIXUP FIX_HC_32BIT, 1, NAME(vmmR0HostToGuestAsm) - NAME(Start)
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync push 0ffffffffh
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync.vmmR0HostToGuestReturn:
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; This selector reloading is probably not necessary, but we do it anyway to be quite sure
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; the CPU has the right idea about the selectors.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov edx, ds
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov ds, edx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov ecx, es
b1212d1cdc6c9396aa851ef0a5388edce69806advboxsync mov es, ecx
b1212d1cdc6c9396aa851ef0a5388edce69806advboxsync mov edx, ss
e361162aaa3f264085c651f9ea83f70d0ff3e431vboxsync mov ss, edx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync %ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync Missing implementation!
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync %ifdef VBOX_WITH_STATISTICS
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; Switcher stats.
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov edx, 0ffffffffh
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync STAM_PROFILE_ADV_STOP edx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncENDPROC vmmR0HostToGuest
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync%endif ;!VBOX_WITH_HYBRID_32BIT_KERNEL
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; *****************************************************************************
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; vmmR0HostToGuestAsm
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; Phase one of the switch from host to guest context (host MMU context)
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; - edx virtual address of CPUM structure (valid in host context)
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; - eax, ecx, edx, r8
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; ASSUMPTION:
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; - current CS and DS selectors are wide open
f1517b3016a7e68a8edb55ea82c704af7386c9advboxsync; *****************************************************************************
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsyncALIGNCODE(16)
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsyncBEGINPROC vmmR0HostToGuestAsm
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync ;; Store the offset from CPUM to CPUMCPU in r8
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync mov r8d, [rdx + CPUM.offCPUMCPU0]
4bc1bbf45f30ff3ca38c2ad006836e490972c7ccvboxsync ;; Save CPU host context
fe7115bba580b609cb1a233f8e08947d0ee0af8dvboxsync ;; Skip eax, edx and ecx as these are not preserved over calls.
fe7115bba580b609cb1a233f8e08947d0ee0af8dvboxsync ; general registers.
282d5da26651aba526a6818d63bcbef8add97f3avboxsync ; mov [rdx + r8 + CPUMCPU.Host.rax], rax - scratch
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.rbx], rbx
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; mov [rdx + r8 + CPUMCPU.Host.rcx], rcx - scratch
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; mov [rdx + r8 + CPUMCPU.Host.rdx], rdx - scratch
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.rdi], rdi
cb172d105a87f41489b1553fbd99ec97932609ffvboxsync mov [rdx + r8 + CPUMCPU.Host.rsi], rsi
2c691730ab202620fe427110841aa4e0075b7ccavboxsync mov [rdx + r8 + CPUMCPU.Host.rsp], rsp
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.rbp], rbp
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; mov [rdx + r8 + CPUMCPU.Host.r8 ], r8 - scratch
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync ; mov [rdx + r8 + CPUMCPU.Host.r9 ], r9 - scratch
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.r10], r10
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.r11], r11
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.r12], r12
5f9dfb422a6ed57822f9c0cb94fa7df8d24acc9bvboxsync mov [rdx + r8 + CPUMCPU.Host.r13], r13
mov [rdx + r8 + CPUMCPU.Host.r14], r14
mov [rdx + r8 + CPUMCPU.Host.r15], r15
mov [rdx + r8 + CPUMCPU.Host.ds], ds
mov [rdx + r8 + CPUMCPU.Host.es], es
mov [rdx + r8 + CPUMCPU.Host.fs], fs
mov [rdx + r8 + CPUMCPU.Host.gs], gs
mov [rdx + r8 + CPUMCPU.Host.ss], ss
mov [rbx + r8 + CPUMCPU.Host.FSbase], eax
mov [rbx + r8 + CPUMCPU.Host.FSbase + 4], edx
mov [rbx + r8 + CPUMCPU.Host.GSbase], eax
mov [rbx + r8 + CPUMCPU.Host.GSbase + 4], edx
mov [rbx + r8 + CPUMCPU.Host.efer], eax
mov [rbx + r8 + CPUMCPU.Host.efer + 4], edx
sldt [rdx + r8 + CPUMCPU.Host.ldtr]
sidt [rdx + r8 + CPUMCPU.Host.idtr]
sgdt [rdx + r8 + CPUMCPU.Host.gdtr]
str [rdx + r8 + CPUMCPU.Host.tr] ; yasm BUG, generates sldt. YASMCHECK!
pop qword [rdx + r8 + CPUMCPU.Host.rflags]
mov rbx, [rdx + CPUM.pvApicBase]
mov [rdx + CPUM.fApicDisVectors], edi
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.
mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs], eax
mov [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4], edx
mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
and esi, ~CPUM_USED_FPU ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
mov [rdx + r8 + CPUMCPU.fUseFlags], esi
mov [rdx + r8 + CPUMCPU.Host.cr0], rax
;mov [rdx + r8 + CPUMCPU.Host.cr2], rax
mov [rdx + r8 + CPUMCPU.Host.cr3], rax
mov [rdx + r8 + CPUMCPU.Host.cr4], rax
; Change CR0 and CR4 so we can correctly emulate FPU/MMX/SSE[23] exceptions
mov ecx, [rdx + r8 + CPUMCPU.Guest.cr4]
; in CPUMCPU.Hyper.cr4 (which isn't currently being used). That should
and ecx, [rdx + CPUM.CR4.AndMask]
or eax, [rdx + CPUM.CR4.OrMask]
mov eax, [rdx + r8 + CPUMCPU.Guest.cr0]
lgdt [rdx + r8 + CPUMCPU.Hyper.gdtr]
mov ebp, [rdx + r8 + CPUMCPU.Hyper.cr3]
mov [rdx + r8 + CPUMCPU.Host.dr7], rax
mov [rdx + r8 + CPUMCPU.Host.dr6], rax
mov [rdx + r8 + CPUMCPU.Host.dr0], rax
mov [rdx + r8 + CPUMCPU.Host.dr1], rbx
mov [rdx + r8 + CPUMCPU.Host.dr2], rcx
mov [rdx + r8 + CPUMCPU.Host.dr3], rax
lidt [edx + CPUMCPU.Hyper.idtr]
mov eax, [edx + CPUMCPU.Hyper.esp]
mov [edx + CPUMCPU.Hyper.lss_esp], eax
lss esp, [edx + CPUMCPU.Hyper.lss_esp]
ltr word [edx + CPUMCPU.Hyper.tr]
lldt [edx + CPUMCPU.Hyper.ldtr]
mov esi, [edx + CPUMCPU.fUseFlags]
mov ebx, [edx + CPUMCPU.Hyper.ebx]
mov ebp, [edx + CPUMCPU.Hyper.ebp]
mov esi, [edx + CPUMCPU.Hyper.esi]
mov edi, [edx + CPUMCPU.Hyper.edi]
push dword [edx + CPUMCPU.Hyper.eflags]
mov eax, [edx + CPUMCPU.Hyper.eip]
mov eax, [edx + CPUMCPU.Hyper.eip]
FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToGC
mov ebx, [edx + CPUMCPU.Hyper.dr]
mov ecx, [edx + CPUMCPU.Hyper.dr + 8*1]
mov eax, [edx + CPUMCPU.Hyper.dr + 8*2]
mov ebx, [edx + CPUMCPU.Hyper.dr + 8*3]
;mov eax, [edx + CPUMCPU.Hyper.dr + 8*6]
mov eax, [edx + CPUMCPU.Hyper.dr + 8*7]
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
mov eax, [esp + 4 + CPUMCTXCORE.edi]
mov [edx + CPUMCPU.Guest.edi], eax
mov eax, [esp + 4 + CPUMCTXCORE.esi]
mov [edx + CPUMCPU.Guest.esi], eax
mov eax, [esp + 4 + CPUMCTXCORE.ebp]
mov [edx + CPUMCPU.Guest.ebp], eax
mov eax, [esp + 4 + CPUMCTXCORE.eax]
mov [edx + CPUMCPU.Guest.eax], eax
mov eax, [esp + 4 + CPUMCTXCORE.ebx]
mov [edx + CPUMCPU.Guest.ebx], eax
mov eax, [esp + 4 + CPUMCTXCORE.edx]
mov [edx + CPUMCPU.Guest.edx], eax
mov eax, [esp + 4 + CPUMCTXCORE.ecx]
mov [edx + CPUMCPU.Guest.ecx], eax
mov eax, [esp + 4 + CPUMCTXCORE.esp]
mov [edx + CPUMCPU.Guest.esp], eax
mov eax, [esp + 4 + CPUMCTXCORE.ss]
mov [edx + CPUMCPU.Guest.ss], eax
mov eax, [esp + 4 + CPUMCTXCORE.gs]
mov [edx + CPUMCPU.Guest.gs], eax
mov eax, [esp + 4 + CPUMCTXCORE.fs]
mov [edx + CPUMCPU.Guest.fs], eax
mov eax, [esp + 4 + CPUMCTXCORE.es]
mov [edx + CPUMCPU.Guest.es], eax
mov eax, [esp + 4 + CPUMCTXCORE.ds]
mov [edx + CPUMCPU.Guest.ds], eax
mov eax, [esp + 4 + CPUMCTXCORE.cs]
mov [edx + CPUMCPU.Guest.cs], eax
mov eax, [esp + 4 + CPUMCTXCORE.eflags]
mov [edx + CPUMCPU.Guest.eflags], eax
mov eax, [esp + 4 + CPUMCTXCORE.eip]
mov [edx + CPUMCPU.Guest.eip], eax
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
mov eax, [ecx + CPUMCTXCORE.edi]
mov [edx + CPUMCPU.Hyper.edi], eax
mov eax, [ecx + CPUMCTXCORE.esi]
mov [edx + CPUMCPU.Hyper.esi], eax
mov eax, [ecx + CPUMCTXCORE.ebp]
mov [edx + CPUMCPU.Hyper.ebp], eax
mov eax, [ecx + CPUMCTXCORE.eax]
mov [edx + CPUMCPU.Hyper.eax], eax
mov eax, [ecx + CPUMCTXCORE.ebx]
mov [edx + CPUMCPU.Hyper.ebx], eax
mov eax, [ecx + CPUMCTXCORE.edx]
mov [edx + CPUMCPU.Hyper.edx], eax
mov eax, [ecx + CPUMCTXCORE.ecx]
mov [edx + CPUMCPU.Hyper.ecx], eax
mov eax, [ecx + CPUMCTXCORE.esp]
mov [edx + CPUMCPU.Hyper.esp], eax
mov eax, [ecx + CPUMCTXCORE.ss]
mov [edx + CPUMCPU.Hyper.ss], eax
mov eax, [ecx + CPUMCTXCORE.gs]
mov [edx + CPUMCPU.Hyper.gs], eax
mov eax, [ecx + CPUMCTXCORE.fs]
mov [edx + CPUMCPU.Hyper.fs], eax
mov eax, [ecx + CPUMCTXCORE.es]
mov [edx + CPUMCPU.Hyper.es], eax
mov eax, [ecx + CPUMCTXCORE.ds]
mov [edx + CPUMCPU.Hyper.ds], eax
mov eax, [ecx + CPUMCTXCORE.cs]
mov [edx + CPUMCPU.Hyper.cs], eax
mov eax, [ecx + CPUMCTXCORE.eflags]
mov [edx + CPUMCPU.Hyper.eflags], eax
mov eax, [ecx + CPUMCTXCORE.eip]
mov [edx + CPUMCPU.Hyper.eip], eax
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalInGC
FIXUP FIX_GC_VM_OFF, 1, VM.StatTotalGCToQemu
FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToHC
pop dword [edx + CPUMCPU.Hyper.eip] ; call return from stack
mov dword [edx + CPUMCPU.Hyper.ebx], ebx
mov dword [edx + CPUMCPU.Hyper.esi], esi
mov dword [edx + CPUMCPU.Hyper.edi], edi
mov dword [edx + CPUMCPU.Hyper.ebp], ebp
mov dword [edx + CPUMCPU.Hyper.esp], esp
; str [edx + CPUMCPU.Hyper.tr] - double fault only, and it won't be right then either.
sldt [edx + CPUMCPU.Hyper.ldtr]
; No need to save CRx here. They are set dynamically according to Guest/Host requirements.
mov rsi, [rdx + CPUMCPU.Host.cr3]
mov r8d, [rdx + CPUM.offCPUMCPU0]
lgdt [rdx + r8 + CPUMCPU.Host.gdtr]
lidt [rdx + r8 + CPUMCPU.Host.idtr]
movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
ltr word [rdx + r8 + CPUMCPU.Host.tr]
movzx eax, word [rdx + r8 + CPUMCPU.Host.tr] ; eax <- TR
ltr word [rdx + r8 + CPUMCPU.Host.tr]
lldt [rdx + r8 + CPUMCPU.Host.ldtr]
mov eax, [rdx + r8 + CPUMCPU.Host.ds]
mov eax, [rdx + r8 + CPUMCPU.Host.es]
mov eax, [rdx + r8 + CPUMCPU.Host.fs]
mov eax, [rdx + r8 + CPUMCPU.Host.gs]
mov eax, [rdx + r8 + CPUMCPU.Host.ss]
mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
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.
mov eax, [rbx + r8 + CPUMCPU.Host.SysEnter.cs]
mov edx, [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4]
mov esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
fxsave [rdx + r8 + CPUMCPU.Guest.fpu]
fxrstor [rdx + r8 + CPUMCPU.Host.fpu]
mov rcx, [rdx + r8 + CPUMCPU.Host.cr4]
mov rcx, [rdx + r8 + CPUMCPU.Host.cr0]
;mov rcx, [rdx + r8 + CPUMCPU.Host.cr2] ; assumes this is waste of time.
mov eax, [rbx + r8 + CPUMCPU.Host.FSbase]
mov edx, [rbx + r8 + CPUMCPU.Host.FSbase + 4]
mov eax, [rbx + r8 + CPUMCPU.Host.GSbase]
mov edx, [rbx + r8 + CPUMCPU.Host.GSbase + 4]
mov eax, [rbx + r8 + CPUMCPU.Host.efer]
mov edx, [rbx + r8 + CPUMCPU.Host.efer + 4]
; mov rax, [rdx + r8 + CPUMCPU.Host.rax] - scratch + return code
mov rbx, [rdx + r8 + CPUMCPU.Host.rbx]
; mov rcx, [rdx + r8 + CPUMCPU.Host.rcx] - scratch
; mov rdx, [rdx + r8 + CPUMCPU.Host.rdx] - scratch
mov rdi, [rdx + r8 + CPUMCPU.Host.rdi]
mov rsi, [rdx + r8 + CPUMCPU.Host.rsi]
mov rsp, [rdx + r8 + CPUMCPU.Host.rsp]
mov rbp, [rdx + r8 + CPUMCPU.Host.rbp]
; mov r8, [rdx + r8 + CPUMCPU.Host.r8 ] - scratch
; mov r9, [rdx + r8 + CPUMCPU.Host.r9 ] - scratch
mov r10, [rdx + r8 + CPUMCPU.Host.r10]
mov r11, [rdx + r8 + CPUMCPU.Host.r11]
mov r12, [rdx + r8 + CPUMCPU.Host.r12]
mov r13, [rdx + r8 + CPUMCPU.Host.r13]
mov r14, [rdx + r8 + CPUMCPU.Host.r14]
mov r15, [rdx + r8 + CPUMCPU.Host.r15]
push qword [rdx + r8 + CPUMCPU.Host.rflags]
mov rax, [rdx + r8 + CPUMCPU.Host.dr0]
mov rbx, [rdx + r8 + CPUMCPU.Host.dr1]
mov rcx, [rdx + r8 + CPUMCPU.Host.dr2]
mov rax, [rdx + r8 + CPUMCPU.Host.dr3]
mov rbx, [rdx + r8 + CPUMCPU.Host.dr6]
mov rcx, [rdx + r8 + CPUMCPU.Host.dr7]
at VMMSWITCHERDEF.pvCode, RTCCPTR_DEF NAME(Start)
at VMMSWITCHERDEF.pvFixups, RTCCPTR_DEF NAME(Fixups)
at VMMSWITCHERDEF.pszDesc, RTCCPTR_DEF NAME(Description)
at VMMSWITCHERDEF.pfnRelocate, RTCCPTR_DEF NAME(Relocate)
at VMMSWITCHERDEF.enmType, dd SWITCHER_TYPE
at VMMSWITCHERDEF.cbCode, dd NAME(End) - NAME(Start)
at VMMSWITCHERDEF.offR0HostToGuest, dd NAME(vmmR0HostToGuest) - NAME(Start)
at VMMSWITCHERDEF.offGCGuestToHost, dd NAME(vmmGCGuestToHost) - NAME(Start)
at VMMSWITCHERDEF.offGCCallTrampoline, dd NAME(vmmGCCallTrampoline) - NAME(Start)
at VMMSWITCHERDEF.offGCGuestToHostAsm, dd NAME(VMMGCGuestToHostAsm) - NAME(Start)
at VMMSWITCHERDEF.offGCGuestToHostAsmHyperCtx, dd NAME(VMMGCGuestToHostAsmHyperCtx)- NAME(Start)
at VMMSWITCHERDEF.offGCGuestToHostAsmGuestCtx, dd NAME(VMMGCGuestToHostAsmGuestCtx)- NAME(Start)
at VMMSWITCHERDEF.offHCCode0, dd 0
at VMMSWITCHERDEF.cbHCCode0, dd NAME(IDEnterTarget) - NAME(Start)
at VMMSWITCHERDEF.offHCCode1, dd NAME(HCExitTarget) - NAME(Start)
at VMMSWITCHERDEF.cbHCCode1, dd NAME(End) - NAME(HCExitTarget)
at VMMSWITCHERDEF.offIDCode0, dd NAME(IDEnterTarget) - NAME(Start)
at VMMSWITCHERDEF.cbIDCode0, dd NAME(JmpGCTarget) - NAME(IDEnterTarget)
at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
at VMMSWITCHERDEF.cbIDCode1, dd NAME(HCExitTarget) - NAME(IDExitTarget)
at VMMSWITCHERDEF.offGCCode, dd NAME(JmpGCTarget) - NAME(Start)
at VMMSWITCHERDEF.cbGCCode, dd NAME(IDExitTarget) - NAME(JmpGCTarget)