/** * * 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)); } }
/** * * 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; } }
/** * * 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)); }
/** * * 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; }
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; }
/** * * 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; }
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; }
/** * * 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; }
/** * * 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; }
/** * * 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 } }
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; }
/** * * 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; } } }
/** * * 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; }
/** * * 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)); } } }
/** * * 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); } } }
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; }