Exemplo n.º 1
0
/**
*
* Register a fast handler function for a specific interrupt ID. The handler
* function will be called when an interrupt occurs for the given interrupt ID.
*
* @param 	BaseAddress is the base address of the interrupt controller
*		whose vector table will be modified.
* @param 	InterruptId is the interrupt ID to be associated with the input
*		handler.
* @param 	FastHandler is the function pointer that will be called when
*   		interrupt occurs
*
* @return	None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id,
					XFastInterruptHandler FastHandler)
{
	u32 CurrentIER;
	u32 Mask;
	u32 Imr;

	CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);

	/* Convert from integer id to bit mask */
	Mask = XIntc_BitPosMask[Id];

	if (CurrentIER & Mask) {
		/* Disable Interrupt if it was enabled */
		CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
		XIntc_Out32(BaseAddress + XIN_IER_OFFSET,(CurrentIER & ~Mask));
	}

	XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4),
				    	(u32) FastHandler);

	Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET);
	XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask);


	/* Enable Interrupt if it was enabled before calling this function */
	if (CurrentIER & Mask) {
		CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
		XIntc_Out32(BaseAddress + XIN_IER_OFFSET,(CurrentIER | Mask));
	}

}
Exemplo n.º 2
0
/**
*
* Updates the interrupt table with the Null Handler and NULL arguments at the
* location pointed at by the Id. This effectively disconnects that interrupt
* source from any handler. The interrupt is disabled also. In Cascade mode,
* disconnects handler from Slave controller handler table depending on the
* interrupt Id.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being
*		the highest priority interrupt.
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void XIntc_Disconnect(XIntc * InstancePtr, u8 Id)
{
	u32 CurrentIER;
	u32 Mask;
	XIntc_Config *CfgPtr;

	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Disable the interrupt such that it won't occur while disconnecting
	 * the handler, only disable the specified interrupt id without
	 * modifying the other interrupt ids
	 */

	/* Disconnect Handlers for Slave controllers in Cascade Mode */
	if (Id > 31) {

		CfgPtr = XIntc_LookupConfig(Id/32);

		CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[(Id%32)];

		XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
		    			(CurrentIER & ~Mask));
		/*
		 * Disconnect the handler and connect a stub, the callback
		 * reference must be set to this instance to allow unhandled
		 * interrupts to be tracked
		 */
		CfgPtr->HandlerTable[Id%32].Handler = StubHandler;
		CfgPtr->HandlerTable[Id%32].CallBackRef = InstancePtr;
	}
	/* Disconnect Handlers for Master/primary controller */
	else {
		CurrentIER = XIntc_In32(InstancePtr->BaseAddress +
							XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[Id];

		XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
		    			(CurrentIER & ~Mask));
		InstancePtr->CfgPtr->HandlerTable[Id%32].Handler =
								StubHandler;
		InstancePtr->CfgPtr->HandlerTable[Id%32].CallBackRef =
								InstancePtr;
	}

}
Exemplo n.º 3
0
/**
*
* Disables the interrupt source provided as the argument Id such that the
* interrupt controller will not cause interrupts for the specified Id. The
* interrupt controller will continue to hold an interrupt condition for the
* Id, but will not cause an interrupt.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the
*		highest priority interrupt.
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void XIntc_Disable(XIntc * InstancePtr, u8 Id)
{
	u32 CurrentIER;
	u32 Mask;

	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * The Id is used to create the appropriate mask for the
	 * desired bit position. Id currently limited to 0 - 31
	 */
	Mask = XIntc_BitPosMask[Id];

	/*
	 * Disable the selected interrupt source by reading the interrupt enable
	 * register and then modifying only the specified interrupt id
	 */
	CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET);
	XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
		    (CurrentIER & ~Mask));
}
Exemplo n.º 4
0
/**
*
* Updates the interrupt table with the Null Handler and NULL arguments at the
* location pointed at by the Id. This effectively disconnects that interrupt
* source from any handler. The interrupt is disabled also.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the
*		highest priority interrupt.
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void XIntc_Disconnect(XIntc * InstancePtr, u8 Id)
{
	u32 CurrentIER;
	u32 Mask;

	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	/*
	 * Disable the interrupt such that it won't occur while disconnecting
	 * the handler, only disable the specified interrupt id without
	 * modifying the other interrupt ids
	 */
	CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET);

	Mask = XIntc_BitPosMask[Id];/* convert from integer id to bit mask */

	XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
		    (CurrentIER & ~Mask));

	/*
	 * Disconnect the handler and connect a stub, the callback reference
	 * must be set to this instance to allow unhandled interrupts to be
	 * tracked
	 */
	InstancePtr->CfgPtr->HandlerTable[Id].Handler = StubHandler;
	InstancePtr->CfgPtr->HandlerTable[Id].CallBackRef = InstancePtr;
}
Exemplo n.º 5
0
XStatus
init_ll_fifo(struct xemac_s *xemac)
{
    xlltemacif_s *xlltemacif = (xlltemacif_s *)(xemac->state);
#if NO_SYS
    struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif

    /* initialize ll fifo */
    XLlFifo_Initialize(&xlltemacif->llfifo,
                       XLlTemac_LlDevBaseAddress(&xlltemacif->lltemac));

    /* Clear any pending FIFO interrupts */
    XLlFifo_IntClear(&xlltemacif->llfifo, XLLF_INT_ALL_MASK);

    /* enable fifo interrupts */
    XLlFifo_IntEnable(&xlltemacif->llfifo, XLLF_INT_ALL_MASK);

#if NO_SYS
    /* Register temac interrupt with interrupt controller */
    XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
                          xlltemacif->lltemac.Config.TemacIntr,
                          (XInterruptHandler)xlltemac_error_handler,
                          &xlltemacif->lltemac);

    /* connect & enable FIFO interrupt */
    XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
                          xlltemacif->lltemac.Config.LLFifoIntr,
                          (XInterruptHandler)xllfifo_intr_handler,
                          xemac);

    /* Enable EMAC interrupts in the interrupt controller */
    do {
        /* read current interrupt enable mask */
        unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

        /* form new mask enabling SDMA & ll_temac interrupts */
        cur_mask = cur_mask
                   | (1 << xlltemacif->lltemac.Config.LLFifoIntr)
                   | (1 << xlltemacif->lltemac.Config.TemacIntr);

        /* set new mask */
        XIntc_mEnableIntr(xtopologyp->intc_baseaddr, cur_mask);
    } while (0);
#else
    /* connect & enable TEMAC interrupts */
    register_int_handler(xlltemacif->lltemac.Config.TemacIntr,
                         (XInterruptHandler)xlltemac_error_handler,
                         &xlltemacif->lltemac);
    enable_interrupt(xlltemacif->lltemac.Config.TemacIntr);

    /* connect & enable FIFO interrupts */
    register_int_handler(xlltemacif->lltemac.Config.LLFifoIntr,
                         (XInterruptHandler)xllfifo_intr_handler,
                         xemac);
    enable_interrupt(xlltemacif->lltemac.Config.LLFifoIntr);
#endif

    return 0;
}
Exemplo n.º 6
0
/**
*
* Enables the interrupt source provided as the argument Id. Any pending
* interrupt condition for the specified Id will occur after this function is
* called. In Cascade mode, enables corresponding interrupt of Slave controllers
* depending on the Id.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being
*		the highest priority interrupt.
*
* @return	None.
*
* @note		None.
*
****************************************************************************/
void XIntc_Enable(XIntc * InstancePtr, u8 Id)
{
	u32 CurrentIER;
	u32 Mask;
	XIntc_Config *CfgPtr;

	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);

	if (Id > 31) {

		/* Enable user required Id in Slave controller */
		CfgPtr = XIntc_LookupConfig(Id/32);

		CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[(Id%32)];

		XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
		    				(CurrentIER | Mask));
	}
	else {
		/*
		 * The Id is used to create the appropriate mask for the
		 * desired bit position.
		 */
		Mask = XIntc_BitPosMask[Id];

		/*
		 * Enable the selected interrupt source by reading the
		 * interrupt enable register and then modifying only the
		 * specified interrupt id enable
		 */
		CurrentIER = XIntc_In32(InstancePtr->BaseAddress +
							XIN_IER_OFFSET);
		XIntc_Out32(InstancePtr->BaseAddress + XIN_IER_OFFSET,
		    (CurrentIER | Mask));
	}
}
/**
*
* Allows software to simulate an interrupt in the interrupt controller. This
* function will only be successful when the interrupt controller has been
* started in simulation mode. Once it has been started in real mode,
* interrupts cannot be simulated. A simulated interrupt allows the interrupt
* controller to be tested without any device to drive an interrupt input
* signal into it.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id is the interrupt ID for which to simulate an interrupt.
*
* @return
* 		- XST_SUCCESS if successful
*		- XST_FAILURE if the interrupt could not be
* 		simulated because the interrupt controller is or
*		has previously been in real mode.
*
* @note		None.
*
******************************************************************************/
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id)
{
	u32 Mask;
	u32 MasterEnable;

	/*
	 * Assert the arguments
	 */
	XASSERT_NONVOID(InstancePtr != NULL);
	XASSERT_NONVOID(InstancePtr->IsReady == XCOMPONENT_IS_READY);
	XASSERT_NONVOID(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);


	/* Get the contents of the master enable register and determine if
	 * hardware interrupts have already been enabled, if so, this is a write
	 * once bit such that simulation can't be done at this point because
	 * the ISR register is no longer writable by software
	 */
	MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET);
	if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) {
		return XST_FAILURE;
	}

	/*
	 * The Id is used to create the appropriate mask for the
	 * desired bit position. Id currently limited to 0 - 31
	 */
	Mask = XIntc_BitPosMask[Id];

	/*
	 * Enable the selected interrupt source by reading the interrupt enable
	 * register and then modifying only the specified interrupt id enable
	 */
	XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask);

	/* indicate the interrupt was successfully simulated */

	return XST_SUCCESS;
}
Exemplo n.º 8
0
xComPortHandle xSerialPortInitMinimal( unsigned long ulWantedBaud, unsigned portBASE_TYPE uxQueueLength )
{
unsigned long ulControlReg, ulMask;

	/* NOTE: The baud rate used by this driver is determined by the hardware
	parameterization of the UART Lite peripheral, and the baud value passed to
	this function has no effect. */

	/* Create the queues used to hold Rx and Tx characters. */
	xRxedChars = xQueueCreate( uxQueueLength, ( unsigned portBASE_TYPE ) sizeof( signed char ) );
	xCharsForTx = xQueueCreate( uxQueueLength + 1, ( unsigned portBASE_TYPE ) sizeof( signed char ) );

	if( ( xRxedChars ) && ( xCharsForTx ) )
	{
		/* Disable the interrupt. */
		XUartLite_mDisableIntr( XPAR_RS232_UART_BASEADDR );
		
		/* Flush the fifos. */
		ulControlReg = XIo_In32( XPAR_RS232_UART_BASEADDR + XUL_STATUS_REG_OFFSET );
		XIo_Out32( XPAR_RS232_UART_BASEADDR + XUL_CONTROL_REG_OFFSET, ulControlReg | XUL_CR_FIFO_TX_RESET | XUL_CR_FIFO_RX_RESET );

		/* Enable the interrupt again.  The interrupt controller has not yet been 
		initialised so there is no chance of receiving an interrupt until the 
		scheduler has been started. */
		XUartLite_mEnableIntr( XPAR_RS232_UART_BASEADDR );

		/* Enable the interrupt in the interrupt controller while maintaining 
		all the other bit settings. */
		ulMask = XIntc_In32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ) );
		ulMask |= XPAR_RS232_UART_INTERRUPT_MASK;
		XIntc_Out32( ( XPAR_OPB_INTC_0_BASEADDR + XIN_IER_OFFSET ), ( ulMask ) );
		XIntc_mAckIntr( XPAR_INTC_SINGLE_BASEADDR, 2 );
	}
	
	return ( xComPortHandle ) 0;
}
Exemplo n.º 9
0
/**
*
* Allows software to simulate an interrupt in the interrupt controller. This
* function will only be successful when the interrupt controller has been
* started in simulation mode. Once it has been started in real mode,
* interrupts cannot be simulated. A simulated interrupt allows the interrupt
* controller to be tested without any device to drive an interrupt input
* signal into it. In Cascade mode writes to ISR of appropraite Slave
* controller depending on Id.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id is the interrupt ID for which to simulate an interrupt.
*
* @return
* 		- XST_SUCCESS if successful
*		- XST_FAILURE if the interrupt could not be
* 		simulated because the interrupt controller is or
*		has previously been in real mode.
*
* @note		None.
*
******************************************************************************/
int XIntc_SimulateIntr(XIntc * InstancePtr, u8 Id)
{
	u32 Mask;
	u32 MasterEnable;
	XIntc_Config *CfgPtr;
	int Index;
	int DeviceId;

	/*
	 * Assert the arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);


	/* Get the contents of the master enable register and determine if
	 * hardware interrupts have already been enabled, if so, this is a write
	 * once bit such that simulation can't be done at this point because
	 * the ISR register is no longer writable by software
	 */
	MasterEnable = XIntc_In32(InstancePtr->BaseAddress + XIN_MER_OFFSET);
	if (MasterEnable & XIN_INT_HARDWARE_ENABLE_MASK) {
		return XST_FAILURE;
	}


	if (Id > 31) {

		DeviceId = Id/32;

		CfgPtr = XIntc_LookupConfig(Id/32);
		Mask = XIntc_BitPosMask[Id%32];
		XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET, Mask);

		/* Generate interrupt for 31 by writing to Interrupt Status
		 * register of parent controllers. Primary controller ISR
		 * will be written last in the loop
		 */
		Mask = XIntc_BitPosMask[31];
		for (Index = DeviceId - 1; Index >= 0; Index--)
		{
			CfgPtr = XIntc_LookupConfig(Index);

			XIntc_Out32(CfgPtr->BaseAddress + XIN_ISR_OFFSET,
									Mask);
		}
	}
	else {
		/*
		 * The Id is used to create the appropriate mask for the
		 * desired bit position.
		 */
		Mask = XIntc_BitPosMask[Id];

		/*
		 * Enable the selected interrupt source by reading the interrupt
		 * enable register and then modifying only the specified
		 * interrupt id enable
		 */
		XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, Mask);

	}
	/* indicate the interrupt was successfully simulated */

	return XST_SUCCESS;
}
Exemplo n.º 10
0
/**
*
* Run a self-test on the driver/device. This is a destructive test.
*
* This involves forcing interrupts into the controller and verifying that they
* are recognized and can be acknowledged. This test will not succeed if the
* interrupt controller has been started in real mode such that interrupts
* cannot be forced.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
*
* @return
* 		- XST_SUCCESS if self-test is successful.
* 		- XST_INTC_FAIL_SELFTEST if the Interrupt controller fails the
*		self-test. It will fail the self test if the device has
*		previously been started in real mode.
*
* @note		None.
*
******************************************************************************/
int XIntc_SelfTest(XIntc * InstancePtr)
{
	u32 CurrentISR;
	u32 Temp;

	/*
	 * Assert the arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);


	/*
	 * Acknowledge all pending interrupts by reading the interrupt status
	 * register and writing the value to the acknowledge register
	 */
	Temp = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);

	XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, Temp);

	/*
	 * Verify that there are no interrupts by reading the interrupt status
	 */
	CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);

	/*
	 * ISR should be zero after all interrupts are acknowledged
	 */
	if (CurrentISR != 0) {
		return XST_INTC_FAIL_SELFTEST;
	}

	/*
	 * Set a bit in the ISR which simulates an interrupt
	 */
	XIntc_Out32(InstancePtr->BaseAddress + XIN_ISR_OFFSET, XIN_TEST_MASK);

	/*
	 * Verify that it was set
	 */
	CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);

	if (CurrentISR != XIN_TEST_MASK) {
		return XST_INTC_FAIL_SELFTEST;
	}

	/*
	 * Acknowledge the interrupt
	 */
	XIntc_Out32(InstancePtr->BaseAddress + XIN_IAR_OFFSET, XIN_TEST_MASK);

	/*
	 * Read back the ISR to verify that the interrupt is gone
	 */
	CurrentISR = XIntc_In32(InstancePtr->BaseAddress + XIN_ISR_OFFSET);

	if (CurrentISR != 0) {
		return XST_INTC_FAIL_SELFTEST;
	}

	return XST_SUCCESS;
}
Exemplo n.º 11
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;
		}
	}
}
Exemplo n.º 12
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
	}
}
Exemplo n.º 13
0
XStatus init_axi_fifo(struct xemac_s *xemac)
{
	xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state);
#if XPAR_INTC_0_HAS_FAST == 1
	xaxiemacif_fast = xaxiemacif;
	xemac_fast = xemac;
#endif
#if NO_SYS
	struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif
#ifdef OS_IS_FREERTOS
	struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif

	/* initialize ll fifo */
	XLlFifo_Initialize(&xaxiemacif->axififo,
			XAxiEthernet_AxiDevBaseAddress(&xaxiemacif->axi_ethernet));

	/* Clear any pending FIFO interrupts */
	XLlFifo_IntClear(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

	/* enable fifo interrupts */
	XLlFifo_IntEnable(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

#if XLWIP_CONFIG_INCLUDE_AXIETH_ON_ZYNQ == 1
	XScuGic_RegisterHandler(xtopologyp->scugic_baseaddr,
				xaxiemacif->axi_ethernet.Config.TemacIntr,
				(XInterruptHandler)xaxiemac_error_handler,
				&xaxiemacif->axi_ethernet);
	XScuGic_RegisterHandler(xtopologyp->scugic_baseaddr,
				xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
				(XInterruptHandler)xllfifo_intr_handler,
				xemac);
	XScuGic_SetPriTrigTypeByDistAddr(INTC_DIST_BASE_ADDR,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			AXIETH_INTR_PRIORITY_SET_IN_GIC,
			TRIG_TYPE_RISING_EDGE_SENSITIVE);
	XScuGic_SetPriTrigTypeByDistAddr(INTC_DIST_BASE_ADDR,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			AXIFIFO_INTR_PRIORITY_SET_IN_GIC,
			TRIG_TYPE_RISING_EDGE_SENSITIVE);

	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR,
				xaxiemacif->axi_ethernet.Config.TemacIntr);
	XScuGic_EnableIntr(INTC_DIST_BASE_ADDR,
				xaxiemacif->axi_ethernet.Config.AxiFifoIntr);
#else
#if NO_SYS
#if XPAR_INTC_0_HAS_FAST == 1
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XFastInterruptHandler)xaxiemac_fasterror_handler);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XFastInterruptHandler)xllfifo_fastintr_handler);
#else
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);

#endif
	/* Enable EMAC interrupts in the interrupt controller */
	do {
		/* read current interrupt enable mask */
		unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

		/* form new mask enabling SDMA & ll_temac interrupts */
		cur_mask = cur_mask
				| (1 << xaxiemacif->axi_ethernet.Config.AxiFifoIntr)
				| (1 << xaxiemacif->axi_ethernet.Config.TemacIntr);

		/* set new mask */
		XIntc_EnableIntr(xtopologyp->intc_baseaddr, cur_mask);
	} while (0);
#else
#ifdef OS_IS_XILKERNEL
	/* connect & enable TEMAC interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.TemacIntr);

	/* connect & enable FIFO interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.AxiFifoIntr);
#else
#if XPAR_INTC_0_HAS_FAST == 1
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XFastInterruptHandler)xaxiemac_fasterror_handler);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XFastInterruptHandler)xllfifo_fastintr_handler);
#else
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);

#endif
	/* Enable EMAC interrupts in the interrupt controller */
	do {
		/* read current interrupt enable mask */
		unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

		/* form new mask enabling SDMA & ll_temac interrupts */
		cur_mask = cur_mask
				| (1 << xaxiemacif->axi_ethernet.Config.AxiFifoIntr)
				| (1 << xaxiemacif->axi_ethernet.Config.TemacIntr);

		/* set new mask */
		XIntc_EnableIntr(xtopologyp->intc_baseaddr, cur_mask);
	} while (0);
#endif
#endif
#endif

	return 0;
}
Exemplo n.º 14
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;
		}
	}
}
Exemplo n.º 15
0
/**
*
* Makes the connection between the Id of the interrupt source and the
* associated handler that is to run when the interrupt is recognized.In Cascade
* mode, connects handler to corresponding Slave controller IVAR register
* depending on the Id and sets all interrupt sources of the Slave controller as
* fast interrupts.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being
*		the highest priority interrupt.
* @param	Handler to the handler for that interrupt.
*
* @return
*		- XST_SUCCESS
*
* @note
* 		Slave controllers in Cascade Mode should have all as Fast
* 		interrupts or Normal interrupts, mixed interrupts are not
*		supported
*
* WARNING: The handler provided as an argument will overwrite any handler
* that was previously connected.
*
****************************************************************************/
int XIntc_ConnectFastHandler(XIntc *InstancePtr, u8 Id,
				XFastInterruptHandler Handler)
{
	u32 Imr;
	u32 CurrentIER;
	u32 Mask;
	XIntc_Config *CfgPtr;

	/*
	 * Assert the arguments
	 */
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertNonvoid(Handler != NULL);
	Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertNonvoid(InstancePtr->CfgPtr->FastIntr == TRUE);


	if (Id > 31) {
		/* Enable user required Id in Slave controller */
		CfgPtr = XIntc_LookupConfig(Id/32);

		if (CfgPtr->FastIntr != TRUE) {
			/*Fast interrupts of slave controller are not enabled*/
			return XST_FAILURE;
		}

		/* Get the Enabled Interrupts */
		CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[(Id%32)];

		/* Disable the Interrupt if it was enabled before calling
		 * this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Disable(InstancePtr, Id);
		}

		XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
				((Id%32) * 4), (u32) Handler);

		/* Slave controllers in Cascade Mode should have all as Fast
		 * interrupts or Normal interrupts, mixed interrupts are not
		 * supported
		 */
		XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF);

		/* Enable the Interrupt if it was enabled before calling this
		 * function
		 */
		if (CurrentIER & Mask) {
			XIntc_Enable(InstancePtr, Id);
		}
	}
	else {
		/* Get the Enabled Interrupts */
		CurrentIER = XIntc_In32(InstancePtr->BaseAddress +
							 XIN_IER_OFFSET);
		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[Id];

		/* Disable the Interrupt if it was enabled before calling
		 * this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Disable(InstancePtr, Id);
		}

		XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET +
					 (Id * 4), (u32) Handler);

		Imr = XIntc_In32(InstancePtr->BaseAddress + XIN_IMR_OFFSET);
		XIntc_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET,
		    					Imr | Mask);

		/* Enable the Interrupt if it was enabled before
		 * calling this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Enable(InstancePtr, Id);
		}

	}

	return XST_SUCCESS;
}
Exemplo n.º 16
0
/**
*
* Register a fast handler function for a specific interrupt ID. The handler
* function will be called when an interrupt occurs for the given interrupt ID.
* In Cascade mode Interrupt Id is used to set Handler for corresponding Slave
* Controller
*
* @param 	BaseAddress is the base address of the interrupt controller
*		whose vector table will be modified.
* @param 	InterruptId is the interrupt ID to be associated with the input
*		handler.
* @param 	FastHandler is the function pointer that will be called when
*   		interrupt occurs
*
* @return	None.
*
* @note
*
* Note that this function has no effect if the input base address is invalid.
*
******************************************************************************/
void XIntc_RegisterFastHandler(u32 BaseAddress, u8 Id,
					XFastInterruptHandler FastHandler)
{
	u32 CurrentIER;
	u32 Mask;
	u32 Imr;
	XIntc_Config *CfgPtr;


	if (Id > 31) {
		/* Enable user required Id in Slave controller */
		CfgPtr = XIntc_LookupConfig(Id/32);

		/* Get the Enabled Interrupts */
		CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[(Id%32)];

		/* Disable the Interrupt if it was enabled before calling
		 * this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
							(CurrentIER & ~Mask));
		}

		XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
					((Id%32) * 4), (u32) FastHandler);

		/* Slave controllers in Cascade Mode should have all as Fast
		 * interrupts or Normal interrupts, mixed interrupts are not
		 * supported
		 */
		XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0xFFFFFFFF);

		/* Enable the Interrupt if it was enabled before calling this
		 * function
		 */
		if (CurrentIER & Mask) {
			XIntc_Out32(CfgPtr->BaseAddress + XIN_IER_OFFSET,
						(CurrentIER | Mask));
		}
	}
	else {

		CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[Id];

		if (CurrentIER & Mask) {
			/* Disable Interrupt if it was enabled */
			CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
			XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
							(CurrentIER & ~Mask));
		}

		XIntc_Out32(BaseAddress + XIN_IVAR_OFFSET + (Id * 4),
						(u32) FastHandler);

		Imr = XIntc_In32(BaseAddress + XIN_IMR_OFFSET);
		XIntc_Out32(BaseAddress + XIN_IMR_OFFSET, Imr | Mask);


		/* Enable Interrupt if it was enabled before calling
		 * this function
		 */
		if (CurrentIER & Mask) {
			CurrentIER = XIntc_In32(BaseAddress + XIN_IER_OFFSET);
			XIntc_Out32(BaseAddress + XIN_IER_OFFSET,
							(CurrentIER | Mask));
		}
	}
}
Exemplo n.º 17
0
/**
*
* Sets the normal interrupt mode for the specified interrupt in the Interrupt
* Mode Register. In Cascade mode disconnects handler from corresponding Slave
* controller IVAR register depending on the Id and sets all interrupt sources
* of the Slave controller as normal interrupts.
*
* @param	InstancePtr is a pointer to the XIntc instance to be worked on.
* @param	Id contains the ID of the interrupt source and should be in the
*		range of 0 to XPAR_INTC_MAX_NUM_INTR_INPUTS - 1 with 0 being the
*		highest priority interrupt.
*
* @return	None.
*
* @note
*		Slave controllers in Cascade Mode should have all as Fast
* 		interrupts or Normal interrupts, mixed interrupts are not
*		supported
*
****************************************************************************/
void XIntc_SetNormalIntrMode(XIntc *InstancePtr, u8 Id)
{
	u32 Imr;
	u32 CurrentIER;
	u32 Mask;
	XIntc_Config *CfgPtr;

	/*
	 * Assert the arguments
	 */
	Xil_AssertVoid(InstancePtr != NULL);
	Xil_AssertVoid(Id < XPAR_INTC_MAX_NUM_INTR_INPUTS);
	Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
	Xil_AssertVoid(InstancePtr->CfgPtr->FastIntr == TRUE);

	if (Id > 31) {
		/* Enable user required Id in Slave controller */
		CfgPtr = XIntc_LookupConfig(Id/32);

		/* Get the Enabled Interrupts */
		CurrentIER = XIntc_In32(CfgPtr->BaseAddress + XIN_IER_OFFSET);

		/* Convert from integer id to bit mask */
		Mask = XIntc_BitPosMask[(Id%32)];

		/* Disable the Interrupt if it was enabled before calling
		 * this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Disable(InstancePtr, Id);
		}

		/* Slave controllers in Cascade Mode should have all as Fast
		 * interrupts or Normal interrupts, mixed interrupts are not
		 * supported
		 */
		XIntc_Out32(CfgPtr->BaseAddress + XIN_IMR_OFFSET, 0x0);

		if (CfgPtr->IntVectorAddr == 0x0) {
			XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
							(Id * 4), 0x10);
		} else {
			XIntc_Out32(CfgPtr->BaseAddress + XIN_IVAR_OFFSET +
					(Id * 4), CfgPtr->IntVectorAddr);
		}

		/* Enable the Interrupt if it was enabled before calling this
		 * function
		 */
		if (CurrentIER & Mask) {
			XIntc_Enable(InstancePtr, Id);
		}

	}
	else {

		/* Get the Enabled Interrupts */
		CurrentIER = XIntc_In32(InstancePtr->BaseAddress + XIN_IER_OFFSET);
		Mask = XIntc_BitPosMask[Id];/* Convert from integer id to bit mask */


		/* Disable the Interrupt if it was enabled before
		 * calling this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Disable(InstancePtr, Id);
		}

		/*
		 * Disable the selected interrupt as Fast Interrupt by reading the
		 * interrupt mode register and then modifying only the
		 * specified interrupt id
		 */
		Imr = XIntc_In32(InstancePtr->BaseAddress + XIN_IMR_OFFSET);
		XIntc_Out32(InstancePtr->BaseAddress + XIN_IMR_OFFSET,
						    Imr & ~Mask);

		if (InstancePtr->CfgPtr->IntVectorAddr == 0x0) {
			XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET +
						 (Id * 4), 0x10);
		} else {
			XIntc_Out32(InstancePtr->BaseAddress + XIN_IVAR_OFFSET +
					(Id * 4), InstancePtr->CfgPtr->IntVectorAddr);
		}

		/* Enable the Interrupt if it was enabled before
		 * calling this function
		 */
		if (CurrentIER & Mask) {
			XIntc_Enable(InstancePtr, Id);
		}
	}
}
Exemplo n.º 18
0
XStatus init_axi_fifo(struct xemac_s *xemac)
{
	xaxiemacif_s *xaxiemacif = (xaxiemacif_s *)(xemac->state);
#if XPAR_INTC_0_HAS_FAST == 1
	xaxiemacif_fast = xaxiemacif;
	xemac_fast = xemac;
#endif
#if NO_SYS
	struct xtopology_t *xtopologyp = &xtopology[xemac->topology_index];
#endif

	/* initialize ll fifo */
	XLlFifo_Initialize(&xaxiemacif->axififo,
			XAxiEthernet_AxiDevBaseAddress(&xaxiemacif->axi_ethernet));

	/* Clear any pending FIFO interrupts */
	XLlFifo_IntClear(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

	/* enable fifo interrupts */
	XLlFifo_IntEnable(&xaxiemacif->axififo, XLLF_INT_ALL_MASK);

#if NO_SYS
#if XPAR_INTC_0_HAS_FAST == 1
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XFastInterruptHandler)xaxiemac_fasterror_handler);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterFastHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XFastInterruptHandler)xllfifo_fastintr_handler);
#else
	/* Register temac interrupt with interrupt controller */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);

	/* connect & enable FIFO interrupt */
	XIntc_RegisterHandler(xtopologyp->intc_baseaddr,
			xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);

#endif
	/* Enable EMAC interrupts in the interrupt controller */
	do {
		/* read current interrupt enable mask */
		unsigned int cur_mask = XIntc_In32(xtopologyp->intc_baseaddr + XIN_IER_OFFSET);

		/* form new mask enabling SDMA & ll_temac interrupts */
		cur_mask = cur_mask
				| (1 << xaxiemacif->axi_ethernet.Config.AxiFifoIntr)
				| (1 << xaxiemacif->axi_ethernet.Config.TemacIntr);

		/* set new mask */
		XIntc_EnableIntr(xtopologyp->intc_baseaddr, cur_mask);
	} while (0);
#else
	/* connect & enable TEMAC interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.TemacIntr,
			(XInterruptHandler)xaxiemac_error_handler,
			&xaxiemacif->axi_ethernet);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.TemacIntr);

	/* connect & enable FIFO interrupts */
	register_int_handler(xaxiemacif->axi_ethernet.Config.AxiFifoIntr,
			(XInterruptHandler)xllfifo_intr_handler,
			xemac);
	enable_interrupt(xaxiemacif->axi_ethernet.Config.AxiFifoIntr);
#endif

	return 0;
}