]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/edb7xxx/v2_0/tests/dram_test.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / edb7xxx / v2_0 / tests / dram_test.c
1 //==========================================================================
2 //
3 //        dram_test.c
4 //
5 //        eCos generic DRAM test code
6 //
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12 //
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
16 //
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20 // for more details.
21 //
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25 //
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
32 //
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 //
36 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37 // at http://sources.redhat.com/ecos/ecos-license/
38 // -------------------------------------------
39 //####ECOSGPLCOPYRIGHTEND####
40 //==========================================================================
41 //#####DESCRIPTIONBEGIN####
42 //
43 // Author(s):     gthomas
44 // Contributors:  gthomas
45 // Date:          1999-10-22
46 // Description:   Tool used to test DRAM on eval boards
47 //####DESCRIPTIONEND####
48
49 #include <pkgconf/system.h>
50 #include <cyg/infra/testcase.h>
51
52 #ifdef CYGPKG_KERNEL
53
54 #include <pkgconf/kernel.h>   // Configuration header
55
56 #ifdef CYGFUN_KERNEL_API_C
57
58 #include <cyg/kernel/kapi.h>
59 #include <cyg/infra/diag.h>
60
61 #include <cyg/hal/hal_arch.h>
62 #include CYGHWR_MEMORY_LAYOUT_H  // Memory layout
63
64 #ifndef FALSE
65 #define FALSE 0
66 #define TRUE  1
67 #endif
68
69 #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
70 static char stack[STACK_SIZE];
71 static cyg_thread thread_data;
72 static cyg_handle_t thread_handle;
73
74 extern char __bss_end;
75 int total_errors;
76 int run_errors;
77 int error_count;
78
79 #define MAX_ERRORS   5
80 #define NUM_RUNS     4
81 #define REFRESH_TIME 5
82
83 int decay_time[] = { 50, 100, 200, 500, 1000 };
84 #define NUM_DECAY sizeof(decay_time)/sizeof(decay_time[0])
85
86 // FUNCTIONS
87
88 static void
89 new_test(void)
90 {
91     error_count = 0;
92 }
93
94 static void
95 report_error(void *addr, cyg_uint32 actual, cyg_uint32 expected)
96 {
97     total_errors++;
98     run_errors++;
99     if (++error_count > MAX_ERRORS) return;
100     diag_printf("   0x%08x: expected - 0x%08x, actual - 0x%08x\n", 
101                 addr, expected, actual);
102 }
103
104 // Fill longwords with their own address and verify
105
106 static void
107 addr_test(cyg_uint32 start, cyg_uint32 end)
108 {
109     cyg_uint32 *mp;
110
111     new_test();
112     diag_printf("-- Address test\n");
113     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
114         *mp = (cyg_uint32)mp;
115     }
116     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
117         if (*mp != (cyg_uint32)mp) {
118             report_error(mp, *mp, (cyg_uint32)mp);
119         }
120     }
121 }
122
123 // Fill longwords with zeros
124
125 static void
126 zeros_test(cyg_uint32 start, cyg_uint32 end)
127 {
128     cyg_uint32 *mp;
129
130     new_test();
131     diag_printf("-- Zeros test\n");
132     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
133         *mp = (cyg_uint32)0;
134     }
135     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
136         if (*mp != (cyg_uint32)0) {
137             report_error(mp, *mp, (cyg_uint32)0);
138         }
139     }
140 }
141
142 // Fill longwords with all ones
143
144 static void
145 ones_test(cyg_uint32 start, cyg_uint32 end)
146 {
147     cyg_uint32 *mp;
148
149     new_test();
150     diag_printf("-- Ones test\n");
151     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
152         *mp = (cyg_uint32)0xFFFFFFFF;
153     }
154     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
155         if (*mp != (cyg_uint32)0xFFFFFFFF) {
156             report_error(mp, *mp, (cyg_uint32)0xFFFFFFFF);
157         }
158     }
159 }
160
161 // Fill longwords with a "walking" bit
162
163 static void
164 walking_bit_test(cyg_uint32 start, cyg_uint32 end)
165 {
166     cyg_uint32 *mp;
167     cyg_uint32 bit;
168
169     new_test();
170     diag_printf("-- Walking test\n");
171     bit = 1;
172     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
173         *mp = (cyg_uint32)bit;
174         bit <<= 1;
175         if (bit == 0) bit = 1;
176     }
177     bit = 1;
178     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
179         if (*mp != (cyg_uint32)bit) {
180             report_error(mp, *mp, (cyg_uint32)bit);
181         }
182         bit <<= 1;
183         if (bit == 0) bit = 1;
184     }
185 }
186
187 // Fill longwords with an alternating pattern
188
189 static void
190 pattern_test(cyg_uint32 start, cyg_uint32 end)
191 {
192     cyg_uint32 *mp;
193     cyg_uint32 pat;
194
195     new_test();
196     diag_printf("-- Pattern test\n");
197     pat = 0x55555555;
198     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
199         *mp = (cyg_uint32)pat;
200     }
201     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
202         if (*mp != (cyg_uint32)pat) {
203             report_error(mp, *mp, (cyg_uint32)pat);
204         }
205     }
206     pat = 0xAAAAAAAA;
207     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
208         *mp = (cyg_uint32)pat;
209     }
210     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
211         if (*mp != (cyg_uint32)pat) {
212             report_error(mp, *mp, (cyg_uint32)pat);
213         }
214     }
215 }
216
217 // Verify if refresh works
218
219 static void
220 refresh_test(cyg_uint32 start, cyg_uint32 end)
221 {
222     cyg_uint32 *mp;
223     cyg_uint32 pat;
224
225     new_test();
226     diag_printf("-- Refresh test\n");
227     pat = 0x55555555;
228     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
229         *mp = (cyg_uint32)pat;
230     }
231     cyg_thread_delay(REFRESH_TIME*100);
232     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
233         if (*mp != (cyg_uint32)pat) {
234             report_error(mp, *mp, (cyg_uint32)pat);
235         }
236     }
237     pat = 0xAAAAAAAA;
238     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
239         *mp = (cyg_uint32)pat;
240     }
241     cyg_thread_delay(REFRESH_TIME*100);
242     for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
243         if (*mp != (cyg_uint32)pat) {
244             report_error(mp, *mp, (cyg_uint32)pat);
245         }
246     }
247 }
248
249 // See how long we can "sleep" before refresh fails
250
251 static void
252 decay_test(cyg_uint32 start, cyg_uint32 end)
253 {
254     cyg_uint32 *mp;
255     cyg_uint32 pat;
256     int i;
257
258     diag_printf("-- Decay test\n");
259     for (i = 0;  i < NUM_DECAY;  i++) {
260         diag_printf("    ... %d.%02d sec delay\n", decay_time[i]/100, decay_time[i]%100);
261         new_test();
262         pat = 0x55555555;
263         for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
264             *mp = (cyg_uint32)pat;
265         }
266         cyg_thread_delay(decay_time[i]);
267         for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
268             if (*mp != (cyg_uint32)pat) {
269                 report_error(mp, *mp, (cyg_uint32)pat);
270             }
271         }
272         pat = 0xAAAAAAAA;
273         for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
274             *mp = (cyg_uint32)pat;
275         }
276         cyg_thread_delay(decay_time[i]);
277         for (mp = (cyg_uint32 *)start;  mp < (cyg_uint32 *)end;  mp++) {
278             if (*mp != (cyg_uint32)pat) {
279                 report_error(mp, *mp, (cyg_uint32)pat);
280             }
281         }
282         diag_printf("    ... %d errors\n", error_count);
283     }
284 }
285
286
287 static void
288 dram_exercise(cyg_addrword_t p)
289 {
290     cyg_uint32 start_DRAM, end_DRAM;
291     int i;
292
293     CYG_TEST_INIT();
294
295     end_DRAM = CYGMEM_REGION_ram+CYGMEM_REGION_ram_SIZE;
296     start_DRAM = ((cyg_uint32)&__bss_end + 0x00000FFF) & 0xFFFFF000;
297     diag_printf("DRAM test - start: 0x%08x, end: 0x%08x\n", start_DRAM, end_DRAM);
298
299     for (i = 0;  i < NUM_RUNS;  i++) {
300         diag_printf("\n*** Start run #%d of %d\n", i+1, NUM_RUNS);
301         run_errors = 0;
302         addr_test(start_DRAM, end_DRAM);
303         ones_test(start_DRAM, end_DRAM);
304         zeros_test(start_DRAM, end_DRAM);
305         walking_bit_test(start_DRAM, end_DRAM);
306         pattern_test(start_DRAM, end_DRAM);
307         refresh_test(start_DRAM, end_DRAM);
308         decay_test(start_DRAM, end_DRAM);
309         diag_printf("\n*** End run, %d errors, %d total errors\n", run_errors, total_errors);
310     }
311
312     CYG_TEST_PASS_FINISH("DRAM testing complete");
313 }
314
315 externC void
316 cyg_start( void )
317 {
318     // Create a main thread, so we can run the scheduler and have time 'pass'
319     cyg_thread_create(10,                // Priority - just a number
320                       dram_exercise,     // entry
321                       0,                 // entry parameter
322                       "DRAM test",       // Name
323                       &stack[0],         // Stack
324                       STACK_SIZE,        // Size
325                       &thread_handle,    // Handle
326                       &thread_data       // Thread data structure
327             );
328     cyg_thread_resume(thread_handle);  // Start it
329     cyg_scheduler_start();
330 } // cyg_package_start()
331
332 #else /* def CYGFUN_KERNEL_API_C */
333 # define NA_MSG "Kernel C API layer disabled"
334 #endif
335
336 #else /* def CYGPKG_KERNEL */
337 # define NA_MSG "No kernel"
338 #endif
339
340
341 #ifdef NA_MSG
342 externC void
343 cyg_start( void )
344 {
345     CYG_TEST_INIT();
346     CYG_TEST_NA(NA_MSG);
347 }
348 #endif