TRPMR0A.asm revision 769d882a3803c0f7321cf9874be77aa3454ad9fb
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; $Id$
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;; @file
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; TRPM - Host Context Ring-0
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync; Copyright (C) 2006 InnoTek Systemberatung GmbH
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; available from http://www.virtualbox.org. This file is free software;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; you can redistribute it and/or modify it under the terms of the GNU
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; General Public License as published by the Free Software Foundation,
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; distribution. VirtualBox OSE is distributed in the hope that it will
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; be useful, but WITHOUT ANY WARRANTY of any kind.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; If you received this file as part of a commercial VirtualBox
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; distribution, then only the terms of your commercial VirtualBox
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; license agreement apply instead of the previous paragraph.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;* Header Files *
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;*******************************************************************************
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync%include "VBox/asmdefs.mac"
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync%include "VBox/x86.mac"
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncBEGINCODE
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync align 16
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; Calls the interrupt gate as if we received an interrupt while in Ring-0.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; Returns with interrupts enabled.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; @param uIP x86:[ebp+8] msc:rcx gcc:rdi The interrupt gate IP.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; @param SelCS x86:[ebp+12] msc:dx gcc:si The interrupt gate CS.
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync; @param RSP msc:r8 gcc:rdx The interrupt gate RSP. ~0 if no stack switch should take place. (only AMD64)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync;DECLASM(void) trpmR0DispatchHostInterrupt(RTR0UINTPTR uIP, RTSEL SelCS, RTR0UINTPTR RSP);
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsyncBEGINPROC trpmR0DispatchHostInterrupt
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push xBP
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync mov xBP, xSP
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync%ifdef __AMD64__
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync mov rax, rsp
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync and rsp, 15h ; align the stack. (do it unconditionally saves some jump mess)
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ; switch stack?
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %ifdef ASM_CALL64_MSC
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync cmp r8, 0ffffffffffffffffh
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync je .no_stack_switch
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync mov rsp, r8
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %else
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync cmp rdx, 0ffffffffffffffffh
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync je .no_stack_switch
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync mov rsp, rdx
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %endif
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync.no_stack_switch:
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ; create the iret frame
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push 0 ; SS
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rax ; RSP
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync pushfd ; RFLAGS
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync and dword [rsp], ~X86_EFL_IF
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync mov ax, cs
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rax ; CS
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync mov rax, .return ; RIP
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rax
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync ; create the retf frame
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %ifdef ASM_CALL64_MSC
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync movzx rdx, dx
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rdx
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rcx
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %else
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync movzx rdi, di
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rdi
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync push rsi
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync %endif
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync ; dispatch it!
a0a3a26a4065b9401681a8c99a11bd83e08f94ccvboxsync db 048h
9fc464631dc4a68fbb5eb6419d61fbe91b6b16bdvboxsync retf
%else ; 32-bit:
mov ecx, [ebp + 8] ; uIP
movzx edx, word [ebp + 12] ; SelCS
; create the iret frame
pushfd ; EFLAGS
and dword [esp], ~X86_EFL_IF
push cs ; CS
push .return ; EIP
; create the retf frame
push edx
push ecx
; dispatch it!
retf
%endif
.return:
leave
ret
ENDPROC trpmR0DispatchHostInterrupt
%ifndef VBOX_WITHOUT_IDT_PATCHING
align 16
;;
; This is the alternative return from VMMR0Entry() used when
; we need to dispatch an interrupt to the Host (we received it in GC).
;
; As seen in TRPMR0SetupInterruptDispatcherFrame() the stack is different
; than for the normal VMMR0Entry() return.
;
; 32-bit:
; 18 iret frame
; 14 retf selector (interrupt handler)
; 10 retf offset (interrupt handler)
; c es
; 8 fs
; 4 ds
; 0 pVM (esp here)
;
; 64-bit:
; 24 iret frame
; 18 retf selector (interrupt handler)
; 10 retf offset (interrupt handler)
; 8 uOperation
; 0 pVM
;
BEGINPROC trpmR0InterruptDispatcher
%ifdef __AMD64__
lea rsp, [rsp + 10h] ; skip pVM and uOperation
db 48h
retf
%else ; !__AMD64__
add esp, byte 4 ; skip pVM
pop ds
pop fs
pop es
retf
%endif ; !__AMD64__
ENDPROC trpmR0InterruptDispatcher
%endif ; !VBOX_WITHOUT_IDT_PATCHING