If cpu1 sends more than one soft interrupt to itself, the driver acknowledge only the first interrupt.
The second one is pending.
The root cause of this behavior is the write operation of register ICCEOIR in XScuGic_InterruptHandler().
It should be written with the full value of ICCIAR.
Here is the original driver:
void XScuGic_InterruptHandler(XScuGic *InstancePtr)
{
u32 IntID;
XScuGic_VectorTableEntry *TablePtr;
Xil_AssertVoid(InstancePtr != NULL);
IntID = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET) &
XSCUGIC_ACK_INTID_MASK;
if(XSCUGIC_MAX_NUM_INTR_INPUTS < IntID){
goto IntrExit;
}
TablePtr = &(InstancePtr->Config->HandlerTable[IntID]);
TablePtr->Handler(TablePtr->CallBackRef);
IntrExit:
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntID);
}
void XScuGic_InterruptHandler1(XScuGic *InstancePtr)
{
u32 IntID;
u32 IntIDFull;
XScuGic_VectorTableEntry *TablePtr;
Xil_AssertVoid(InstancePtr != NULL);
IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET);
IntID = IntIDFull & XSCUGIC_ACK_INTID_MASK;
if(XSCUGIC_MAX_NUM_INTR_INPUTS < IntID){
goto IntrExit;
}
TablePtr = &(InstancePtr->Config->HandlerTable[IntID]);
TablePtr->Handler(TablePtr->CallBackRef);
IntrExit:
XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull);
}
AR# 53563 | |
---|---|
Date | 05/19/2014 |
Status | Active |
Type | General Article |
Devices | |
Tools |