PCI interrupts issues on x86 - code snippets included

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



Thanks in advance for any help with this issue! I'm going nuts.

Target platform - x86, ETX formfactor
Using WinCE 5.0, Platform Builder for WinCE 5.0
BSP supplied from target manufacturer

I have debugged enough to know that the hardware is triggering the hardware
interrupt. The hardware interrupt is INTA on the PCI bus. I also know that
what I've done so far seems to be working (I have manually triggered the
event I have associated with the system interrupt and my IST operates as
expected). I have looked at the registry and the instance key reports that
my driver is using system interrupt 32(0x20). I also print out the system
interrupt when I grab it from DDKReg_GetIsrInfo and verified it matches.
The physical interrupt reported when I looked at the registry is IRQ 11.

I'm assuming the BSP/OAL layers will properly trigger my IST event when the
hardware interrupt is triggered. From what I've read in the Microsoft Help
Pages, a properly designed OAL is responsible for setting up the ISRs that
will tie the hardware interrupts (IRQs) to logical system interrupts. In my
mind, the mapping in my case, should be:
INTA-->IRQ11-->system interrupt 32
This is what does not seem to be working. I'm also not getting very much
help from the manufacturer. However, I want to make certain that I'm doing
stuff correctly on the driver side.

I've taken out all debug messages, error handling and in the case of the
interrupt thread, I've boiled it down to what I consider useful for
investigation.
******************************Snippets**********************************

Save the interrupt information gotten with DDKReg_GetIsrInfo:
pDrvInfo->sysInterrupt = intInformation.dwSysintr;


Tie the system interrupt to my thread:
pDrvInfo->hIstEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
boolStatus = InterruptInitialize(pDrvInfo->sysInterrupt,
pDrvInfo->hIstEvent, NULL, 0);
pDrvInfo->hIst = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)DCB_Interrupt_Thread, (LPVOID)pDrvInfo, 0,
&threadID);


Turn on the PCI interrupts:
WRITE_REGISTER_ULONG(((PULONG)(pDrvInfo->memCnfgMappedBase.pVirtualAddress +
INTERRUPT_CONTROL_STATUS_REGISTER)),
(ULONG)(PCI_INTERRUPT_ENABLE |
PCI_DOORBELL_INTERRUPT_ENABLE));


Writing the cmd generates the interrupt.
WRITE_PORT_USHORT((PUSHORT)(pDrvInfo->ioMappedBase.pVirtualAddress +
COMMAND_REGISTER_OFFSET), cmd);
waitForSingleObjectStatus = WaitForSingleObject(pDrvInfo->hDoorbellEvent,
WAIT_10_MSEC);


DWORD DCB_Interrupt_Thread(LPVOID pDeviceContext)
{
InterruptDone(pDrvInfo->sysInterrupt);
for(;;)
{
WaitForSingleObject(pDrvInfo->hIstEvent, INFINITE);

DEBUGMSG(1, (TEXT("DCB_Interrupt_Thread: Interrupt occured.\n\r")));

/* Indicate to OS that we are done. */
InterruptDone(pDrvInfo->sysInterrupt);
}

return(0);
}



.



Relevant Pages