OpenCores
URL https://opencores.org/ocsvn/qaz_libs/qaz_libs/trunk

Subversion Repositories qaz_libs

[/] [qaz_libs/] [trunk/] [cli/] [cli/] [memtest.c] - Blame information for rev 28

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 22 qaztronic
/**********************************************************************
2
 *
3
 * Filename:    memtest.c
4
 *
5
 * Description: General-purpose memory testing functions.
6
 *
7
 * Notes:       This software can be easily ported to systems with
8
 *              different data bus widths by redefining 'datum'.
9
 *
10
 *
11
 * Copyright (c) 1998 by Michael Barr.  This software is placed into
12
 * the public domain and may be used for any purpose.  However, this
13
 * notice must not be changed or removed and no warranty is either
14
 * expressed or implied by its publication or distribution.
15
 **********************************************************************/
16
 
17
 
18
#include "memtest.h"
19
 
20
 
21
/**********************************************************************
22
 *
23
 * Function:    memTestDataBus()
24
 *
25
 * Description: Test the data bus wiring in a memory region by
26
 *              performing a walking 1's test at a fixed address
27
 *              within that region.  The address (and hence the
28
 *              memory region) is selected by the caller.
29
 *
30
 * Notes:
31
 *
32
 * Returns:     0 if the test succeeds.
33
 *              A non-zero result is the first pattern that failed.
34
 *
35
 **********************************************************************/
36
datum
37
memTestDataBus(volatile datum * address)
38
{
39
    datum pattern;
40
 
41
 
42
    /*
43
     * Perform a walking 1's test at the given address.
44
     */
45
    for (pattern = 1; pattern != 0; pattern <<= 1)
46
    {
47
        /*
48
         * Write the test pattern.
49
         */
50
        *address = pattern;
51
 
52
        /*
53
         * Read it back (immediately is okay for this test).
54
         */
55
        if (*address != pattern)
56
        {
57
            return (pattern);
58
        }
59
    }
60
 
61
    return (0);
62
 
63
}   /* memTestDataBus() */
64
 
65
 
66
/**********************************************************************
67
 *
68
 * Function:    memTestAddressBus()
69
 *
70
 * Description: Test the address bus wiring in a memory region by
71
 *              performing a walking 1's test on the relevant bits
72
 *              of the address and checking for aliasing. This test
73
 *              will find single-bit address failures such as stuck
74
 *              -high, stuck-low, and shorted pins.  The base address
75
 *              and size of the region are selected by the caller.
76
 *
77
 * Notes:       For best results, the selected base address should
78
 *              have enough LSB 0's to guarantee single address bit
79
 *              changes.  For example, to test a 64-Kbyte region,
80
 *              select a base address on a 64-Kbyte boundary.  Also,
81
 *              select the region size as a power-of-two--if at all
82
 *              possible.
83
 *
84
 * Returns:     NULL if the test succeeds.
85
 *              A non-zero result is the first address at which an
86
 *              aliasing problem was uncovered.  By examining the
87
 *              contents of memory, it may be possible to gather
88
 *              additional information about the problem.
89
 *
90
 **********************************************************************/
91
datum *
92
memTestAddressBus(volatile datum * baseAddress, unsigned long nBytes)
93
{
94
    unsigned long addressMask = (nBytes/sizeof(datum) - 1);
95
    unsigned long offset;
96
    unsigned long testOffset;
97
 
98
    datum pattern     = (datum) 0xAAAAAAAA;
99
    datum antipattern = (datum) 0x55555555;
100
 
101
 
102
    /*
103
     * Write the default pattern at each of the power-of-two offsets.
104
     */
105
    for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
106
    {
107
        baseAddress[offset] = pattern;
108
    }
109
 
110
    /*
111
     * Check for address bits stuck high.
112
     */
113
    testOffset = 0;
114
    baseAddress[testOffset] = antipattern;
115
 
116
    for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
117
    {
118
        if (baseAddress[offset] != pattern)
119
        {
120
            return ((datum *) &baseAddress[offset]);
121
        }
122
    }
123
 
124
    baseAddress[testOffset] = pattern;
125
 
126
    /*
127
     * Check for address bits stuck low or shorted.
128
     */
129
    for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
130
    {
131
        baseAddress[testOffset] = antipattern;
132
 
133
                if (baseAddress[0] != pattern)
134
                {
135
                        return ((datum *) &baseAddress[testOffset]);
136
                }
137
 
138
        for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
139
        {
140
            if ((baseAddress[offset] != pattern) && (offset != testOffset))
141
            {
142
                return ((datum *) &baseAddress[testOffset]);
143
            }
144
        }
145
 
146
        baseAddress[testOffset] = pattern;
147
    }
148
 
149
    return (NULL);
150
 
151
}   /* memTestAddressBus() */
152
 
153
 
154
/**********************************************************************
155
 *
156
 * Function:    memTestDevice()
157
 *
158
 * Description: Test the integrity of a physical memory device by
159
 *              performing an increment/decrement test over the
160
 *              entire region.  In the process every storage bit
161
 *              in the device is tested as a zero and a one.  The
162
 *              base address and the size of the region are
163
 *              selected by the caller.
164
 *
165
 * Notes:
166
 *
167
 * Returns:     NULL if the test succeeds.
168
 *
169
 *              A non-zero result is the first address at which an
170
 *              incorrect value was read back.  By examining the
171
 *              contents of memory, it may be possible to gather
172
 *              additional information about the problem.
173
 *
174
 **********************************************************************/
175
datum *
176
memTestDevice(volatile datum * baseAddress, unsigned long nBytes)
177
{
178
    unsigned long offset;
179
    unsigned long nWords = nBytes / sizeof(datum);
180
 
181
    datum pattern;
182
    datum antipattern;
183
 
184
 
185
    /*
186
     * Fill memory with a known pattern.
187
     */
188
    for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
189
    {
190
        baseAddress[offset] = pattern;
191
    }
192
 
193
    /*
194
     * Check each location and invert it for the second pass.
195
     */
196
    for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
197
    {
198
        if (baseAddress[offset] != pattern)
199
        {
200
            return ((datum *) &baseAddress[offset]);
201
        }
202
 
203
        antipattern = ~pattern;
204
        baseAddress[offset] = antipattern;
205
    }
206
 
207
    /*
208
     * Check each location for the inverted pattern and zero it.
209
     */
210
    for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
211
    {
212
        antipattern = ~pattern;
213
        if (baseAddress[offset] != antipattern)
214
        {
215
            return ((datum *) &baseAddress[offset]);
216
        }
217
    }
218
 
219
    return (NULL);
220
 
221
}   /* memTestDevice() */
222
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.