]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/diagnosis/v2_0/src/memory/ram_rw.c
TX51 pre-release
[karo-tx-redboot.git] / packages / services / diagnosis / v2_0 / src / memory / ram_rw.c
1 #include <redboot.h>
2 #include <stdlib.h>
3 #include <cyg/diagnosis/diagnosis.h>
4 #include <cyg/hal/plf_io.h>
5
6 #include CYGHWR_MEMORY_LAYOUT_H
7
8 static int loops1;
9 static unsigned int pattern1, pattern2;
10 static unsigned int start;
11 static int length;
12 static int burst = 0;
13
14 local_cmd_entry("ram_rw",
15          "ram read/write accessing",
16         "-c iterators -b <base address> -l <length> "\
17         "-p pattern -m case [-s]\n",
18         ram_rw_test,
19         DIAGNOSIS_cmds
20 );
21
22 local_cmd_entry("memcpybm",
23         "ram memory copy benchmarking",
24         "-c <loops> -s <start size KB> -e <end size KB>  -a <source align Byte> -b <dest align Byte>\n",
25         memcpybm,
26         DIAGNOSIS_cmds
27 );
28
29 static void raw_rw_case1(void)
30 {
31         unsigned int * current_write;
32         unsigned int * current_read;
33         int round = 0;
34         diag_printf("RAM diagnostical pattern from David.Young of freescale\n");
35         diag_printf("burst is %s\n", burst?"enabled":"disabled");
36         while( (round++) < loops1) {
37                 if (_rb_break(0))
38                         return;
39                 if (burst) {
40                         current_write = (unsigned int *)start;
41                         memset(current_write, (pattern1 & 0xFF000000) >> 24, length);
42                 } else {
43                         for (current_write = (unsigned int *)start;
44                                 current_write < (unsigned int *)(start + length);
45                                 current_write += 2) {
46                                 *current_write = ((unsigned int)current_write & 0x0000FFFF) |
47                                         (0xFFFF0000 & pattern1);
48                         }
49                         for (current_write = (unsigned int *)start + 1;
50                                 current_write < (unsigned int *)(start + length);
51                                  current_write += 2) {
52                                 *current_write = ((unsigned int)current_write & 0x0000FFFF) |
53                                         (0xFFFF0000 & pattern2);
54                         }
55                 }
56                 for (current_read = (unsigned int *)start;
57                          current_read<(unsigned int *)(start + length);
58                          current_read ++) {
59                         if (burst) {
60                                 if ((*current_read) != pattern2) {
61                                         diag_printf("\tround %d::[%p]=0x%08x:0x%08x\n", round,
62                                                                 current_read, pattern2, *current_read);
63                                         goto fail;
64                                 }
65                         } else {
66                                 if((current_read - (unsigned int *)start) & 1) {
67                                         if(((*current_read)&0xFFFF0000) != (pattern2&0xFFFF0000)) {
68                                                 diag_printf("\tround %d::[%p]=0x%08x:0x%08x\n", round,
69                                                                         current_read, (pattern2 & 0xFFFF0000) |
70                                                                         (((unsigned int)current_read) & 0xFFFF),
71                                                                         *current_read);
72                                                 goto fail;
73                                         }
74                                 } else {
75                                         if(((*current_read)&0xFFFF0000) != (pattern1&0xFFFF0000)) {
76                                                 diag_printf("\tround %d::[%p]=0x%08x:0x%08x\n", round,
77                                                                         current_read, (pattern1 & 0xFFFF0000) |
78                                                                         (((unsigned int)current_read) & 0xFFFF),
79                                                                         *current_read);
80                                                 goto fail;
81                                         }
82                                 }
83                         }
84                 }
85         }
86         diag_printf("Diagnosis is successful!\n");
87         return;
88 fail:
89         diag_printf("Diagnosis is failure !\n");
90 }
91
92 static void ram_rw_test(int argc, char * argv[])
93 {
94         int opts_map[6];
95         struct option_info opts[6];
96         int mode;
97
98         memset(opts_map, 0, sizeof(int)*6);
99
100         init_opts(&opts[0], 'c', true, OPTION_ARG_TYPE_NUM,
101                  &loops1, &opts_map[0], "the rounds of test");
102         init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
103                  &start, &opts_map[1], "accessing start address");
104         init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM,
105                  &length, &opts_map[2], "accessing size(bytes)");
106         init_opts(&opts[3], 'p', true, OPTION_ARG_TYPE_NUM,
107                  &pattern1, &opts_map[3], "High 16bit is valid");
108         init_opts(&opts[4], 'm', true, OPTION_ARG_TYPE_NUM,
109                  &mode, &opts_map[4], "Test case number");
110         init_opts(&opts[5], 's', false, OPTION_ARG_TYPE_FLG,
111                  &burst, NULL, "enable bust mode(based on memset)");
112
113         if (!scan_opts(argc, argv, 2, opts, 6, 0, 0, 0)) {
114                 diagnosis_usage("invalid arguments");
115                 return;
116         }
117
118         if (!opts_map[0]) {
119                 loops1 = 32;
120         }
121
122         if (!opts_map[1]) {
123                 start = 0x80000;
124         }
125
126         if (!opts_map[2]) {
127                 length = 8192;
128         }
129
130         if (!opts_map[3]) {
131                 pattern1 = 0x55550000;
132         }
133
134         if (!opts_map[4]) {
135                 mode = DIAGNOSIS_MEM_RAM_RD;
136         }
137
138         if (burst) {
139                 pattern2 = (pattern1&0xFF000000);
140                 pattern2 |= pattern2>>8;
141                 pattern2 |= pattern2>>16;
142         } else {
143                 pattern2 = (~pattern1)&0xFFFF0000;
144         }
145
146         if(!valid_address((unsigned char *)start)) {
147                 if (!verify_action("Specified address (%p) is not believed to be in RAM", (void*)start))
148                         return;
149         }
150
151         switch(mode) {
152         case DIAGNOSIS_MEM_RAM_RD:
153                 raw_rw_case1();
154                 break;
155         default:
156                 diag_printf("Invalid memory diagnosis case!\n");
157         }
158 }
159
160 /* Defines */
161 #define SIZE_1K                 1024
162 #define SIZE_4K                 (4*SIZE_1K)
163 #define SIZE_1M                 (1024*1024)
164 #define START_SIZE              (2*SIZE_1K)
165 #define END_SIZE                SIZE_1M
166 #define ALIGN                   SIZE_4K
167 #define START_LOOPS             200000
168
169 #define OPT_SIZE        5
170 #define printf          diag_printf
171 #define CLOCKS_PER_SEC  32768
172 extern unsigned int hal_timer_count(void);
173 #define clock()         hal_timer_count()
174
175 //#define memcpy diagnosis_mem_copy_block
176 static void memcpybm(int argc, char * argv[])
177 {
178         int opts_map[OPT_SIZE];
179         struct option_info opts[OPT_SIZE];
180         int size = START_SIZE / SIZE_1K;
181         int end_size = END_SIZE / SIZE_1K;
182         int salign = ALIGN;
183         int dalign = ALIGN;
184         int loops = START_LOOPS / 1000;
185         int src, dst, asrc, adst;
186
187
188         memset(opts_map, 0, sizeof(int)*OPT_SIZE);
189
190         init_opts(&opts[0], 'c', true, OPTION_ARG_TYPE_NUM,
191                  &loops, &opts_map[0], "the rounds of test in thousands");
192         init_opts(&opts[1], 's', true, OPTION_ARG_TYPE_NUM,
193                  &size, &opts_map[1], "start size in KB");
194         init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM,
195                  &end_size, &opts_map[2], "end size in KB");
196         init_opts(&opts[3], 'a', true, OPTION_ARG_TYPE_NUM,
197                  &salign, &opts_map[3], "source align in byte");
198         init_opts(&opts[4], 'b', true, OPTION_ARG_TYPE_NUM,
199                  &dalign, &opts_map[4], "destination align in byte");
200
201         if (!scan_opts(argc, argv, 2, opts, OPT_SIZE, 0, 0, 0)) {
202                 diagnosis_usage("invalid arguments");
203                 return;
204         }
205
206         loops *= 1000;
207         size *=  SIZE_1K;
208         end_size *= SIZE_1K;
209         /* Allocate buffers */
210         if ((src = (int) malloc(end_size + salign + SIZE_4K)) == 0) {
211                 printf("%s: insufficient memory\n", argv[0]);
212                 return;
213         }
214         memset((void*)src, 0xaa, end_size + salign + SIZE_4K);
215         if ((dst = (int) malloc(end_size + dalign + SIZE_4K)) == 0) {
216                 free((void*)src);
217                 printf("%s: insuficient memory\n", argv[0]);
218                 return;
219         }
220         memset((void*)dst, 0x55, end_size + dalign + SIZE_4K);
221
222         /* Align buffers */
223         if (src % SIZE_4K == 0)
224                 asrc = src + salign;
225         else
226                 asrc = src + SIZE_4K - (src % SIZE_4K) + salign;
227         if (dst % SIZE_4K == 0)
228                 adst = dst + dalign;
229         else
230                 adst = dst + SIZE_4K - (dst % SIZE_4K) + dalign;
231
232         /* Print Banner */
233         printf("\nMEMCPY Benchmark\n\n");
234         printf("Src Buffer 0x%08x\n", asrc);
235         printf("Dst Buffer 0x%08x\n\n", adst);
236         printf("%10s %10s\n", "Cached", "Bandwidth");
237         printf("%10s %10s\n", "(KBytes)", "(MB/sec)");
238
239         /* Loop over copy sizes */
240         while (size <= end_size)
241         {
242                 unsigned int start_time;
243                 unsigned int elapsed_time;
244                 int loop;
245                 unsigned long long sz;
246
247                 printf("%10d", size / SIZE_1K);
248
249                 /* Do data copies */
250                 start_time = clock();
251                 for (loop = 0; loop < loops; loop++)
252                         memcpy((void*)adst, (void*)asrc, size);
253                 elapsed_time = (clock() - start_time);
254
255                 sz = size *loops * 2;
256                 printf("   %llu", sz * CLOCKS_PER_SEC / elapsed_time / SIZE_1M);
257                 printf("\t elapsed=%u", elapsed_time);
258                 printf("\tsize=%d, loops=%d, sz=%llu", size, loops, sz);
259                 printf("\n");
260
261 /*
262                 printf(" %10.0f\n", ((float)size*loops*2)/elapsed_time/SIZE_1M);
263                 printf("   %d.%d.%d\n", elapsed_time / CLOCKS_PER_SEC,
264                (elapsed_time % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC,
265                (((elapsed_time % CLOCKS_PER_SEC) * 1000) % CLOCKS_PER_SEC) * 1000 / CLOCKS_PER_SEC);
266 */
267                 /* Adjust for next test */
268                 size *= 2;
269                 loops /= 2;
270         }
271
272         /* Free buffers */
273         free((void*)src);
274         free((void*)dst);
275 }
276