]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/ebsa285/v2_0/tests/sdram0.cxx
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / ebsa285 / v2_0 / tests / sdram0.cxx
1 //==========================================================================
2 //
3 //        sdram0.cxx
4 //
5 //        SDRAM function test 0
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):     hmt
44 // Contributors:  hmt
45 // Date:          1999-11-11
46 // Description:   Basic memory test, knowledgeable of the EBSA285's
47 //                memory size.
48 //####DESCRIPTIONEND####
49
50 #include <cyg/infra/testcase.h>
51
52 #include <cyg/infra/diag.h>
53
54 #include <cyg/hal/hal_arch.h>
55 #include <cyg/hal/hal_intr.h>
56
57 #define ONE_MEG (0x100000)
58 #define ONE_MEG_IN_WORDS (ONE_MEG/4)
59
60 #define MEGS 9
61 #define WORDS ONE_MEG_IN_WORDS
62 #define START 0x400000
63
64 #define INNERLOOPS 10
65
66 #define NUMTESTS 1
67
68 #if WORDS > ONE_MEG_IN_WORDS
69 # error "Too many WORDS in a block - they'll overlap!"
70 #endif
71
72 #include <cyg/hal/hal_ebsa285.h>
73
74
75 void
76 check_addrsize_setup( void )
77 {
78     cyg_uint32 sizes[4] = { 0, };
79     cyg_uint32 bases[4] = { 0, };
80     cyg_uint32 codes[4] = { 0, };
81     cyg_uint32 muxes[4] = { 0, };
82     cyg_uint32 i;
83
84 #define MBytes <<20
85
86     static cyg_uint32 lookup[] =
87     { 0, 1 MBytes, 2 MBytes, 4 MBytes, 8 MBytes, 16 MBytes, 32 MBytes, 64 MBytes };
88
89     static cyg_uint32 maxsizes[] =
90     { 2 MBytes, 16 MBytes, 64 MBytes, 8 MBytes, 64 MBytes,  0, 0, 0 };
91
92     codes[0] = *SA110_SDRAM_ADDRESS_SIZE_ARRAY_0;
93     codes[1] = *SA110_SDRAM_ADDRESS_SIZE_ARRAY_1;
94     codes[2] = *SA110_SDRAM_ADDRESS_SIZE_ARRAY_2;
95     codes[3] = *SA110_SDRAM_ADDRESS_SIZE_ARRAY_3;
96
97     // Print all the info for the benefit of humans:
98     for ( i = 0; i < 4; i++ ) {
99         bases[i] = 0x0ff00000 & codes[i];
100         sizes[i] = lookup[ 7 & codes[i] ];
101         muxes[i] = 7 & (codes[i] >> 4);
102         diag_printf( "Bank %d: [%08x]: base %08x, size %08x; mux mode %d\n",
103                      i, codes[i], bases[i] , sizes[i] , muxes[i] );
104     }
105     // THEN check individual entries for sanity
106     for ( i = 0; i < 4; i++ ) {
107         if ( 0 == sizes[i] ) {
108             // then the bank is not in use
109             CYG_TEST_CHECK( 0 == bases[i], "Unused bank nonzero address" );
110             CYG_TEST_CHECK( 0 == muxes[i], "Unused bank nonzero mux mode" );
111         } else {
112             CYG_TEST_CHECK( muxes[i] <= 4, "Mux mode overflow" );
113             if ( (muxes[i] == 3) && (8 != sizes[i]) )
114                 CYG_TEST_FAIL( "Mux mode 3 and size not 8Mb" );
115             CYG_TEST_CHECK( maxsizes[ muxes[i] ] >= sizes[i],
116                             "Size too larget for mux mode" );
117         }
118     }
119
120     // NEXT check that addresses are singly mapped IYSWIM:
121     // Easiest way is, foreach megabyte, check it is mapped exactly once;
122     // shouldn't take too long.
123     for ( i = 0; i < hal_dram_size; i += ONE_MEG ) {
124         int j = 0;
125         int k;
126         for ( k = 0; k < 4; k++ )
127             // this test works OK for an unused slot because i is +ve:
128             if ( (bases[k] <= i) && (i < (bases[k] + sizes[k])) )
129                 j++;
130         CYG_TEST_CHECK( 2 > j, "Good memory is multiply mapped" );
131         CYG_TEST_CHECK( 0 < j, "Good memory is not mapped" );
132     }
133     for ( /* i */ ; i < 256 MBytes; i += ONE_MEG ) {
134         int j = 0;
135         int k;
136         for ( k = 0; k < 4; k++ )
137             // this test works OK for an unused slot because i is +ve:
138             if ( (bases[k] <= i) && (i < (bases[k] + sizes[k])) )
139                 j++;
140         CYG_TEST_CHECK( 2 > j,  "Non-existent memory is multiply mapped" );
141         CYG_TEST_CHECK( 0 == j, "Non-existent memory is mapped" );
142     }
143     CYG_TEST_PASS( "Memory controller setup self-consistent" );
144 }
145
146
147 void mymain( void )
148 {
149     cyg_uint32 h, i, j, k;
150     cyg_uint32 *pbase[ MEGS ] = { 0, };
151     int totaltests = 0;
152     int ptotalerrors[ MEGS ] = { 0, };
153
154     CYG_TEST_INIT();
155
156
157     check_addrsize_setup();
158
159
160     h = hal_dram_size - ONE_MEG;
161     i = MEGS - 1;
162     j = START;
163     k = 0;
164     while ( (i > k) && (h > j) ) {
165         pbase[i] = (cyg_uint32 *)h; 
166         pbase[k] = (cyg_uint32 *)j;
167         i--;
168         k++;
169         h -= ONE_MEG;
170         j += ONE_MEG;
171     }
172     if ( (i == k) && (h > j) )
173         pbase[ i ] = (cyg_uint32 *)((h+j)/2);
174
175     for ( h = 0; h < NUMTESTS; h++ ) { 
176         int perrors[ MEGS ] = { 0, };
177         cyg_uint32 pbadbits[ MEGS ] = { 0, };
178         for ( i = 0 ; i < INNERLOOPS; i++ ) {
179             cyg_uint32 d = 0xdeadbeef ^ ((cyg_uint32)i * 0x10001);
180             for ( k = 0; k < MEGS; k++ ) {
181                 cyg_uint32 *p = pbase[k];
182                 cyg_uint32 dp = d ^ (cyg_uint32)p;
183                 if ( ! p ) continue;
184                 for ( j = 0; j < WORDS; j++ )
185                     p[j] = dp ^ j ^ (j << 19) ;
186             }
187             for ( k = 0; k < MEGS; k++ ) {
188                 cyg_uint32 *p = pbase[k];
189                 cyg_uint32 dp = d ^ (cyg_uint32)p;
190                 if ( ! p ) continue;
191                 for ( j = 0; j < WORDS; j++ )
192                     if ( p[j] != (dp ^ j ^ (j << 19)) ) {
193                         perrors[k]++;
194                         pbadbits[k] |= (p[j] ^ dp ^ j ^ (j << 19));
195                     }
196             }
197         }
198         totaltests += i * j;
199         for ( k = 0; k < MEGS; k++ ) {
200             if ( ! pbase[k] ) continue;
201             ptotalerrors[k] += perrors[k];
202             diag_printf(
203 "p %x: %d tests of %d words: %d errors, badbits %x ...totals %d tests %d errors\n",
204  pbase[k], i,      j,      perrors[k], pbadbits[k],  totaltests, ptotalerrors[k] );
205             if ( 0 != perrors[k] )
206                 CYG_TEST_FAIL( "Errors in memory test" );
207         }
208     }
209
210     h = j = 0;
211     for ( k = 0; k < MEGS; k++ ) {
212         if ( ! pbase[k] ) continue;
213         h += ptotalerrors[k] ;
214         j += totaltests;
215     }
216     diag_printf( "Total tests %d, total errors %d\n", j, h );
217     if ( 0 == h )
218         CYG_TEST_PASS( "Memory test all OK" );
219
220     CYG_TEST_EXIT("End of mem test");
221     
222 }
223
224 externC void
225 cyg_start( void )
226
227     HAL_ENABLE_INTERRUPTS();
228
229 #ifdef CYGPKG_HAL_ARM_EBSA285
230     cyg_uint32 i;
231     i = *(cyg_uint32 *)(0x42000000 + 0x10c);
232     diag_printf( "SDRAM timing %08x\n", i );
233     for ( i = 0; i < 4; i++ ) {
234         diag_printf( "Bank %d: addrsize %08x\n", i, *(cyg_uint32 *)(0x42000000 + 0x110 + i * 4 ));
235     }
236     diag_printf( "Mem size: %08x == %d\n", hal_dram_size, hal_dram_size );
237 #endif
238
239     mymain();
240 }
241 // EOF sdram0.cxx