예제 #1
0
/**
* 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.
     */
}
예제 #2
0
/**
* 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.
	 */
}