summaryrefslogtreecommitdiffstats
path: root/src/VBox/VMM/VMMR0/TRPMR0A.asm
blob: 8eee50f39630300346e2714d56ec036f08fb2420 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
; $Id: TRPMR0A.asm $
;; @file
; TRPM - Host Context Ring-0
;

;
; Copyright (C) 2006-2019 Oracle Corporation
;
; This file is part of VirtualBox Open Source Edition (OSE), as
; available from http://www.virtualbox.org. This file is free software;
; you can redistribute it and/or modify it under the terms of the GNU
; General Public License (GPL) as published by the Free Software
; Foundation, in version 2 as it comes in the "COPYING" file of the
; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
;

;*******************************************************************************
;* Header Files                                                                *
;*******************************************************************************
%include "VBox/asmdefs.mac"
%include "iprt/x86.mac"


BEGINCODE

;;
; Calls the interrupt gate as if we received an interrupt while in Ring-0.
;
; @param   uIP     x86:[ebp+8]   msc:rcx  gcc:rdi  The interrupt gate IP.
; @param   SelCS   x86:[ebp+12]  msc:dx   gcc:si   The interrupt gate CS.
; @param   RSP                   msc:r8   gcc:rdx  The interrupt gate RSP. ~0 if no stack switch should take place. (only AMD64)
;DECLASM(void) trpmR0DispatchHostInterrupt(RTR0UINTPTR uIP, RTSEL SelCS, RTR0UINTPTR RSP);
ALIGNCODE(16)
BEGINPROC trpmR0DispatchHostInterrupt
    push    xBP
    mov     xBP, xSP

%ifdef RT_ARCH_AMD64
    mov     r11, rsp                    ; save the RSP for the iret frame.
    and     rsp, 0fffffffffffffff0h     ; align the stack. (do it unconditionally saves some jump mess)

    ; switch stack?
 %ifdef ASM_CALL64_MSC
    cmp     r8,  0ffffffffffffffffh
    je      .no_stack_switch
    mov     rsp, r8
 %else
    cmp     rdx, 0ffffffffffffffffh
    je      .no_stack_switch
    mov     rsp, rdx
 %endif
.no_stack_switch:

    ; create the iret frame
    push    0                           ; SS
    push    r11                         ; RSP
    pushfq                              ; RFLAGS
    and     dword [rsp], ~X86_EFL_IF
    mov     ax, cs
    push    rax                         ; CS
    lea     r10, [.return wrt rip]      ; RIP
    push    r10

    ; create the retf frame
 %ifdef ASM_CALL64_MSC
    movzx   rdx, dx
    cmp     rdx, r11
    je      .dir_jump
    push    rdx
    push    rcx
 %else
    movzx   rsi, si
    cmp     rsi, r11
    je      .dir_jump
    push    rsi
    push    rdi
 %endif

    ; dispatch it
    db 048h
    retf

    ; dispatch it by a jmp (don't mess up the IST stack)
.dir_jump:
 %ifdef ASM_CALL64_MSC
    jmp     rcx
 %else
    jmp     rdi
 %endif

%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:
    cli

    leave
    ret
ENDPROC trpmR0DispatchHostInterrupt


;;
; Issues a software interrupt to the specified interrupt vector.
;
; @param   uActiveVector   x86:[esp+4]   msc:rcx  gcc:rdi   The vector number.
;
;DECLASM(void) trpmR0DispatchHostInterruptSimple(RTUINT uActiveVector);
ALIGNCODE(16)
BEGINPROC trpmR0DispatchHostInterruptSimple
%ifdef RT_ARCH_X86
    mov     eax, [esp + 4]
    jmp     dword [.jmp_table + eax * 4]
%else
    lea     r9, [.jmp_table wrt rip]
 %ifdef ASM_CALL64_MSC
    jmp     qword [r9 + rcx * 8]
 %else
    jmp     qword [r9 + rdi * 8]
 %endif
%endif

ALIGNCODE(4)
.jmp_table:
%assign i 0
%rep 256
RTCCPTR_DEF .int_ %+ i
%assign i i+1
%endrep

%assign i 0
%rep 256
    ALIGNCODE(4)
.int_ %+ i:
    int i
    ret
%assign i i+1
%endrep

ENDPROC trpmR0DispatchHostInterruptSimple