Esempio n. 1
0
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);
    }
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
// 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();
	}
}
Esempio n. 4
0
// 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);
	}
}
Esempio n. 7
0
// 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);
	}
}
Esempio n. 9
0
/**
*
* 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;
		}
	}
}
Esempio n. 10
0
/**
*
* 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
	}
}
Esempio n. 11
0
/**
*
* 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;
		}
	}
}
Esempio n. 12
0
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;
		}
	}
}