; ============================================================================= ; Модуль : 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