1 /* $Id: xipif_v1_23_b.c,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
2 /******************************************************************************
4 * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"
5 * AS A COURTESY TO YOU, SOLELY FOR USE IN DEVELOPING PROGRAMS AND
6 * SOLUTIONS FOR XILINX DEVICES. BY PROVIDING THIS DESIGN, CODE,
7 * OR INFORMATION AS ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE,
8 * APPLICATION OR STANDARD, XILINX IS MAKING NO REPRESENTATION
9 * THAT THIS IMPLEMENTATION IS FREE FROM ANY CLAIMS OF INFRINGEMENT,
10 * AND YOU ARE RESPONSIBLE FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE
11 * FOR YOUR IMPLEMENTATION. XILINX EXPRESSLY DISCLAIMS ANY
12 * WARRANTY WHATSOEVER WITH RESPECT TO THE ADEQUACY OF THE
13 * IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OR
14 * REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE FROM CLAIMS OF
15 * INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
16 * FOR A PARTICULAR PURPOSE.
18 * (c) Copyright 2002 Xilinx Inc.
19 * All rights reserved.
21 ******************************************************************************/
22 /******************************************************************************
30 * This file contains the implementation of the XIpIf component. The
31 * XIpIf component encapsulates the IPIF, which is the standard interface
32 * that IP must adhere to when connecting to a bus. The purpose of this
33 * component is to encapsulate the IPIF processing such that maintainability
34 * is increased. This component does not provide a lot of abstraction from
35 * from the details of the IPIF as it is considered a building block for
36 * device drivers. A device driver designer must be familiar with the
37 * details of the IPIF hardware to use this component.
39 * The IPIF hardware provides a building block for all hardware devices such
40 * that each device does not need to reimplement these building blocks. The
41 * IPIF contains other building blocks, such as FIFOs and DMA channels, which
42 * are also common to many devices. These blocks are implemented as separate
43 * hardware blocks and instantiated within the IPIF. The primary hardware of
44 * the IPIF which is implemented by this software component is the interrupt
45 * architecture. Since there are many blocks of a device which may generate
46 * interrupts, all the interrupt processing is contained in the common part
47 * of the device, the IPIF. This interrupt processing is for the device level
48 * only and does not include any processing for the interrupt controller.
50 * A device is a mechanism such as an Ethernet MAC. The device is made
51 * up of several parts which include an IPIF and the IP. The IPIF contains most
52 * of the device infrastructure which is common to all devices, such as
53 * interrupt processing, DMA channels, and FIFOs. The infrastructure may also
54 * be referred to as IPIF internal blocks since they are part of the IPIF and
55 * are separate blocks that can be selected based upon the needs of the device.
56 * The IP of the device is the logic that is unique to the device and interfaces
57 * to the IPIF of the device.
59 * In general, there are two levels of registers within the IPIF. The first
60 * level, referred to as the device level, contains registers which are for the
61 * entire device. The second level, referred to as the IP level, contains
62 * registers which are specific to the IP of the device. The two levels of
63 * registers are designed to be hierarchical such that the device level is
64 * is a more general register set above the more specific registers of the IP.
65 * The IP level of registers provides functionality which is typically common
66 * across all devices and allows IP designers to focus on the unique aspects
69 * The interrupt registers of the IPIF are parameterizable such that the only
70 * the number of bits necessary for the device are implemented. The functions
71 * of this component do not attempt to validate that the passed in arguments are
72 * valid based upon the number of implemented bits. This is necessary to
73 * maintain the level of performance required for the common components. Bits
74 * of the registers are assigned starting at the least significant bit of the
79 * It is the responsibility of the device driver designer to use critical
80 * sections as necessary when calling functions of the IPIF. This component
81 * does not use critical sections and it does access registers using
82 * read-modify-write operations. Calls to IPIF functions from a main thread
83 * and from an interrupt context could produce unpredictable behavior such that
84 * the caller must provide the appropriate critical sections.
88 * The functions of the IPIF are not thread safe such that the caller of all
89 * functions is responsible for ensuring mutual exclusion for an IPIF. Mutual
90 * exclusion across multiple IPIF components is not necessary.
96 * MODIFICATION HISTORY:
98 * Ver Who Date Changes
99 * ----- ---- -------- -----------------------------------------------
100 * 1.23b jhl 02/27/01 Repartioned to reduce size
102 ******************************************************************************/
104 /***************************** Include Files *********************************/
106 #include "xipif_v1_23_b.h"
109 /************************** Constant Definitions *****************************/
111 /* the following constant is used to generate bit masks for register testing
112 * in the self test functions, it defines the starting bit mask that is to be
113 * shifted from the LSB to MSB in creating a register test mask
115 #define XIIF_V123B_FIRST_BIT_MASK 1UL
117 /**************************** Type Definitions *******************************/
119 /***************** Macros (Inline Functions) Definitions *********************/
121 /************************** Variable Definitions *****************************/
123 /************************** Function Prototypes ******************************/
125 static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
127 /******************************************************************************
135 * This function performs a self test on the specified IPIF component. Many
136 * of the registers in the IPIF are tested to ensure proper operation. This
137 * function is destructive because the IPIF is reset at the start of the test
138 * and at the end of the test to ensure predictable results. The IPIF reset
139 * also resets the entire device that uses the IPIF. This function exits with
140 * all interrupts for the device disabled.
144 * InstancePtr points to the XIpIf to operate on.
146 * DeviceRegistersWidth contains the number of bits in the device interrupt
147 * registers. The hardware is parameterizable such that only the number of bits
148 * necessary to support a device are implemented. This value must be between 0
149 * and 32 with 0 indicating there are no device interrupt registers used.
151 * IpRegistersWidth contains the number of bits in the IP interrupt registers
152 * of the device. The hardware is parameterizable such that only the number of
153 * bits necessary to support a device are implemented. This value must be
154 * between 0 and 32 with 0 indicating there are no IP interrupt registers used.
158 * A value of XST_SUCCESS indicates the test was successful with no errors.
159 * Any one of the following error values may also be returned.
161 * XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
163 * XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
164 * register did not read back correctly
165 * XST_IPIF_IP_ACK_ERROR One or more bits in the IP interrupt
166 * status register did not reset when acked
167 * XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
168 * did not read back correctly based upon
169 * what was written to it
175 ******************************************************************************/
177 /* the following constant defines the maximum number of bits which may be
178 * used in the registers at the device and IP levels, this is based upon the
179 * number of bits available in the registers
181 #define XIIF_V123B_MAX_REG_BIT_COUNT 32
184 XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
188 /* assert to verify arguments are valid */
190 XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
192 /* reset the IPIF such that it's in a known state before the test
193 * and interrupts are globally disabled
195 XIIF_V123B_RESET(RegBaseAddress);
197 /* perform the self test on the IP interrupt registers, if
198 * it is not successful exit with the status
200 Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
201 if (Status != XST_SUCCESS) {
205 /* reset the IPIF such that it's in a known state before exiting test */
207 XIIF_V123B_RESET(RegBaseAddress);
209 /* reaching this point means there were no errors, return success */
214 /******************************************************************************
222 * Perform a self test on the IP interrupt registers of the IPIF. This
223 * function modifies registers of the IPIF such that they are not guaranteed
224 * to be in the same state when it returns. Any bits in the IP interrupt
225 * status register which are set are assumed to be set by default after a reset
226 * and are not tested in the test.
230 * InstancePtr points to the XIpIf to operate on.
232 * IpRegistersWidth contains the number of bits in the IP interrupt registers
233 * of the device. The hardware is parameterizable such that only the number of
234 * bits necessary to support a device are implemented. This value must be
235 * between 0 and 32 with 0 indicating there are no IP interrupt registers used.
239 * A status indicating XST_SUCCESS if the test was successful. Otherwise, one
240 * of the following values is returned.
242 * XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
244 * XST_IPIF_IP_STATUS_ERROR A write to the IP interrupt status
245 * register did not read back correctly
246 * XST_IPIF_IP_ACK_ERROR One or more bits in the IP status
247 * register did not reset when acked
248 * XST_IPIF_IP_ENABLE_ERROR The IP interrupt enable register
249 * did not read back correctly based upon
250 * what was written to it
255 ******************************************************************************/
257 IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
259 /* ensure that the IP interrupt interrupt enable register is zero
260 * as it should be at reset, the interrupt status is dependent upon the
261 * IP such that it's reset value is not known
263 if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
264 return XST_IPIF_RESET_REGISTER_ERROR;
267 /* if there are any used IP interrupts, then test all of the interrupt
268 * bits in all testable registers
270 if (IpRegistersWidth > 0) {
272 u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
273 u32 Mask = XIIF_V123B_FIRST_BIT_MASK; /* bits assigned MSB to LSB */
276 /* generate the register masks to be used for IP register tests, the
277 * number of bits supported by the hardware is parameterizable such
278 * that only that number of bits are implemented in the registers, the
279 * bits are allocated starting at the MSB of the registers
281 for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
283 IpInterruptMask |= Mask;
286 /* get the current IP interrupt status register contents, any bits
287 * already set must default to 1 at reset in the device and these
288 * bits can't be tested in the following test, remove these bits from
289 * the mask that was generated for the test
291 InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
292 IpInterruptMask &= ~InterruptStatus;
294 /* set the bits in the device status register and verify them by reading
295 * the register again, all bits of the register are latched
297 XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
298 InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
299 if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
301 return XST_IPIF_IP_STATUS_ERROR;
304 /* test to ensure that the bits set in the IP interrupt status register
305 * can be cleared by acknowledging them in the IP interrupt status
306 * register then read it again and verify it was cleared
308 XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
309 InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
310 if ((InterruptStatus & IpInterruptMask) != 0) {
311 return XST_IPIF_IP_ACK_ERROR;
314 /* set the IP interrupt enable set register and then read the IP
315 * interrupt enable register and verify the interrupts were enabled
317 XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
318 if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
319 return XST_IPIF_IP_ENABLE_ERROR;
322 /* clear the IP interrupt enable register and then read the
323 * IP interrupt enable register and verify the interrupts were disabled
325 XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
326 if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
327 return XST_IPIF_IP_ENABLE_ERROR;