Root/qiboot/src/memory-test.c

1#include <qi.h>
2#include <string.h>
3
4int memory_test_const32(void * start, unsigned int length, u32 value)
5{
6    int errors = 0;
7    u32 * p = (u32 *)start;
8    u32 * pend = (u32 *)(start + length);
9    int count = length >> 2;
10
11    puts(".");
12
13    while (p < pend)
14        *p++ = value;
15
16    p = (u32 *)start;
17    count = length >> 2;
18
19    while (count--)
20        if (*p++ != value) {
21            puts("*** Error ");
22            print32((long)p - 4);
23            errors++;
24        }
25
26    return errors;
27}
28
29int memory_test_ads(void * start, unsigned int length, u32 mask)
30{
31    int errors = 0;
32    u32 * p = (u32 *)start;
33    u32 * pend = (u32 *)(start + length);
34
35    puts(".");
36
37    while (p < pend)
38        if ((u32)p & mask)
39            *p++ = 0xffffffff;
40        else
41            *p++ = 0;
42
43    p = (u32 *)start;
44
45    while (p < pend) {
46        if ((u32)p & mask) {
47            if (*p++ != 0xffffffff) {
48                puts("*** Error ");
49                print32((long)p - 4);
50                errors++;
51            }
52        } else {
53            if (*p++) {
54                puts("*** Error ");
55                print32((long)p - 4);
56                errors++;
57            }
58        }
59    }
60    return errors;
61}
62
63int memory_test_walking1(void * start, unsigned int length)
64{
65    int errors = 0;
66    u32 value = 1;
67
68    while (value) {
69        errors += memory_test_const32(start, length, value);
70        value <<= 1;
71    }
72
73    return errors;
74}
75
76/* negative runs == run forever */
77
78void __memory_test(void * start, unsigned int length)
79{
80    int errors = 0;
81    int series = 0;
82    int mask;
83
84    puts("\nMemory Testing 0x");
85    print32((u32)start);
86    puts(" length ");
87    printdec(length >> 20);
88    puts(" MB\n");
89
90    while (1) {
91        puts(" Test series ");
92        printdec(series + 1);
93        puts(" ");
94
95        /* these are looking at data issues, they flood the whole
96         * array with the same data
97         */
98
99        errors += memory_test_const32(start, length, 0x55555555);
100        errors += memory_test_const32(start, length, 0xaaaaaaaa);
101        errors += memory_test_const32(start, length, 0x55aa55aa);
102        errors += memory_test_const32(start, length, 0xaa55aa55);
103        errors += memory_test_const32(start, length, 0x00ff00ff);
104        errors += memory_test_const32(start, length, 0xff00ff00);
105        errors += memory_test_walking1(start, length);
106
107        /* this is looking at addressing issues, it floods only
108         * addresses meeting a walking mask with 0xffffffff (the rest
109         * is zeroed), and makes sure all the bits are only seen where
110         * they were placed
111         */
112
113        mask = 1;
114        while (! (length & mask)) {
115            errors += memory_test_ads(start, length, mask);
116            mask = mask << 1;
117        }
118
119        puts(" Total errors: ");
120        printdec(errors);
121        puts("\n");
122
123        series++;
124    }
125}
126
127
128void memory_test(void * start, unsigned int length)
129{
130    /* it's a small steppingstone stack from start.S */
131    extern int _ss_stack;
132
133    /*
134     * we won't be coming back from this, so just force our local stack to
135     * steppingstone out of the way of main memory test action
136     *
137     * then jump into the actual test
138     */
139    asm volatile (
140        "mov sp, %0\n"
141        : : "r" (&_ss_stack)
142    );
143
144    __memory_test(start, length);
145}
146

Archive Download this file



interactive