void interrupt_handler_dispatcher(void* ptr) { // Ask the Interrupt Controller for a status of its interrupts uint32_t status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check what triggered the interrupt if (status & XPAR_FIT_TIMER_0_INTERRUPT_MASK) { // Let the timer know it got an interrupt! if (interrupts_timer_handler) interrupts_timer_handler(); // Then acknowledge it so it can interrupt again XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); } else if (status & XPAR_PIT_0_MYINTERRUPT_MASK) { if (interrupts_timer_handler) interrupts_timer_handler(); // Then acknowledge it so it can interrupt again XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PIT_0_MYINTERRUPT_MASK); } else if (status & XPAR_AXI_AC97_0_INTERRUPT_MASK) { // Let the audio controller know we got an interrupt! if (interrupts_audio_handler) interrupts_audio_handler(); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); } else if (status & XPAR_DMA_CTRL_0_INTERRUPT_MASK) { if (interrupts_dma_handler) interrupts_dma_handler(); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_DMA_CTRL_0_INTERRUPT_MASK); } }
void sound_interrupt_handler(void* ptr) { int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check the FIT interrupt first. if (intc_status & XPAR_AXI_AC97_0_INTERRUPT_MASK) { sound_writeToFifo(100); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); } else xil_printf("Unknown interupt: %x\n\r", intc_status); }
// Main interrupt handler, queries the interrupt controller to see what peripheral // fired the interrupt and then dispatches the corresponding interrupt handler. // This routine acks the interrupt at the controller level but the peripheral // interrupt must be ack'd by the dispatched interrupt handler. void interrupt_handler_dispatcher(void* ptr) { int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check the FIT interrupt first. if (intc_status & XPAR_FIT_TIMER_0_INTERRUPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); timer_interrupt_handler(); } // Check the push buttons. if (intc_status & XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK); pb_interrupt_handler(); } }
// Main interrupt handler, queries the interrupt controller to see what peripheral // fired the interrupt and then dispatches the corresponding interrupt handler. // This routine acks the interrupt at the controller level but the peripheral // interrupt must be ack'd by the dispatched interrupt handler. void interrupt_handler_dispatcher(void* ptr) { // /* Reset the timers, and clear interrupts */ // XTmrCtr_mSetControlStatusReg(XPAR_DELAY_BASEADDR, 0, XTC_CSR_INT_OCCURED_MASK | // XTC_CSR_LOAD_MASK ); // // /* Enable timer interrupts in the interrupt controller */ // XIntc_mEnableIntr(XPAR_DELAY_BASEADDR, XPAR_DELAY_INTERRUPT_MASK); // // /* Start the timers */ // XTmrCtr_mSetControlStatusReg(XPAR_DELAY_BASEADDR, 0, XTC_CSR_ENABLE_TMR_MASK | // XTC_CSR_ENABLE_INT_MASK | XTC_CSR_AUTO_RELOAD_MASK | // XTC_CSR_DOWN_COUNT_MASK); int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check the FIT interrupt first. if (intc_status & XPAR_FIT_TIMER_0_INTERRUPT_MASK) // add pit timer here { //xil_printf("fit timer\r\n"); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); timer_interrupt_handler(); } if (intc_status & XPAR_AXI_AC97_0_INTERRUPT_MASK) { // if(XAC97_isInFIFOFull(XPAR_AXI_AC97_0_BASEADDR)) // xil_printf("buffer is full why are you interrupting????\r\n"); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); audio_interrupt_handler(); } if(intc_status & XPAR_DMA_0_INTERRUPT_MASK) { XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_DMA_0_INTERRUPT_MASK); } }
// Main interrupt handler, queries the interrupt controller to see what peripheral // fired the interrupt and then dispatches the corresponding interrupt handler. // This routine acks the interrupt at the controller level but the peripheral // interrupt must be ack'd by the dispatched interrupt handler. void interrupt_handler_dispatcher(void* ptr) { static int boolPrintedFIT = 0; int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); //Check the PS2 Interrupt first if (intc_status & XPAR_FIT_TIMER_0_INTERRUPT_MASK) { XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); if(!boolPrintedFIT) { xil_printf("FIT Timer Interrupt\n\r"); boolPrintedFIT = 1; } } if (intc_status & XPAR_DMA_CONTROLLER_0_INTERRUPT_MASK) { XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_DMA_CONTROLLER_0_INTERRUPT_MASK); printf("DMA Interrupt\n\r"); } }
// Main interrupt handler, queries the interrupt controller to see what peripheral // fired the interrupt and then dispatches the corresponding interrupt handler. // This routine acks the interrupt at the controller level but the peripheral // interrupt must be ack'd by the dispatched interrupt handler. void interrupt_handler_dispatcher(void* ptr) { int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); //Check the PS2 Interrupt first if (intc_status & XPAR_PS2CTRL_0_INTERRUPT_MASK) { mouse_stateMachine(mouse_ps2ctrlReadValue()); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PS2CTRL_0_INTERRUPT_MASK); } if (intc_status & XPAR_PIT_0_INTERRUPT_MASK) { low_priority_intc_status = low_priority_intc_status | XPAR_PIT_0_INTERRUPT_MASK; XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PIT_0_INTERRUPT_MASK); } if (intc_status & XPAR_AXI_AC97_0_INTERRUPT_MASK) { low_priority_intc_status = low_priority_intc_status | XPAR_AXI_AC97_0_INTERRUPT_MASK; XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); } }
// Main interrupt handler, queries the interrupt controller to see what peripheral // fired the interrupt and then dispatches the corresponding interrupt handler. // This routine acks the interrupt at the controller level but the peripheral // interrupt must be ack'd by the dispatched interrupt handler. void interrupt_handler_dispatcher(void* ptr) { int intc_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check the FIT interrupt first. if (intc_status & XPAR_FIT_TIMER_0_INTERRUPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); timer_interrupt_handler(); } //xil_printf("intc_status: %d\n\r", intc_status); if (intc_status & XPAR_PIT3_0_PIT_INTERRUPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PIT3_0_PIT_INTERRUPT_MASK); timer_interrupt_handler(); } // Check the push buttons. if (intc_status & XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK); pb_interrupt_handler(); } if (intc_status & XPAR_AXI_AC97_0_INTERRUPT_MASK){ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); sound_interrupt_handler(); } }
void interrupt_handler_dispatcher(void* ptr) { // Ask the Interrupt Controller for a status of its interrupts uint32_t status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); // Check what triggered the interrupt if (status & XPAR_FIT_TIMER_0_INTERRUPT_MASK) { // Let the timer know it got an interrupt! // if (interrupts_timer_handler) interrupts_timer_handler(); // Then acknowledge it so it can interrupt again XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_FIT_TIMER_0_INTERRUPT_MASK); } else if (status & XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK) { // ---------- // Turn off all PB interrupts for now. XGpio_InterruptGlobalDisable(&gpPB); u32 currentButtonState = XGpio_DiscreteRead(&gpPB, 1); pb_interrupt_handler(currentButtonState); // XAC97_PlayAudio(XPAR_AXI_AC97_0_BASEADDR, sound_alienMove2.data, &sound_alienMove2.data[sound_alienMove2.numSamples]); // Ack the PB interrupt. XGpio_InterruptClear(&gpPB, 0xFFFFFFFF); // Re-enable PB interrupts. XGpio_InterruptGlobalEnable(&gpPB); // ------ XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_PUSH_BUTTONS_5BITS_IP2INTC_IRPT_MASK); } else if (status & XPAR_AXI_AC97_0_INTERRUPT_MASK) { fifo_interrupt_handler(); XIntc_AckIntr(XPAR_INTC_0_BASEADDR, XPAR_AXI_AC97_0_INTERRUPT_MASK); } }
/** * * This function is called by primary interrupt handler for the driver to handle * all Controllers in Cascade mode.It will resolve which interrupts are active * and enabled and call the appropriate interrupt handler. It uses the * AckBeforeService flag in the configuration data 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.This function calls itself recursively to handle * all interrupt controllers. * * @param DeviceId is the zero-based device ID defined in xparameters.h * of the interrupting interrupt controller. It is used as a direct * index into the configuration data, which contains the vector * table for the interrupt controller. * * @return None. * * @note * ******************************************************************************/ static void XIntc_CascadeHandler(void *DeviceId) { u32 IntrStatus; u32 IntrMask = 1; int IntrNumber; u32 Imr; XIntc_Config *CfgPtr; static int Id = 0; /* Get the configuration data using the device ID */ CfgPtr = &XIntc_ConfigTable[(u32)DeviceId]; /* Get the interrupts that are waiting to be serviced */ IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* Mask the Fast Interrupts */ if (CfgPtr->FastIntr == TRUE) { Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET); IntrStatus &= ~Imr; } /* Service each interrupt that is active and enabled by * checking each bit in the register from LSB to MSB which * corresponds to an interrupt input signal */ for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs; IntrNumber++) { if (IntrStatus & 1) { XIntc_VectorTableEntry *TablePtr; /* In Cascade mode call this function recursively * for interrupt id 31 and until interrupts of last * instance/controller are handled */ if ((IntrNumber == 31) && (CfgPtr->IntcType != XIN_INTC_LAST) && (CfgPtr->IntcType != XIN_INTC_NOCASCADE)) { XIntc_CascadeHandler((void *)++Id); Id--; } /* If the interrupt has been setup to * acknowledge it before servicing the * interrupt, then ack it */ if (CfgPtr->AckBeforeService & IntrMask) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } /* Handler of 31 interrupt Id has to be called only * for Last controller in cascade Mode */ if (!((IntrNumber == 31) && (CfgPtr->IntcType != XIN_INTC_LAST) && (CfgPtr->IntcType != XIN_INTC_NOCASCADE))) { /* The interrupt is active and enabled, call * the interrupt handler that was setup with * the specified parameter */ TablePtr = &(CfgPtr->HandlerTable[IntrNumber]); TablePtr->Handler(TablePtr->CallBackRef); } /* If the interrupt has been setup to acknowledge it * after it has been serviced then ack it */ if ((CfgPtr->AckBeforeService & IntrMask) == 0) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } /* * Read the ISR again to handle architectures with * posted write bus access issues. */ XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* * If only the highest priority interrupt is to be * serviced, exit loop and return after servicing * the interrupt */ if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) { return; } } /* Move to the next interrupt to check */ IntrMask <<= 1; IntrStatus >>= 1; /* If there are no other bits set indicating that all interrupts * have been serviced, then exit the loop */ if (IntrStatus == 0) { break; } } }
/** * * This function is the primary interrupt handler for the driver. It must be * connected to the interrupt source such that 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 AckBeforeService flag in the configuration data 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. In Cascade mode this function calls * XIntc_CascadeHandler to handle interrupts of Master and Slave controllers. * This functions also handles interrupts nesting by saving and restoring link * register of Microblaze and Interrupt Level register of interrupt controller * properly. * @param DeviceId is the zero-based device ID defined in xparameters.h * of the interrupting interrupt controller. It is used as a direct * index into the configuration data, which contains the vector * table for the interrupt controller. Note that even though the * argument is a void pointer, the value is not a pointer but the * actual device ID. The void pointer type is necessary to meet * the XInterruptHandler typedef for interrupt handlers. * * @return None. * * @note For nested interrupts, this function saves microblaze r14 * register on entry and restores on exit. This is required since * compiler does not support nesting. This function enables * Microblaze interrupts after blocking further interrupts * from the current interrupt number and interrupts below current * interrupt proirity by writing to Interrupt Level Register of * INTC on entry. On exit, it disables microblaze interrupts and * restores ILR register default value(0xFFFFFFFF)back. It is * recommended to increase STACK_SIZE in linker script for nested * interrupts. * ******************************************************************************/ void XIntc_DeviceInterruptHandler(void *DeviceId) { u32 IntrStatus; u32 IntrMask = 1; int IntrNumber; XIntc_Config *CfgPtr; u32 Imr; /* Get the configuration data using the device ID */ CfgPtr = &XIntc_ConfigTable[(u32)DeviceId]; #if XPAR_INTC_0_INTC_TYPE != XIN_INTC_NOCASCADE if (CfgPtr->IntcType != XIN_INTC_NOCASCADE) { XIntc_CascadeHandler(DeviceId); } else #endif { /* This extra brace is required for compilation in Cascade Mode */ #if XPAR_XINTC_HAS_ILR == TRUE #ifdef __MICROBLAZE__ volatile u32 R14_register; /* Save r14 register */ R14_register = mfgpr(r14); #endif volatile u32 ILR_reg; /* Save ILR register */ ILR_reg = Xil_In32(CfgPtr->BaseAddress + XIN_ILR_OFFSET); #endif /* Get the interrupts that are waiting to be serviced */ IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* Mask the Fast Interrupts */ if (CfgPtr->FastIntr == TRUE) { Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET); IntrStatus &= ~Imr; } /* Service each interrupt that is active and enabled by * checking each bit in the register from LSB to MSB which * corresponds to an interrupt input signal */ for (IntrNumber = 0; IntrNumber < CfgPtr->NumberofIntrs; IntrNumber++) { if (IntrStatus & 1) { XIntc_VectorTableEntry *TablePtr; #if XPAR_XINTC_HAS_ILR == TRUE /* Write to ILR the current interrupt * number */ Xil_Out32(CfgPtr->BaseAddress + XIN_ILR_OFFSET, IntrNumber); /* Read back ILR to ensure the value * has been updated and it is safe to * enable interrupts */ Xil_In32(CfgPtr->BaseAddress + XIN_ILR_OFFSET); /* Enable interrupts */ Xil_ExceptionEnable(); #endif /* If the interrupt has been setup to * acknowledge it before servicing the * interrupt, then ack it */ if (CfgPtr->AckBeforeService & IntrMask) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } /* The interrupt is active and enabled, call * the interrupt handler that was setup with * the specified parameter */ TablePtr = &(CfgPtr->HandlerTable[IntrNumber]); TablePtr->Handler(TablePtr->CallBackRef); /* If the interrupt has been setup to * acknowledge it after it has been serviced * then ack it */ if ((CfgPtr->AckBeforeService & IntrMask) == 0) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } #if XPAR_XINTC_HAS_ILR == TRUE /* Disable interrupts */ Xil_ExceptionDisable(); /* Restore ILR */ Xil_Out32(CfgPtr->BaseAddress + XIN_ILR_OFFSET, ILR_reg); #endif /* * Read the ISR again to handle architectures * with posted write bus access issues. */ XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* * If only the highest priority interrupt is to * be serviced, exit loop and return after * servicing * the interrupt */ if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) { #if XPAR_XINTC_HAS_ILR == TRUE #ifdef __MICROBLAZE__ /* Restore r14 */ mtgpr(r14, R14_register); #endif #endif return; } } /* Move to the next interrupt to check */ IntrMask <<= 1; IntrStatus >>= 1; /* If there are no other bits set indicating that all * interrupts have been serviced, then exit the loop */ if (IntrStatus == 0) { break; } } #if XPAR_XINTC_HAS_ILR == TRUE #ifdef __MICROBLAZE__ /* Restore r14 */ mtgpr(r14, R14_register); #endif #endif } }
/** * * This function is the primary interrupt handler for the driver. It must be * connected to the interrupt source such that 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 AckBeforeService flag in the configuration data to determine when to * acknowledge the interrupt. Highest priority interrupts are serviced first. * The driver can be configured to service only the highest priority interrupt * or all pending interrupts using the {XIntc_SetOptions()} function or * the {XIntc_SetIntrSrvOption()} function. * * 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 zero-based device ID defined in xparameters.h * of the interrupting interrupt controller. It is used as a direct * index into the configuration data, which contains the vector * table for the interrupt controller. Note that even though the * argument is a void pointer, the value is not a pointer but the * actual device ID. The void pointer type is necessary to meet * the XInterruptHandler typedef for interrupt handlers. * * @return None. * * @note * * The constant XPAR_INTC_MAX_NUM_INTR_INPUTS must be setup for this to compile. * Interrupt IDs range from 0 - 31 and correspond to the interrupt input signals * for the interrupt controller. XPAR_INTC_MAX_NUM_INTR_INPUTS specifies the * highest numbered interrupt input signal that is used. * ******************************************************************************/ void XIntc_DeviceInterruptHandler(void *DeviceId) { u32 IntrStatus; u32 IntrMask = 1; int IntrNumber; XIntc_Config *CfgPtr; u32 Imr; /* Get the configuration data using the device ID */ CfgPtr = &XIntc_ConfigTable[(u32) DeviceId]; /* Get the interrupts that are waiting to be serviced */ IntrStatus = XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* Mask the Fast Interrupts */ if (CfgPtr->FastIntr == TRUE) { Imr = XIntc_In32(CfgPtr->BaseAddress + XIN_IMR_OFFSET); IntrStatus &= ~Imr; } /* Service each interrupt that is active and enabled by checking each * bit in the register from LSB to MSB which corresponds to an interrupt * intput signal */ for (IntrNumber = 0; IntrNumber < XPAR_INTC_MAX_NUM_INTR_INPUTS; IntrNumber++) { if (IntrStatus & 1) { XIntc_VectorTableEntry *TablePtr; /* If the interrupt has been setup to acknowledge it * before servicing the interrupt, then ack it */ if (CfgPtr->AckBeforeService & IntrMask) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } /* The interrupt is active and enabled, call the * interrupt handler that was setup with the specified * parameter */ TablePtr = &(CfgPtr->HandlerTable[IntrNumber]); TablePtr->Handler(TablePtr->CallBackRef); /* If the interrupt has been setup to acknowledge it * after it has been serviced then ack it */ if ((CfgPtr->AckBeforeService & IntrMask) == 0) { XIntc_AckIntr(CfgPtr->BaseAddress, IntrMask); } /* * Read the ISR again to handle architectures with posted write * bus access issues. */ XIntc_GetIntrStatus(CfgPtr->BaseAddress); /* * If only the highest priority interrupt is to be * serviced, exit loop and return after servicing * the interrupt */ if (CfgPtr->Options == XIN_SVC_SGL_ISR_OPTION) { return; } } /* Move to the next interrupt to check */ IntrMask <<= 1; IntrStatus >>= 1; /* If there are no other bits set indicating that all interrupts * have been serviced, then exit the loop */ if (IntrStatus == 0) { break; } } }
void rt_hw_trap_irq(void ) { u32 intr_status; u32 intr_mask = 1; int intr_number; volatile u32 reg; /* used as bit bucket */ XIntc_Config *cfg_ptr; /* Get the configuration data using the device ID */ cfg_ptr = &XIntc_ConfigTable[0]; /* Get the interrupts that are waiting to be serviced */ intr_status = XIntc_GetIntrStatus(XPAR_INTC_0_BASEADDR); /* Service each interrupt that is active and enabled by checking each * bit in the register from LSB to MSB which corresponds to an interrupt * intput signal */ for (intr_number = 0; intr_number < XPAR_INTC_MAX_NUM_INTR_INPUTS; intr_number++) { if (intr_status & 1) { XIntc_VectorTableEntry *table_ptr; /* If the interrupt has been setup to acknowledge it * before servicing the interrupt, then ack it */ if (cfg_ptr->AckBeforeService & intr_mask) { XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask); } /* The interrupt is active and enabled, call the * interrupt handler that was setup with the specified * parameter */ table_ptr = &(cfg_ptr->HandlerTable[intr_number]); table_ptr->Handler(table_ptr->CallBackRef); /* If the interrupt has been setup to acknowledge it * after it has been serviced then ack it */ if ((cfg_ptr->AckBeforeService & intr_mask) == 0) { XIntc_AckIntr(cfg_ptr->BaseAddress, intr_mask); } /* * Read the ISR again to handle architectures with posted write * bus access issues. */ reg = XIntc_GetIntrStatus(cfg_ptr->BaseAddress); /* * If only the highest priority interrupt is to be * serviced, exit loop and return after servicing * the interrupt */ if (cfg_ptr->Options == XIN_SVC_SGL_ISR_OPTION) { return; } } /* Move to the next interrupt to check */ intr_mask <<= 1; intr_status >>= 1; /* If there are no other bits set indicating that all interrupts * have been serviced, then exit the loop */ if (intr_status == 0) { break; } } }