]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - examples/test_burst.c
Fix compile problems caused by new burst mode SDRAM test;
[karo-tx-uboot.git] / examples / test_burst.c
1 /*
2  * (C) Copyright 2005
3  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License as
10  * published by the Free Software Foundation; either version 2 of
11  * the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21  * MA 02111-1307 USA
22  *
23  * The test exercises SDRAM accesses in burst mode
24  */
25
26 #include <common.h>
27 #include <exports.h>
28
29 #include <commproc.h>
30 #include <asm/mmu.h>
31 #include <asm/processor.h>
32
33 #include <serial.h>
34 #include <watchdog.h>
35
36 #include "test_burst.h"
37
38 /* 8 MB test region of physical RAM */
39 #define TEST_PADDR      0x00800000
40 /* The uncached virtual region */
41 #define TEST_VADDR_NC   0x00800000
42 /* The cached virtual region */
43 #define TEST_VADDR_C    0x01000000
44 /* When an error is detected, the address where the error has been found,
45    and also the current and the expected data will be written to
46    the following flash address
47 */
48 #define TEST_FLASH_ADDR 0x40100000
49
50 /* Define GPIO ports to signal start of burst transfers and errors */
51 #ifdef CONFIG_LWMON
52 /* Use PD.8 to signal start of burst transfers */
53 #define GPIO1_DAT       (((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddat)
54 #define GPIO1_BIT       0x0080
55 /* Configure PD.8 as general purpose output */
56 #define GPIO1_INIT \
57         ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pdpar &= ~GPIO1_BIT; \
58         ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddir |=  GPIO1_BIT;
59 /* Use PD.9 to signal error */
60 #define GPIO2_DAT       (((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddat)
61 #define GPIO2_BIT       0x0040
62 /* Configure PD.9 as general purpose output */
63 #define GPIO2_INIT \
64         ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pdpar &= ~GPIO2_BIT; \
65         ((volatile immap_t *)CFG_IMMR)->im_ioport.iop_pddir |=  GPIO2_BIT;
66 #endif /* CONFIG_LWMON */
67
68
69 static void test_prepare (void);
70 static int test_burst_start (unsigned long size, unsigned long pattern);
71 static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached);
72 static int test_mmu_is_on(void);
73 static void test_desc(unsigned long size);
74 static void test_error(char * step, volatile void * addr, unsigned long val, unsigned long pattern);
75 static void signal_init(void);
76 static void signal_start(void);
77 static void signal_error(void);
78 static void test_usage(void);
79
80 static unsigned long test_pattern [] = {
81         0x00000000,
82         0xffffffff,
83         0x55555555,
84         0xaaaaaaaa,
85 };
86
87
88 int test_burst (int argc, char *argv[])
89 {
90         unsigned long size = CACHE_LINE_SIZE;
91         int res;
92         int i;
93
94         if (argc == 2) {
95                 char * d;
96                 for (size = 0, d = argv[1]; *d >= '0' && *d <= '9'; d++) {
97                         size *= 10;
98                         size += *d - '0';
99                 }
100                 if (size == 0 || *d) {
101                         test_usage();
102                         return 1;
103                 }
104         } else if (argc > 2) {
105                 test_usage();
106                 return 1;
107         }
108
109         size +=  (CACHE_LINE_SIZE - 1);
110         size &= ~(CACHE_LINE_SIZE - 1);
111
112         if (!test_mmu_is_on()) {
113                 test_prepare();
114         }
115
116         test_desc(size);
117
118         for (i = 0; i < sizeof(test_pattern) / sizeof(test_pattern[0]); i++) {
119                 res = test_burst_start(size, test_pattern[i]);
120                 if (res != 0) {
121                         goto Done;
122                 }
123         }
124 Done:
125         return res;
126 }
127
128 static void test_prepare (void)
129 {
130         printf ("\n");
131
132         caches_init();
133         disable_interrupts();
134         mmu_init();
135
136         printf ("Interrupts are disabled\n");
137         printf ("I-Cache is ON\n");
138         printf ("D-Cache is ON\n");
139         printf ("MMU is ON\n");
140
141         printf ("\n");
142
143         test_map_8M (TEST_PADDR, TEST_VADDR_NC, 0);
144         test_map_8M (TEST_PADDR, TEST_VADDR_C,  1);
145
146         test_map_8M (TEST_FLASH_ADDR & 0xFF800000, TEST_FLASH_ADDR & 0xFF800000, 0);
147
148         /* Configure GPIO ports */
149         signal_init();
150 }
151
152 static int test_burst_start (unsigned long size, unsigned long pattern)
153 {
154         volatile unsigned long * vaddr_c = (unsigned long *)TEST_VADDR_C;
155         volatile unsigned long * vaddr_nc = (unsigned long *)TEST_VADDR_NC;
156         int i, n;
157         int res = 1;
158
159         printf ("Test pattern %08x ...", pattern);
160
161         n = size / 4;
162
163         for (i = 0; i < n; i ++) {
164                 vaddr_c [i] = pattern;
165         }
166         signal_start();
167         flush_dcache_range((unsigned long)vaddr_c, (unsigned long)(vaddr_c + n) - 1);
168
169         for (i = 0; i < n; i ++) {
170                 register unsigned long tmp = vaddr_nc [i];
171                 if (tmp != pattern) {
172                         test_error("2a", vaddr_nc + i, tmp, pattern);
173                         goto Done;
174                 }
175         }
176
177         for (i = 0; i < n; i ++) {
178                 register unsigned long tmp = vaddr_c [i];
179                 if (tmp != pattern) {
180                         test_error("2b", vaddr_c + i, tmp, pattern);
181                         goto Done;
182                 }
183         }
184
185         for (i = 0; i < n; i ++) {
186                 vaddr_nc [i] = pattern;
187         }
188
189         for (i = 0; i < n; i ++) {
190                 register unsigned long tmp = vaddr_nc [i];
191                 if (tmp != pattern) {
192                         test_error("3a", vaddr_nc + i, tmp, pattern);
193                         goto Done;
194                 }
195         }
196
197         signal_start();
198         for (i = 0; i < n; i ++) {
199                 register unsigned long tmp = vaddr_c [i];
200                 if (tmp != pattern) {
201                         test_error("3b", vaddr_c + i, tmp, pattern);
202                         goto Done;
203                 }
204         }
205
206         res = 0;
207 Done:
208         printf(" %s\n", res == 0 ? "OK" : "");
209
210         return res;
211 }
212
213 static void test_map_8M (unsigned long paddr, unsigned long vaddr, int cached)
214 {
215         mtspr (MD_EPN, (vaddr & 0xFFFFFC00) | MI_EVALID);
216         mtspr (MD_TWC, MI_PS8MEG | MI_SVALID);
217         mtspr (MD_RPN, (paddr & 0xFFFFF000) | MI_BOOTINIT | (cached ? 0 : 2));
218         mtspr (MD_AP, MI_Kp);
219 }
220
221 static int test_mmu_is_on(void)
222 {
223         unsigned long msr;
224
225         asm volatile("mfmsr %0" : "=r" (msr) :);
226
227         return msr & MSR_DR;
228 }
229
230 static void test_desc(unsigned long size)
231 {
232         printf(
233         "The following tests will be conducted:\n"
234         "1)  Map %d-byte region of physical RAM at 0x%08x\n"
235         "    into two virtual regions:\n"
236         "    one cached at 0x%08x and\n"
237         "    the the other uncached at 0x%08x.\n",
238         size, TEST_PADDR, TEST_VADDR_NC, TEST_VADDR_C);
239
240         puts(
241         "2)  Fill the cached region with a pattern, and flush the cache\n"
242         "2a) Check the uncached region to match the pattern\n"
243         "2b) Check the cached region to match the pattern\n"
244         "3)  Fill the uncached region with a pattern\n"
245         "3a) Check the cached region to match the pattern\n"
246         "3b) Check the uncached region to match the pattern\n"
247         "2b) Change the patterns and go to step 2\n"
248         "\n"
249         );
250 }
251
252 static void test_error(
253         char * step, volatile void * addr, unsigned long val, unsigned long pattern)
254 {
255         volatile unsigned long * p = (void *)TEST_FLASH_ADDR;
256
257         signal_error();
258
259         p[0] = (unsigned long)addr;
260         p[1] = val;
261         p[2] = pattern;
262
263         printf ("\nError at step %s, addr %08x: read %08x, pattern %08x",
264                 step, addr, val, pattern);
265 }
266
267 static void signal_init(void)
268 {
269 #if defined(GPIO1_INIT)
270         GPIO1_INIT;
271 #endif
272 #if defined(GPIO2_INIT)
273         GPIO2_INIT;
274 #endif
275 }
276
277 static void signal_start(void)
278 {
279 #if defined(GPIO1_INIT)
280         if (GPIO1_DAT & GPIO1_BIT) {
281                 GPIO1_DAT &= ~GPIO1_BIT;
282         } else {
283                 GPIO1_DAT |= GPIO1_BIT;
284         }
285 #endif
286 }
287
288 static void signal_error(void)
289 {
290 #if defined(GPIO2_INIT)
291         if (GPIO2_DAT & GPIO2_BIT) {
292                 GPIO2_DAT &= ~GPIO2_BIT;
293         } else {
294                 GPIO2_DAT |= GPIO2_BIT;
295         }
296 #endif
297 }
298
299 static void test_usage(void)
300 {
301         printf("Usage: go 0x40004 [size]\n");
302 }