110 lines
2.5 KiB
HTML
110 lines
2.5 KiB
HTML
; =============================================================================
|
||
; Модуль : IRQ Handler
|
||
; Назначение : Обработчик прерываний VMMDev
|
||
; Файл : core/irq.inc
|
||
; =============================================================================
|
||
|
||
align 4
|
||
vbox_irq_count dd 0
|
||
|
||
; vbox_irq_handler — Top-half обработчик IRQ
|
||
proc vbox_irq_handler stdcall
|
||
push ebx edx
|
||
|
||
movzx edx, word [vbox_device.port]
|
||
add dx, VMMDEV_PORT_OFF_REQUEST_FAST
|
||
in eax, dx
|
||
|
||
test eax, eax
|
||
jz .not_ours
|
||
|
||
mov ebx, eax
|
||
|
||
; ACK все события сразу
|
||
out dx, eax
|
||
|
||
DEBUGF __DEBUG_IRQ__, "[VBoxGuest] [Dispatch] [IRQ] events=0x%x, service event=0x%x\n", ebx, [dispatcher_active_events]
|
||
|
||
; Немедленно разбудить HGCM-треды (Linux: wake_up() из IRQ)
|
||
test ebx, VMMDEV_EVENT_HGCM
|
||
jz .no_hgcm_wake
|
||
call hgcm_irq_dispatch
|
||
.no_hgcm_wake:
|
||
|
||
; Вызвать fn_on_event у всех подходящих сервисов прямо сейчас
|
||
stdcall dispatcher_dispatch, ebx
|
||
|
||
lock inc dword [vbox_irq_count]
|
||
|
||
.acked:
|
||
pop edx ebx
|
||
mov eax, 1
|
||
ret
|
||
|
||
.not_ours:
|
||
pop edx ebx
|
||
xor eax, eax
|
||
ret
|
||
endp
|
||
|
||
; hgcm_irq_dispatch — Разбудить все HGCM-треды из IRQ контекста
|
||
proc hgcm_irq_dispatch
|
||
push eax ebx ecx edx esi edi
|
||
|
||
mov ecx, [services_count]
|
||
test ecx, ecx
|
||
jz .done
|
||
|
||
mov edi, services_table
|
||
|
||
.loop:
|
||
cmp dword [edi + SERVICE_ENTRY.enabled], 0
|
||
je .next
|
||
|
||
cmp dword [edi + SERVICE_ENTRY.hgcm_wakeup_event], 0
|
||
je .next
|
||
|
||
mov eax, [edi + SERVICE_ENTRY.hgcm_wakeup_event]
|
||
mov ebx, [edi + SERVICE_ENTRY.hgcm_wakeup_event_id]
|
||
xor edx, edx
|
||
xor esi, esi
|
||
invoke RaiseEvent
|
||
|
||
.next:
|
||
add edi, sizeof.SERVICE_ENTRY
|
||
dec ecx
|
||
jnz .loop
|
||
|
||
.done:
|
||
pop edi esi edx ecx ebx eax
|
||
ret
|
||
endp
|
||
|
||
; vmmdev_irq_install — Установить обработчик IRQ
|
||
proc vmmdev_irq_install
|
||
mov eax, [vbox_device.irq]
|
||
test eax, eax
|
||
jz .no_irq
|
||
|
||
DEBUGF 2, "[VBoxGuest] [IRQ] Attaching to IRQ %d\n", eax
|
||
|
||
invoke AttachIntHandler, eax, vbox_irq_handler, 0
|
||
test eax, eax
|
||
jz .failed
|
||
|
||
DEBUGF 2, "[VBoxGuest] [IRQ] Handler attached successfully\n"
|
||
xor eax, eax
|
||
ret
|
||
|
||
.no_irq:
|
||
DEBUGF 2, "[VBoxGuest] [IRQ] No IRQ line\n"
|
||
mov eax, VERR_GENERAL_FAILURE
|
||
ret
|
||
|
||
.failed:
|
||
DEBUGF 2, "[VBoxGuest] [IRQ] Attach failed\n"
|
||
mov eax, VERR_INTERNAL_ERROR
|
||
ret
|
||
endp
|
||
|