/** * This function is the primary interrupt handler for the driver. It must be * connected to the interrupt source such that it is called when an interrupt of * the interrupt controller is active. It will resolve which interrupts are * active and enabled and call the appropriate interrupt handler. It uses * the Interrupt Type information to determine when to acknowledge the interrupt. * Highest priority interrupts are serviced first. * * This function assumes that an interrupt vector table has been previously * initialized. It does not verify that entries in the table are valid before * calling an interrupt handler. * * * @param InstancePtr is a pointer to the XScuGic instance. * * @return None. * * @note None. * ******************************************************************************/ void XScuGic_InterruptHandler(XScuGic *InstancePtr) { u32 InterruptID; u32 IntIDFull; XScuGic_VectorTableEntry *TablePtr; /* Assert that the pointer to the instance is valid */ Xil_AssertVoid(InstancePtr != NULL); /* * Read the int_ack register to identify the highest priority interrupt ID * and make sure it is valid. Reading Int_Ack will clear the interrupt * in the GIC. */ IntIDFull = XScuGic_CPUReadReg(InstancePtr, XSCUGIC_INT_ACK_OFFSET); InterruptID = IntIDFull & XSCUGIC_ACK_INTID_MASK; if(XSCUGIC_MAX_NUM_INTR_INPUTS < InterruptID){ goto IntrExit; } /* * If the interrupt is shared, do some locking here if there are multiple * processors. */ /* * If pre-eption is required: * Re-enable pre-emption by setting the CPSR I bit for non-secure , * interrupts or the F bit for secure interrupts */ /* * If we need to change security domains, issue a SMC instruction here. */ /* * Execute the ISR. Jump into the Interrupt service routine based on the * IRQSource. A software trigger is cleared by the ACK. */ TablePtr = &(InstancePtr->Config->HandlerTable[InterruptID]); if(TablePtr != NULL) { TablePtr->Handler(TablePtr->CallBackRef); } IntrExit: /* * Write to the EOI register, we are all done here. * Let this function return, the boot code will restore the stack. */ XScuGic_CPUWriteReg(InstancePtr, XSCUGIC_EOI_OFFSET, IntIDFull); /* * Return from the interrupt. Change security domains could happen here. */ }
/** * This function is the primary interrupt handler for the driver. It must be * connected to the interrupt source such that it is called when an interrupt of * the interrupt controller is active. It will resolve which interrupts are * active and enabled and call the appropriate interrupt handler. It uses * the Interrupt Type information to determine when to acknowledge the * interrupt.Highest priority interrupts are serviced first. * * This function assumes that an interrupt vector table has been previously * initialized. It does not verify that entries in the table are valid before * calling an interrupt handler. * * @param DeviceId is the unique identifier for the ScuGic device. * * @return None. * * @note None. * ******************************************************************************/ void XScuGic_DeviceInterruptHandler(void *DeviceId) { u32 IntID; XScuGic_VectorTableEntry *TablePtr; XScuGic_Config *CfgPtr; CfgPtr = &XScuGic_ConfigTable[(u32 )DeviceId]; /* * Read the int_ack register to identify the highest priority * interrupt ID and make sure it is valid. Reading Int_Ack will * clear the interrupt in the GIC. */ IntID = XScuGic_ReadReg(CfgPtr->CpuBaseAddress, XSCUGIC_INT_ACK_OFFSET) & XSCUGIC_ACK_INTID_MASK; if(XSCUGIC_MAX_NUM_INTR_INPUTS < IntID){ goto IntrExit; } /* * If the interrupt is shared, do some locking here if there are * multiple processors. */ /* * If pre-eption is required: * Re-enable pre-emption by setting the CPSR I bit for non-secure , * interrupts or the F bit for secure interrupts */ /* * If we need to change security domains, issue a SMC instruction here. */ /* * Execute the ISR. Jump into the Interrupt service routine based on * the IRQSource. A software trigger is cleared by the ACK. */ TablePtr = &(CfgPtr->HandlerTable[IntID]); TablePtr->Handler(TablePtr->CallBackRef); IntrExit: /* * Write to the EOI register, we are all done here. * Let this function return, the boot code will restore the stack. */ XScuGic_WriteReg(CfgPtr->CpuBaseAddress, XSCUGIC_EOI_OFFSET, IntID); /* * Return from the interrupt. Change security domains could happen * here. */ }