/** * 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. */ }
void zynqMP_r5_irq_isr() { unsigned int raw_irq; int irq_vector; raw_irq = (unsigned int)XScuGic_CPUReadReg(&InterruptController,XSCUGIC_INT_ACK_OFFSET); irq_vector = (int) (raw_irq & XSCUGIC_ACK_INTID_MASK); bm_env_isr(irq_vector); XScuGic_CPUWriteReg(&InterruptController,XSCUGIC_EOI_OFFSET, raw_irq); }