blob: c7311ab9be52dfafdcb0c65857f99b48ae2b33d2 [file] [log] [blame]
wdenk97e8bda2004-09-29 22:43:59 +00001/* $Id: xipif_v1_23_b.c,v 1.1 2002/03/18 23:24:52 linnj Exp $ */
2/******************************************************************************
3*
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.
17*
18* (c) Copyright 2002 Xilinx Inc.
19* All rights reserved.
20*
21******************************************************************************/
22/******************************************************************************
23*
24* FILENAME:
25*
26* xipif.c
27*
28* DESCRIPTION:
29*
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.
38*
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.
49*
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.
58*
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
67* of the IP.
68*
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
75* registers.
76*
77* Critical Sections
78*
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.
85*
86* Mutual Exclusion
87*
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.
91*
92* NOTES:
93*
94* None.
95*
96* MODIFICATION HISTORY:
97*
98* Ver Who Date Changes
99* ----- ---- -------- -----------------------------------------------
100* 1.23b jhl 02/27/01 Repartioned to reduce size
101*
102******************************************************************************/
103
104/***************************** Include Files *********************************/
105
106#include "xipif_v1_23_b.h"
107#include "xio.h"
108
109/************************** Constant Definitions *****************************/
110
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
114 */
115#define XIIF_V123B_FIRST_BIT_MASK 1UL
116
117/**************************** Type Definitions *******************************/
118
119/***************** Macros (Inline Functions) Definitions *********************/
120
121/************************** Variable Definitions *****************************/
122
123/************************** Function Prototypes ******************************/
124
125static XStatus IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth);
126
127/******************************************************************************
128*
129* FUNCTION:
130*
131* XIpIf_SelfTest
132*
133* DESCRIPTION:
134*
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.
141*
142* ARGUMENTS:
143*
144* InstancePtr points to the XIpIf to operate on.
145*
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.
150*
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.
155*
156* RETURN VALUE:
157*
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.
160*
161* XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
162* not valid
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
170*
171* NOTES:
172*
173* None.
174*
175******************************************************************************/
176
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
180 */
181#define XIIF_V123B_MAX_REG_BIT_COUNT 32
182
183XStatus
184XIpIfV123b_SelfTest(u32 RegBaseAddress, u8 IpRegistersWidth)
185{
186 XStatus Status;
187
188 /* assert to verify arguments are valid */
189
190 XASSERT_NONVOID(IpRegistersWidth <= XIIF_V123B_MAX_REG_BIT_COUNT);
191
192 /* reset the IPIF such that it's in a known state before the test
193 * and interrupts are globally disabled
194 */
195 XIIF_V123B_RESET(RegBaseAddress);
196
197 /* perform the self test on the IP interrupt registers, if
198 * it is not successful exit with the status
199 */
200 Status = IpIntrSelfTest(RegBaseAddress, IpRegistersWidth);
201 if (Status != XST_SUCCESS) {
202 return Status;
203 }
204
205 /* reset the IPIF such that it's in a known state before exiting test */
206
207 XIIF_V123B_RESET(RegBaseAddress);
208
209 /* reaching this point means there were no errors, return success */
210
211 return XST_SUCCESS;
212}
213
214/******************************************************************************
215*
216* FUNCTION:
217*
218* IpIntrSelfTest
219*
220* DESCRIPTION:
221*
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.
227*
228* ARGUMENTS:
229*
230* InstancePtr points to the XIpIf to operate on.
231*
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.
236*
237* RETURN VALUE:
238*
239* A status indicating XST_SUCCESS if the test was successful. Otherwise, one
240* of the following values is returned.
241*
242* XST_IPIF_RESET_REGISTER_ERROR The value of a register at reset was
243* not valid
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
251* NOTES:
252*
253* None.
254*
255******************************************************************************/
256static XStatus
257IpIntrSelfTest(u32 RegBaseAddress, u32 IpRegistersWidth)
258{
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
262 */
263 if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
264 return XST_IPIF_RESET_REGISTER_ERROR;
265 }
266
267 /* if there are any used IP interrupts, then test all of the interrupt
268 * bits in all testable registers
269 */
270 if (IpRegistersWidth > 0) {
271 u32 BitCount;
272 u32 IpInterruptMask = XIIF_V123B_FIRST_BIT_MASK;
273 u32 Mask = XIIF_V123B_FIRST_BIT_MASK; /* bits assigned MSB to LSB */
274 u32 InterruptStatus;
275
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
280 */
281 for (BitCount = 1; BitCount < IpRegistersWidth; BitCount++) {
282 Mask = Mask << 1;
283 IpInterruptMask |= Mask;
284 }
285
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
290 */
291 InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
292 IpInterruptMask &= ~InterruptStatus;
293
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
296 */
297 XIIF_V123B_WRITE_IISR(RegBaseAddress, IpInterruptMask);
298 InterruptStatus = XIIF_V123B_READ_IISR(RegBaseAddress);
299 if ((InterruptStatus & IpInterruptMask) != IpInterruptMask)
300 {
301 return XST_IPIF_IP_STATUS_ERROR;
302 }
303
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
307 */
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;
312 }
313
314 /* set the IP interrupt enable set register and then read the IP
315 * interrupt enable register and verify the interrupts were enabled
316 */
317 XIIF_V123B_WRITE_IIER(RegBaseAddress, IpInterruptMask);
318 if (XIIF_V123B_READ_IIER(RegBaseAddress) != IpInterruptMask) {
319 return XST_IPIF_IP_ENABLE_ERROR;
320 }
321
322 /* clear the IP interrupt enable register and then read the
323 * IP interrupt enable register and verify the interrupts were disabled
324 */
325 XIIF_V123B_WRITE_IIER(RegBaseAddress, 0);
326 if (XIIF_V123B_READ_IIER(RegBaseAddress) != 0) {
327 return XST_IPIF_IP_ENABLE_ERROR;
328 }
329 }
330 return XST_SUCCESS;
331}