%include "defs.asm"
%include "symbol.asm"
+SVM_ERROR equ 0xFFFFFFFF
+SVM_SUCCESS equ 0x00000000
+
+EXPORT DisableInts
EXPORT GetGDTR
EXPORT GetIDTR
+EXPORT GetTR
-
+EXPORT exit_test
EXTERN handle_svm_exit
EXPORT launch_svm
+EXPORT safe_svm_launch
+
+
+;; These need to be kept similar with the svm return values in svm.h
+SVM_HANDLER_SUCCESS equ 0x00
+SVM_HANDLER_ERROR equ 0x1
+SVM_HANDLER_HALT equ 0x2
+
[BITS 32]
+
+; Save and restore registers needed by SVM
+%macro Save_SVM_Registers 1
+ push eax
+ mov eax, dword %1
+ mov [eax], edi
+ mov [eax + 8], esi
+ mov [eax + 16], ebp
+ mov [eax + 24], dword 0 ;; esp
+ mov [eax + 32], ebx
+ mov [eax + 40], edx
+ mov [eax + 48], ecx
+
+ push ebx
+ mov ebx, [esp + 4]
+ mov [eax + 56], ebx ;; eax
+ pop ebx
+
+ pop eax
+%endmacro
+
+
+%macro Restore_SVM_Registers 1
+ push eax
+ mov eax, dword %1
+ mov edi, [eax]
+ mov esi, [eax + 8]
+ mov ebp, [eax + 16]
+;; mov esp, [eax + 24]
+ mov ebx, [eax + 32]
+ mov edx, [eax + 40]
+ mov ecx, [eax + 48]
+;; mov eax, [eax + 56]
+ pop eax
+%endmacro
+
%macro vmrun 0
db 00fh, 001h, 0d8h
%endmacro
+%macro vmsave 0
+ db 00fh, 001h, 0dbh
+%endmacro
+
+%macro vmload 0
+ db 00fh, 001h, 0dah
+%endmacro
;VMRUN equ db 0Fh, 01h, D8h
;VMLOAD equ db 0x0F,0x01,0xDA
;CLGI equ db 0x0F,0x01,0xDD
+align 8
+DisableInts:
+ cli
+ ret
+align 8
GetGDTR:
push ebp
mov ebp, esp
ret
-
+align 8
GetIDTR:
push ebp
mov ebp, esp
pusha
+
mov ebx, [ebp + 8]
- sgdt [ebx]
+ sidt [ebx]
+
+ popa
+ pop ebp
+ ret
+
+
+
+align 8
+GetTR:
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ebx, [ebp + 8]
+ str [ebx]
popa
pop ebp
; I think its safe to say that there are some pretty serious register issues...
+align 8
launch_svm:
push ebp
mov ebp, esp
-; eventual svm_launch
-; pusha
-; pushf
-;
-; .vmm_loop
-; vmrun
-; push guest GPRs
-; call handle_svm_exit
-; jz .vmm_loop
-; popf
-; popa
-; ret
-;
-;
-;
+exit_test:
+ mov cr4, eax
+ ret
;; Need to check this..
-;; Since RAX/EAX is saved in the VMCB, we should probably just
-;; do our own replacement for pusha/popa that excludes [e|r]ax
+;; save_svm_launch(rax, struct guest_gprs * regs)
+align 8
safe_svm_launch:
push ebp
mov ebp, esp
pushf
- pusha
+ pusha ;; Save Host state
-.vmm_loop:
- mov eax, [ebp + 8]
+
+ push dword [ebp + 12] ;; pointer to the guest GPR save area
+ push dword [ebp + 8] ;; pointer to the VMCB pointer
+
+;; mov eax, [esp + 4] ;; mov guest GPR pointer to eax
+
+ Restore_SVM_Registers [esp + 4] ;; Restore Guest GPR state
+ pop eax ;; pop VMCB pointer into eax
+
+ vmload
vmrun
- pusha
- call handle_svm_exit
- and eax, eax
- popa ;; restore the guest GPRs, (DOES THIS AFFECT E/RFLAGS?)
- jz .vmm_loop
+ vmsave
- ;; HOW DO WE GET THE RETURN VALUE OF HANDLE_SVM_EXIT BACK TO THE CALLER
+;; pop eax ;; pop Guest GPR pointer into eax
+ Save_SVM_Registers [esp] ;; save guest GPRs
+
+ add esp, 4 ;; skip past the gpr ptr
+
+ popa ;; Restore Host state
popf
- popa
- pop ebp
+ pop ebp
ret
+
%endif