I am trying to write a serial port VxD. I think I am doing what supposed to be done, yet the interrupt service routine never runs.
Maybe someone can see what I am doing wrong or missed. All this is in a Vxd that does run. I have it send msgbox's at various points to see where its at.
Here's where I build the IRQ_Descriptor
lea edi, VP_Data
assume edi:ptr VPICD_IRQ_Descriptor
mov eax, 04H ;<- IRQ4 for COM1
mov .VID_IRQ_Number, word ptr ax
mov eax, VPICD_OPT_CAN_SHARE
mov .VID_Options, word ptr ax
mov eax, OFFSET32 IRQ4
mov .VID_Hw_Int_Proc, dword ptr eax
mov eax, 0H
mov .VID_Virt_Int_Proc, dword ptr eax
mov eax, 0H
mov .VID_EOI_Proc, dword ptr eax
mov eax, 0H
mov .VID_Mask_Change_Proc, dword ptr eax
mov eax, 0H
mov .VID_IRET_Proc, dword ptr eax
mov eax, 100
mov .VID_IRET_Time_Out, dword ptr eax
mov eax, 0H
mov .VID_Hw_Int_Ref, dword ptr eax
mov edi, OFFSET32 VP_Data
VxDcall VPICD_Virtualize_IRQ
or eax, eax
jz Virt_Error
mov , eax
here's where I unmask the interrupt (I think)
mov eax,
VxDcall VPICD_Physically_Unmask
here's where I trigger a interrupt
mov eax,
mov ebx,
VxDcall VPICD_Set_Int_Request
Last but not least, heres the interrupt handler
BeginProc IRQ4
cli
mov eax, 1H
mov , eax
mov eax,
VxDcall VPICD_Phys_EOI
sti
stc
ret
EndProc IRQ4
I could really use some help here, cause it's dead in the water.
Thanks,
sceptor
Maybe someone can see what I am doing wrong or missed. All this is in a Vxd that does run. I have it send msgbox's at various points to see where its at.
Here's where I build the IRQ_Descriptor
lea edi, VP_Data
assume edi:ptr VPICD_IRQ_Descriptor
mov eax, 04H ;<- IRQ4 for COM1
mov .VID_IRQ_Number, word ptr ax
mov eax, VPICD_OPT_CAN_SHARE
mov .VID_Options, word ptr ax
mov eax, OFFSET32 IRQ4
mov .VID_Hw_Int_Proc, dword ptr eax
mov eax, 0H
mov .VID_Virt_Int_Proc, dword ptr eax
mov eax, 0H
mov .VID_EOI_Proc, dword ptr eax
mov eax, 0H
mov .VID_Mask_Change_Proc, dword ptr eax
mov eax, 0H
mov .VID_IRET_Proc, dword ptr eax
mov eax, 100
mov .VID_IRET_Time_Out, dword ptr eax
mov eax, 0H
mov .VID_Hw_Int_Ref, dword ptr eax
mov edi, OFFSET32 VP_Data
VxDcall VPICD_Virtualize_IRQ
or eax, eax
jz Virt_Error
mov , eax
here's where I unmask the interrupt (I think)
mov eax,
VxDcall VPICD_Physically_Unmask
here's where I trigger a interrupt
mov eax,
mov ebx,
VxDcall VPICD_Set_Int_Request
Last but not least, heres the interrupt handler
BeginProc IRQ4
cli
mov eax, 1H
mov , eax
mov eax,
VxDcall VPICD_Phys_EOI
sti
stc
ret
EndProc IRQ4
I could really use some help here, cause it's dead in the water.
Thanks,
sceptor
Hi sceptor,
Interesting problem, just a couple of ideas, can you use VPICD_Get_Complete_Status and check the flags returned that the IRQ is actually physically unmasked, and that your interrupt is set?
;----------------------
mov eax, IRQHandle
mov ebx, VMHandle
VxDcall VPICD_Get_Complete_Status
mov , ecx
Retrieves the complete status for a virtual IRQ in a specified virtual machine. Uses ECX and Flags.
Returns a combination of these status flag values in ECX:
VPICD_STAT_PHYS_MASK The IRQ is physically masked
VPICD_STAT_PHYS_REQ The physical interrupt request has been set.
;----------------------
The other thing you should check if you already haven't, is if your interrupt handler should go in a locked code segment VxD_LOCKED_CODE_SEG, which ISR routines should generally be in. VPICD_Set_Int_Request simulates an interrupt in the virtual machine, but it may occur at a later time with VMMCall Simulate_Int, which waits for the VM to resume execution. Your VPICD_IRQ_Descriptor data needs to be safe.
I've never done any IRQ programming so I may be off base, but from looking at the docs and your code, do you develop your code by simulating an interrupt, and change this to handle the data input from the serial port (as triggered by a real hardware interrupt). Or do you detect an IRQ interrupt first with other code and simulate the interrupt as part of the calling procedure?
i.e. is VPICD_Set_Int_Request only used for development and debugging of your code, and this is a virtual interrupt, in which case your hook proc IRQ4 seems to be set in .VID_Hw_Int_Proc for a hardware interrupt.
VID_Hw_Int_Proc
Address of the callback procedure that handles hardware interrupts for this IRQ.
VID_Virt_Int_Proc
Address of the callback procedure that handles virtual interrupts for this IRQ.
I'm curious about the use of the VPICD_IRQ_Descriptor.VID_Options field. When would you use VPICD_OPT_VIRT_INT_REJECT as a flag?
VPICD_OPT_VIRT_INT_REJECT
Within your virtual interrupt procedure, set this bit and return with the carry flag set if you no longer want the interrupt virtualized.
When would you want to do this? When your code is ready for final use and you want to switch over to using VID_Hw_Int_Proc only instead of VID_Virt_Int_Proc?
There are a couple of other calls that seem associated with what you're doing that I wonder if you can't use:
;----------------------
VID_Virt_Int_Proc
include vpicd.inc
mov eax, IRQHandle
mov ebx, VMHandle
call VID_Virt_Int_Proc
Handles virtual interrupts for a virtual device. The system calls the procedure whenever a simulated interrupt occurs. The procedure is useful for implementing critical sections around a simulated hardware interrupt.
;----------------------
;----------------------
VPICD_Call_When_Hw_Int
include vpicd.inc
pushfd
cli
mov esi, OFFSET32 Callback
VxDcall VPICD_Call_When_Hw_Int
popfd
mov , esi
Installs a callback procedure for hardware interrupts. The system calls the callback procedure whenever a hardware interrupt occurs. The caller must disable interrupts before calling this service. Uses ESI and Flags.
;----------------------
Don't know if any of this helped.
Cheers,
Kayaker
Interesting problem, just a couple of ideas, can you use VPICD_Get_Complete_Status and check the flags returned that the IRQ is actually physically unmasked, and that your interrupt is set?
;----------------------
mov eax, IRQHandle
mov ebx, VMHandle
VxDcall VPICD_Get_Complete_Status
mov , ecx
Retrieves the complete status for a virtual IRQ in a specified virtual machine. Uses ECX and Flags.
Returns a combination of these status flag values in ECX:
VPICD_STAT_PHYS_MASK The IRQ is physically masked
VPICD_STAT_PHYS_REQ The physical interrupt request has been set.
;----------------------
The other thing you should check if you already haven't, is if your interrupt handler should go in a locked code segment VxD_LOCKED_CODE_SEG, which ISR routines should generally be in. VPICD_Set_Int_Request simulates an interrupt in the virtual machine, but it may occur at a later time with VMMCall Simulate_Int, which waits for the VM to resume execution. Your VPICD_IRQ_Descriptor data needs to be safe.
I've never done any IRQ programming so I may be off base, but from looking at the docs and your code, do you develop your code by simulating an interrupt, and change this to handle the data input from the serial port (as triggered by a real hardware interrupt). Or do you detect an IRQ interrupt first with other code and simulate the interrupt as part of the calling procedure?
i.e. is VPICD_Set_Int_Request only used for development and debugging of your code, and this is a virtual interrupt, in which case your hook proc IRQ4 seems to be set in .VID_Hw_Int_Proc for a hardware interrupt.
VID_Hw_Int_Proc
Address of the callback procedure that handles hardware interrupts for this IRQ.
VID_Virt_Int_Proc
Address of the callback procedure that handles virtual interrupts for this IRQ.
I'm curious about the use of the VPICD_IRQ_Descriptor.VID_Options field. When would you use VPICD_OPT_VIRT_INT_REJECT as a flag?
VPICD_OPT_VIRT_INT_REJECT
Within your virtual interrupt procedure, set this bit and return with the carry flag set if you no longer want the interrupt virtualized.
When would you want to do this? When your code is ready for final use and you want to switch over to using VID_Hw_Int_Proc only instead of VID_Virt_Int_Proc?
There are a couple of other calls that seem associated with what you're doing that I wonder if you can't use:
;----------------------
VID_Virt_Int_Proc
include vpicd.inc
mov eax, IRQHandle
mov ebx, VMHandle
call VID_Virt_Int_Proc
Handles virtual interrupts for a virtual device. The system calls the procedure whenever a simulated interrupt occurs. The procedure is useful for implementing critical sections around a simulated hardware interrupt.
;----------------------
;----------------------
VPICD_Call_When_Hw_Int
include vpicd.inc
pushfd
cli
mov esi, OFFSET32 Callback
VxDcall VPICD_Call_When_Hw_Int
popfd
mov , esi
Installs a callback procedure for hardware interrupts. The system calls the callback procedure whenever a hardware interrupt occurs. The caller must disable interrupts before calling this service. Uses ESI and Flags.
;----------------------
Don't know if any of this helped.
Cheers,
Kayaker