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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [xscale/] [iq80321/] [v2_0/] [src/] [diag/] [memtest.c] - Blame information for rev 565

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

Line No. Rev Author Line
1 27 unneback
//=============================================================================
2
//
3
//      memtest.c
4
//
5
//=============================================================================
6
//####ECOSGPLCOPYRIGHTBEGIN####
7
// -------------------------------------------
8
// This file is part of eCos, the Embedded Configurable Operating System.
9
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
10
//
11
// eCos is free software; you can redistribute it and/or modify it under
12
// the terms of the GNU General Public License as published by the Free
13
// Software Foundation; either version 2 or (at your option) any later version.
14
//
15
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18
// for more details.
19
//
20
// You should have received a copy of the GNU General Public License along
21
// with eCos; if not, write to the Free Software Foundation, Inc.,
22
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23
//
24
// As a special exception, if other files instantiate templates or use macros
25
// or inline functions from this file, or you compile this file and link it
26
// with other works to produce a work based on this file, this file does not
27
// by itself cause the resulting work to be covered by the GNU General Public
28
// License. However the source code for this file must still be made available
29
// in accordance with section (3) of the GNU General Public License.
30
//
31
// This exception does not invalidate any other reasons why a work based on
32
// this file might be covered by the GNU General Public License.
33
//
34
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
35
// at http://sources.redhat.com/ecos/ecos-license/
36
// -------------------------------------------
37
//####ECOSGPLCOPYRIGHTEND####
38
//=============================================================================
39
//#####DESCRIPTIONBEGIN####
40
//
41
// Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
42
// Contributors: Mark Salter
43
// Date:        2001-01-25
44
// Purpose:     
45
// Description: 
46
//
47
//####DESCRIPTIONEND####
48
//
49
//===========================================================================*/
50
 
51
/*************************************************************************
52
* Memtest.c - this file performs an address/address bar memory test.
53
*
54
*  Modification History
55
*  --------------------
56
*  01sep00 ejb Ported to StrongARM2
57
*  18dec00 snc
58
*  02feb01 jwf for snc
59
*  25jan02 Rewritten for RedBoot by Mark Salter
60
*/
61
 
62
#include <redboot.h>
63
 
64
#define FAILED          1
65
#define PASSED          0
66
 
67
// Do walking one's test
68
//
69
static int
70
onesTest(CYG_ADDRWORD *testAddr)
71
{
72
    CYG_ADDRWORD theOne, dataRead;
73
    int fail, loopCount = 0; // To keep track of when to print CR
74
 
75
    diag_printf("\n");
76
 
77
    // Loop for all bits in an address
78
    for (theOne = 1, fail = 0; theOne && !fail; theOne <<= 1) {
79
 
80
        testAddr[0] = theOne;     // Write test data
81
        testAddr[1] = ~0L;        // Drive d0-dn hi
82
        dataRead = *testAddr;     // Read back data
83
 
84
        diag_printf("%08x%s", dataRead, (++loopCount % 8) ? "" : "\n");
85
 
86
        if (dataRead != theOne)  // Verify data
87
            return FAILED;       // Signal failure
88
    }
89
    return PASSED;
90
}
91
 
92
 
93
// Do 32-bit word address test
94
//
95
static int
96
Addr32 (cyg_uint32 *start, cyg_uint32 *end, CYG_ADDRWORD *badAddr)
97
{
98
    cyg_uint32 *currentAddr; /* Current address being tested */
99
    cyg_uint32 data;
100
 
101
    for(currentAddr = start; currentAddr <= end; currentAddr++)
102
        *currentAddr = (cyg_uint32)(CYG_ADDRWORD)currentAddr;
103
 
104
    for (currentAddr = start; currentAddr <= end; currentAddr++) {
105
        data = *currentAddr;
106
        if (data != (cyg_uint32)(CYG_ADDRWORD)currentAddr) {
107
            diag_printf ("\n\nBad Read, Address = %p, Data Read = 0x%08x\n\n",
108
                         currentAddr, data);
109
            *badAddr = (CYG_ADDRWORD)currentAddr;
110
            return FAILED;
111
        }
112
    }
113
    return PASSED;
114
}
115
 
116
 
117
// Do inverse long word address test
118
//
119
static int
120
Bar32 (cyg_uint32 *start, cyg_uint32 *end, CYG_ADDRWORD *badAddr)
121
{
122
    cyg_uint32 *currentAddr, data;
123
 
124
    for(currentAddr = start; currentAddr <= end; currentAddr++)
125
        *currentAddr = ~(CYG_ADDRWORD)currentAddr;
126
 
127
    for (currentAddr = start; currentAddr <= end; currentAddr++) {
128
        data = *currentAddr;
129
        if (data != (~(CYG_ADDRWORD)currentAddr) & 0xffffffff) {
130
            diag_printf ("\n\nBad Read, Address = %p, Data Read = 0x%08x\n\n",
131
                         currentAddr, data);
132
            *badAddr = (CYG_ADDRWORD)currentAddr;
133
            return FAILED;
134
        }
135
    }
136
    return PASSED;
137
}
138
 
139
// Do byte address test
140
//
141
static int
142
Addr8 (cyg_uint8 *start, cyg_uint8 *end, CYG_ADDRWORD *badAddr)
143
{
144
    cyg_uint8 *currentAddr; // Current address being tested
145
 
146
    for (currentAddr = start; currentAddr <= end; currentAddr++)
147
        *currentAddr = (cyg_uint8)(CYG_ADDRWORD)currentAddr;
148
 
149
    for (currentAddr = start; currentAddr <= end; currentAddr++)
150
        if (*currentAddr != (cyg_uint8)(CYG_ADDRWORD)currentAddr) {
151
            *badAddr = (CYG_ADDRWORD)currentAddr;
152
            return FAILED;
153
        }
154
    return PASSED;
155
}
156
 
157
// Do inverse byte address test
158
//
159
static int
160
Bar8 (cyg_uint8 *start, cyg_uint8 *end, CYG_ADDRWORD *badAddr)
161
{
162
    cyg_uint8 *currentAddr;  // Current address being tested
163
 
164
    for(currentAddr = start; currentAddr <= end; currentAddr++)
165
        *currentAddr = ~(CYG_ADDRWORD)currentAddr;
166
 
167
    for(currentAddr = start; currentAddr <= end; currentAddr++)
168
        if (*currentAddr != (~(CYG_ADDRWORD)currentAddr & 0xff)) {
169
            *badAddr = (CYG_ADDRWORD)currentAddr;
170
            return FAILED;
171
        }
172
    return PASSED;
173
}
174
 
175
// This routine is called if one of the memory tests fails.  It dumps
176
// the 8 32-bit words before and the 8 after the failure address
177
//
178
void
179
dumpMem (CYG_ADDRWORD badAddr)
180
{
181
    cyg_uint32 *addr;
182
    cyg_uint16 *saddr;
183
    int i;
184
 
185
    // Print out first line of mem dump
186
    diag_printf("\n%p: %08x %08x %08x %08x",
187
                (char *)badAddr - 32,
188
                *(cyg_uint32 *)(badAddr - 32),
189
                *(cyg_uint32 *)(badAddr - 28),
190
                *(cyg_uint32 *)(badAddr - 24),
191
                *(cyg_uint32 *)(badAddr - 20));
192
 
193
    diag_printf("\n%p: %08x %08x %08x %08x",
194
                (char *)badAddr - 16,
195
                *(cyg_uint32 *)(badAddr - 16),
196
                *(cyg_uint32 *)(badAddr - 12),
197
                *(cyg_uint32 *)(badAddr - 8),
198
                *(cyg_uint32 *)(badAddr - 4));
199
 
200
    // Print out contents of fault addr
201
    diag_printf("\n%p: %08x",
202
                (char *)badAddr, *(cyg_uint32 *)badAddr);
203
 
204
    diag_printf("\n%p: %08x %08x %08x %08x",
205
                (char *)badAddr + 4,
206
                *(cyg_uint32 *)(badAddr + 4),
207
                *(cyg_uint32 *)(badAddr + 8),
208
                *(cyg_uint32 *)(badAddr + 12),
209
                *(cyg_uint32 *)(badAddr + 16));
210
 
211
    diag_printf("\n%p: %08x %08x %08x %08x",
212
                (char *)badAddr + 20,
213
                *(cyg_uint32 *)(badAddr + 20),
214
                *(cyg_uint32 *)(badAddr + 24),
215
                *(cyg_uint32 *)(badAddr + 28),
216
                *(cyg_uint32 *)(badAddr + 32));
217
 
218
    /* DEBUG */
219
    diag_printf ("\n\nReading back data in 32bit chunks:\n");
220
    for (addr = (cyg_uint32 *)(badAddr - 16), i = 0; i <= 8; i++, addr++)
221
        diag_printf ("Address = %p, Data = 0x%08x\n", addr, *addr);
222
    diag_printf ("\n");
223
 
224
    diag_printf ("Reading back data in 16bit chunks:\n");
225
    for (saddr = (cyg_uint16 *)(badAddr - 16), i = 0; i <= 16; i++, saddr++)
226
        diag_printf ("Address = %p, Data = 0x%08x\n", saddr, *saddr);
227
    diag_printf ("\n");
228
}
229
 
230
// Returns 1 if passed, 0 if failed.
231
//
232
int
233
memTest (CYG_ADDRWORD startAddr, CYG_ADDRWORD endAddr)
234
{
235
    CYG_ADDRWORD badAddr;  // Addr test failed at
236
 
237
    diag_printf("\nWalking 1's test: ");
238
    if (onesTest((CYG_ADDRWORD *)startAddr) == FAILED)
239
        goto failed;
240
    diag_printf("passed");
241
 
242
    diag_printf("\n32-bit address test: ");
243
    if (Addr32((cyg_uint32 *)startAddr, (cyg_uint32 *)endAddr, &badAddr) == FAILED)
244
        goto failed;
245
    diag_printf("passed");
246
 
247
    diag_printf("\n32-bit address bar test: ");
248
    if (Bar32((cyg_uint32 *)startAddr, (cyg_uint32 *)endAddr, &badAddr) == FAILED)
249
        goto failed;
250
    diag_printf("passed");
251
 
252
    diag_printf("\n8-bit address test: ");
253
    if (Addr8((cyg_uint8 *)startAddr, (cyg_uint8 *)endAddr, &badAddr) == FAILED)
254
        goto failed;
255
    diag_printf("passed");
256
 
257
    diag_printf("\nByte address bar test: ");
258
    if (Bar8((cyg_uint8 *)startAddr, (cyg_uint8 *)endAddr, &badAddr) == FAILED)
259
        goto failed;
260
    diag_printf("passed");
261
 
262
    return 1;
263
 
264
 failed:
265
    diag_printf("failed");
266
    dumpMem(badAddr);
267
    return 0;
268
}
269
 
270
 
271
/* 02/02/01 jwf */
272
/* Do alternating inverse long word address test */
273
static int
274
ABar32(cyg_uint32 *start,               /* Starting address of test */
275
       cyg_uint32 *end,         /* Ending address */
276
       CYG_ADDRWORD *badAddr)           /* Failure address */
277
{
278
    register cyg_uint32 *currentAddr;   /* Current address being tested */
279
    int fail = 0;                /* Test hasn't failed yet */
280
    cyg_uint32 data;
281
 
282
    /* In this test, the contents of each longword address toggles
283
       between the Address and the Address BAR */
284
    for(currentAddr = start; currentAddr <= end; currentAddr++) {
285
 
286
        if ((CYG_ADDRWORD)currentAddr & 4) /* Address ending in 0x4 or 0xc */
287
            *currentAddr = ~(cyg_uint32)(CYG_ADDRWORD)currentAddr;
288
 
289
        else /* Address ending in 0x0 or 0x8 */
290
            *currentAddr = (cyg_uint32)(CYG_ADDRWORD)currentAddr;
291
    }
292
 
293
    for (currentAddr = start; currentAddr <= end && !fail; currentAddr++) {
294
        data = *currentAddr;
295
 
296
        switch ((CYG_ADDRWORD)currentAddr & 0xf) {
297
          case 0x0:
298
          case 0x8:
299
            if (data != (cyg_uint32)(CYG_ADDRWORD)currentAddr) {
300
                fail = 1;
301
                diag_printf ("\nFailed at Address %p, Expected 0x%08X, Read 0x%08X\n",
302
                             currentAddr, (cyg_uint32)(CYG_ADDRWORD)currentAddr, data);
303
            }
304
            break;
305
 
306
          case 0x4:
307
          case 0xc:
308
            if (data != ~(cyg_uint32)(CYG_ADDRWORD)currentAddr) {
309
                fail = 1;
310
                diag_printf ("\nFailed at Address %p, Expected 0x%08X, Read 0x%08X\n",
311
                             currentAddr, ~(cyg_uint32)(CYG_ADDRWORD)currentAddr, data);
312
            }
313
            break;
314
 
315
          default:
316
            fail = 1;
317
            diag_printf ("\nFailed at Address %p, Unaligned address\n", currentAddr);
318
            break;
319
        }
320
    }
321
 
322
    if (fail) {
323
        *badAddr = (CYG_ADDRWORD)(--currentAddr);
324
        return FAILED;
325
    } else
326
        return PASSED;
327
}
328
 
329
 
330
/* 02/02/01 jwf */
331
/*
332
 * Returns 1 if passed, 0 if failed.
333
 */
334
int
335
LoopMemTest (CYG_ADDRWORD startAddr, CYG_ADDRWORD endAddr)
336
{
337
    CYG_ADDRWORD badAddr;  /* Addr test failed at */
338
    volatile int junk;
339
 
340
    while (1) {
341
        diag_printf("\n");
342
 
343
        diag_printf("\n32-bit address test: ");
344
        if (Addr32((cyg_uint32 *)startAddr, (cyg_uint32 *)endAddr, &badAddr) == FAILED)
345
            break;
346
        diag_printf("passed");
347
 
348
        diag_printf("\n32-bit address bar test: ");
349
        if (Bar32((cyg_uint32 *)startAddr, (cyg_uint32 *)endAddr, &badAddr) == FAILED)
350
            break;
351
        diag_printf("passed");
352
 
353
        diag_printf("\nAlternating Long word, Long word address bar test: ");
354
        if (ABar32((cyg_uint32 *)startAddr, (cyg_uint32 *)endAddr, &badAddr) == FAILED)
355
            break;
356
        diag_printf("passed");
357
    }
358
 
359
    diag_printf("failed at Address %p\n", badAddr);
360
    diag_printf("Performing Continuous Write/Read/!Write/Read...\n\n");
361
    while (1) {
362
        *(volatile int *)badAddr = badAddr;
363
        junk = *(volatile int *)badAddr;
364
        *(volatile int *)badAddr = ~badAddr;
365
        junk = *(volatile int *)badAddr;
366
    }
367
 
368
    return 1;   // not reached
369
}
370
 
371
 

powered by: WebSVN 2.1.0

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