1 |
27 |
unneback |
//==========================================================================
|
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
|