PAEand32Bit.mac revision c98c1b741a7d46beda192d871d02ff91774d4c31
2N/A; available from http://www.virtualbox.org. This file is free software;
2N/A%include "VBox/asmdefs.mac"
2N/A%include "VBox/x86.mac"
2N/A%include "VBox/cpum.mac"
2N/A%include "VBox/stam.mac"
2N/A%include "VBox/vm.mac"
2N/A%include "CPUMInternal.mac"
2N/A%include "VMMSwitcher/VMMSwitcher.mac"
2N/A FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToGC
2N/A FIXUP FIX_HC_VM_OFF, 1, VM.StatSwitcherToHC
2N/A mov [edx + CPUM.Host.ebx], ebx
2N/A mov [edx + CPUM.Host.edi], edi
mov [edx + CPUM.Host.esi], esi
mov [edx + CPUM.Host.esp], esp
mov [edx + CPUM.Host.ebp], ebp
mov [edx + CPUM.Host.ds], ds
mov [edx + CPUM.Host.es], es
mov [edx + CPUM.Host.fs], fs
mov [edx + CPUM.Host.gs], gs
mov [edx + CPUM.Host.ss], ss
sldt [edx + CPUM.Host.ldtr]
sidt [edx + CPUM.Host.idtr]
sgdt [edx + CPUM.Host.gdtr]
str [edx + CPUM.Host.tr]
pop dword [edx + CPUM.Host.eflags]
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 [ebx + CPUM.Host.SysEnter.cs], eax
mov [ebx + CPUM.Host.SysEnter.cs + 4], edx
mov esi, [edx + CPUM.fUseFlags] ; esi == use flags.
and esi, ~CPUM_USED_FPU ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
mov [edx + CPUM.fUseFlags], esi
mov [edx + CPUM.Host.cr0], eax
;mov [edx + CPUM.Host.cr2], eax
mov [edx + CPUM.Host.cr3], eax
mov [edx + CPUM.Host.cr4], eax
; Change CR0 and CR4 so we can correctly emulate FPU/MMX/SSE[23] exceptions
mov ecx, [edx + CPUM.Guest.cr4]
; in CPUM.Hyper.cr4 (which isn't currently being used). That should
and ecx, [edx + CPUM.CR4.AndMask]
or eax, [edx + CPUM.CR4.OrMask]
mov eax, [edx + CPUM.Guest.cr0]
lgdt [edx + CPUM.Hyper.gdtr]
lidt [edx + CPUM.Hyper.idtr]
lss esp, [edx + CPUM.Hyper.esp]
ltr word [edx + CPUM.Hyper.tr]
lldt [edx + CPUM.Hyper.ldtr]
mov esi, [edx + CPUM.fUseFlags]
mov ebx, [edx + CPUM.Hyper.ebx]
mov ebp, [edx + CPUM.Hyper.ebp]
mov esi, [edx + CPUM.Hyper.esi]
mov edi, [edx + CPUM.Hyper.edi]
push dword [edx + CPUM.Hyper.eflags]
mov eax, [edx + CPUM.Hyper.eip]
mov eax, [edx + CPUM.Hyper.eip]
FIXUP FIX_GC_VM_OFF, 1, VM.StatSwitcherToGC
mov [edx + CPUM.Host.dr7], eax
mov [edx + CPUM.Host.dr6], eax
mov [edx + CPUM.Host.dr0], eax
mov [edx + CPUM.Host.dr1], ebx
mov [edx + CPUM.Host.dr2], ecx
mov [edx + CPUM.Host.dr3], eax
mov ebx, [edx + CPUM.Hyper.dr0]
mov ecx, [edx + CPUM.Hyper.dr1]
mov eax, [edx + CPUM.Hyper.dr2]
mov ebx, [edx + CPUM.Hyper.dr3]
;mov eax, [edx + CPUM.Hyper.dr6]
mov eax, [edx + CPUM.Hyper.dr7]
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.eax]
mov [edx + CPUM.Guest.eax], eax
mov eax, [esp + 4 + CPUMCTXCORE.ecx]
mov [edx + CPUM.Guest.ecx], eax
mov eax, [esp + 4 + CPUMCTXCORE.edx]
mov [edx + CPUM.Guest.edx], eax
mov eax, [esp + 4 + CPUMCTXCORE.ebx]
mov [edx + CPUM.Guest.ebx], eax
mov eax, [esp + 4 + CPUMCTXCORE.esp]
mov [edx + CPUM.Guest.esp], eax
mov eax, [esp + 4 + CPUMCTXCORE.ebp]
mov [edx + CPUM.Guest.ebp], eax
mov eax, [esp + 4 + CPUMCTXCORE.esi]
mov [edx + CPUM.Guest.esi], eax
mov eax, [esp + 4 + CPUMCTXCORE.edi]
mov [edx + CPUM.Guest.edi], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.es]
mov dword [edx + CPUM.Guest.es], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.cs]
mov dword [edx + CPUM.Guest.cs], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.ss]
mov dword [edx + CPUM.Guest.ss], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.ds]
mov dword [edx + CPUM.Guest.ds], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.fs]
mov dword [edx + CPUM.Guest.fs], eax
mov eax, dword [esp + 4 + CPUMCTXCORE.gs]
mov dword [edx + CPUM.Guest.gs], eax
mov eax, [esp + 4 + CPUMCTXCORE.eflags]
mov dword [edx + CPUM.Guest.eflags], eax
mov eax, [esp + 4 + CPUMCTXCORE.eip]
mov dword [edx + CPUM.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 + CPUM.Hyper.edi], eax
mov eax, [ecx + CPUMCTXCORE.esi]
mov [edx + CPUM.Hyper.esi], eax
mov eax, [ecx + CPUMCTXCORE.ebp]
mov [edx + CPUM.Hyper.ebp], eax
mov eax, [ecx + CPUMCTXCORE.eax]
mov [edx + CPUM.Hyper.eax], eax
mov eax, [ecx + CPUMCTXCORE.ebx]
mov [edx + CPUM.Hyper.ebx], eax
mov eax, [ecx + CPUMCTXCORE.edx]
mov [edx + CPUM.Hyper.edx], eax
mov eax, [ecx + CPUMCTXCORE.ecx]
mov [edx + CPUM.Hyper.ecx], eax
mov eax, [ecx + CPUMCTXCORE.esp]
mov [edx + CPUM.Hyper.esp], eax
mov eax, [ecx + CPUMCTXCORE.ss]
mov [edx + CPUM.Hyper.ss], eax
mov eax, [ecx + CPUMCTXCORE.gs]
mov [edx + CPUM.Hyper.gs], eax
mov eax, [ecx + CPUMCTXCORE.fs]
mov [edx + CPUM.Hyper.fs], eax
mov eax, [ecx + CPUMCTXCORE.es]
mov [edx + CPUM.Hyper.es], eax
mov eax, [ecx + CPUMCTXCORE.ds]
mov [edx + CPUM.Hyper.ds], eax
mov eax, [ecx + CPUMCTXCORE.cs]
mov [edx + CPUM.Hyper.cs], eax
mov eax, [ecx + CPUMCTXCORE.eflags]
mov [edx + CPUM.Hyper.eflags], eax
mov eax, [ecx + CPUMCTXCORE.eip]
mov [edx + CPUM.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 + CPUM.Hyper.eip] ; call return from stack
mov dword [edx + CPUM.Hyper.ebx], ebx
mov dword [edx + CPUM.Hyper.esi], esi
mov dword [edx + CPUM.Hyper.edi], edi
mov dword [edx + CPUM.Hyper.ebp], ebp
mov dword [edx + CPUM.Hyper.esp], esp
; str [edx + CPUM.Hyper.tr] - double fault only, and it won't be right then either.
sldt [edx + CPUM.Hyper.ldtr]
; No need to save CRx here. They are set dynamically according to Guest/Host requirements.
mov ecx, [edx + CPUM.Host.cr3]
lgdt [edx + CPUM.Host.gdtr]
lidt [edx + CPUM.Host.idtr]
movzx eax, word [edx + CPUM.Host.tr] ; eax <- TR
ltr word [edx + CPUM.Host.tr]
movzx eax, word [edx + CPUM.Host.tr] ; eax <- TR
ltr word [edx + CPUM.Host.tr]
lldt [edx + CPUM.Host.ldtr]
mov eax, [edx + CPUM.Host.ds]
mov eax, [edx + CPUM.Host.es]
mov eax, [edx + CPUM.Host.fs]
mov eax, [edx + CPUM.Host.gs]
lss esp, [edx + CPUM.Host.esp]
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, [edx + CPUM.Host.SysEnter.cs]
mov ebx, [edx + CPUM.Host.SysEnter.cs + 4]
xchg edx, ebx ; save/load edx
mov esi, [edx + CPUM.fUseFlags] ; esi == use flags.
FIXUP FIX_NO_FXSAVE_JMP, 0, gth_no_fxsave - NAME(Start) ; this will insert a jmp gth_no_fxsave if fxsave isn't supported.
fxsave [edx + CPUM.Guest.fpu]
fxrstor [edx + CPUM.Host.fpu]
fnsave [edx + CPUM.Guest.fpu]
mov eax, [edx + CPUM.Host.fpu] ; control word
test eax, [edx + CPUM.Host.fpu + 4] ; status word
and dword [edx + CPUM.Host.fpu + 4], ~03Fh
frstor [edx + CPUM.Host.fpu]
mov ecx, [edx + CPUM.Host.cr4]
mov ecx, [edx + CPUM.Host.cr0]
;mov ecx, [edx + CPUM.Host.cr2] ; assumes this is waste of time.
mov edi, [edx + CPUM.Host.edi]
mov esi, [edx + CPUM.Host.esi]
mov ebx, [edx + CPUM.Host.ebx]
mov ebp, [edx + CPUM.Host.ebp]
push dword [edx + CPUM.Host.eflags]
mov eax, [edx + CPUM.Host.dr0]
mov ebx, [edx + CPUM.Host.dr1]
mov ecx, [edx + CPUM.Host.dr2]
mov eax, [edx + CPUM.Host.dr3]
mov ebx, [edx + CPUM.Host.dr6]
mov ecx, [edx + CPUM.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.cbHCCode0, dd NAME(FarJmpGCTarget) - 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(FarJmpGCTarget) - NAME(IDEnterTarget)
at VMMSWITCHERDEF.offIDCode1, dd NAME(IDExitTarget) - NAME(Start)
at VMMSWITCHERDEF.cbIDCode1, dd NAME(HCExitTarget) - NAME(IDExitTarget)
at VMMSWITCHERDEF.offIDCode0, dd 0
at VMMSWITCHERDEF.cbIDCode0, dd 0
at VMMSWITCHERDEF.offIDCode1, dd 0
at VMMSWITCHERDEF.cbIDCode1, dd 0
at VMMSWITCHERDEF.offGCCode, dd NAME(FarJmpGCTarget) - NAME(Start)
at VMMSWITCHERDEF.cbGCCode, dd NAME(IDExitTarget) - NAME(FarJmpGCTarget)
at VMMSWITCHERDEF.cbGCCode, dd NAME(HCExitTarget) - NAME(FarJmpGCTarget)