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 .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
mov eax, 1H
mov , eax
mov eax,
VxDcall VPICD_Phys_EOI

EndProc IRQ4

I could really use some help here, cause it's dead in the water.

Posted on 2002-06-14 17:17:56 by 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.

Address of the callback procedure that handles hardware interrupts for this IRQ.
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?

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:

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.

include vpicd.inc

mov esi, OFFSET32 Callback
VxDcall VPICD_Call_When_Hw_Int
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.

Posted on 2002-06-15 14:25:43 by Kayaker