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