]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/services/diagnosis/v2_0/src/memory/ram_pm.c
Initial revision
[karo-tx-redboot.git] / packages / services / diagnosis / v2_0 / src / memory / ram_pm.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 #define DEFAULT_TEST_TIME       2
9 #define MIN_TEST_TIME   1
10 #define MAX_TEST_TIME   20
11
12 #define DEFAULT_BLOCK_SIZE      4096
13 #define MAX_BLOCK_SIZE          32768
14 #define MIN_BLOCK_SIZE          1024
15
16 local_cmd_entry("ram_pm",
17         "ram performance test",
18         "-t time -b size [-m mode]\n"
19         "    -t time: set test time\n"
20         "    -b size: set block size < 8192\n"
21         "    -m mode: set 0:read, 1:write, 2:copy\n",
22         ram_pm_test,
23         DIAGNOSIS_cmds
24 );
25
26 enum {
27         RAM_PM_READ = 0,
28         RAM_PM_WRITE,
29         RAM_PM_COPY,
30         RAM_PM_MAX,
31 };
32
33 static char * mode_str[RAM_PM_MAX] =
34 {
35         "read",
36         "write",
37         "copy"
38 };
39
40 static inline void start_timer(int second)
41 {
42         unsigned int reg;
43         reg = readl(CCM_BASE_ADDR + CLKCTL_CGR1);
44         writel(reg | 0x30, CCM_BASE_ADDR + CLKCTL_CGR1);
45
46         reg = readl(GPT_BASE_ADDR + GPTCR) | 0x8002;
47         writel(reg&(~1), GPT_BASE_ADDR + GPTCR);
48         while(readl(GPT_BASE_ADDR + GPTCR) & 0x8000);
49
50         reg = second * 1000;
51         writel(reg, GPT_BASE_ADDR + GPTOCR1);
52         writel(0, GPT_BASE_ADDR + GPTIR);
53         writel(0, GPT_BASE_ADDR + GPTCNT);
54         writel(31, GPT_BASE_ADDR + GPTPR);
55         writel(0x3F, GPT_BASE_ADDR + GPTSR);
56
57         reg = readl(GPT_BASE_ADDR + GPTCR) | 0x303;
58         writel(reg, GPT_BASE_ADDR + GPTCR);
59 }
60
61 static inline int get_time(int * cycles)
62 {
63         *cycles = readl(GPT_BASE_ADDR + GPTCNT);
64         if (readl(GPT_BASE_ADDR + GPTSR)& 1)
65                 *cycles -= readl(GPT_BASE_ADDR + GPTOCR1);
66         return readl(GPT_BASE_ADDR + GPTSR) & 1;
67 }
68
69 static inline void stop_timer(void)
70 {
71         unsigned int reg;
72         reg = readl(GPT_BASE_ADDR + GPTCR) | 0x8000;
73         writel(reg&(~1), GPT_BASE_ADDR + GPTCR);
74 }
75
76 static int performance_read_write(int time, int bsize, int read)
77 {
78         unsigned long start = CYGMEM_REGION_ram + 1*1024*1024;
79         int size = CYGMEM_REGION_ram_SIZE / 2;
80         int cycles;
81         long long i;
82
83         if ( (bsize % 32) || (size % bsize) || size < (1*1024*1024)) {
84                 diag_printf("size is illegal(size=%d)\n", size);
85         }
86
87         size = (size / bsize) * bsize;
88         diag_printf("%s:size=%d, bsize=%d\n", read?"READ":"WRITE", size, bsize);
89         start_timer(time);
90         for (i=0; !get_time(&cycles); i += bsize) {
91                 if (read)
92                         diagnosis_mem_read_block(start + (i % size), bsize);
93                 else
94                         diagnosis_mem_write_block(start + (i % size), bsize);
95         }
96         stop_timer();
97         diag_printf("Finished size=%ld ", i);
98         diag_printf("time=%d", time);
99         diag_printf(" %d(ms)\n", cycles);
100         i = (i * 1000) / ((time * 1000) + cycles);
101         return i / 1024;
102 }
103
104 static int performance_copy(int time, int bsize)
105 {
106         unsigned long start = CYGMEM_REGION_ram + 1 * 1024 * 1024;
107         unsigned long dest = start + 1 * 1024 * 1024;
108         int size = CYGMEM_REGION_ram_SIZE / 4;
109         int cycles;
110         long long i;
111
112         dest += size;
113
114         if ( (bsize % 32) || (size % bsize) || size < (1 * 1024 * 1024)) {
115                 diag_printf("size is illegal(size=%d)\n", size);
116         }
117
118         start_timer(time);
119
120         size = (size / bsize) * bsize;
121         for (i = 0; !get_time(&cycles); i += bsize) {
122                 if (diagnosis_mem_copy_block(start + (i % size),
123                                             dest + (i % size), bsize)
124                                                 < 0) {
125                         diag_printf("verify data fail\n");
126                         break;
127                 }
128         }
129         stop_timer();
130         i = (i * 1000) / ((time * 1000) + cycles);
131         return i / 1024;
132 }
133
134 static void ram_pm_test(int argc, char * argv[])
135 {
136         int opts_map[3];
137         struct option_info opts[3];
138         int time, mode, result, bsize;
139
140         memset(opts_map, 0, sizeof(int)*2);
141         init_opts(&opts[0], 't', true, OPTION_ARG_TYPE_NUM,
142                  (void *)&time, (bool *)&opts_map[0], "test time");
143         init_opts(&opts[1], 'b', true, OPTION_ARG_TYPE_NUM,
144                  (void *)&bsize, (bool *)&opts_map[1], "block size");
145         init_opts(&opts[2], 'm', true, OPTION_ARG_TYPE_NUM,
146                  (void *)&mode, (bool *)&opts_map[2], "operate mode");
147
148         if (!scan_opts(argc, argv, 2, opts, 3, 0, 0, 0)) {
149                 diagnosis_usage("invalid arguments");
150                 return;
151         }
152
153         if (!opts_map[0] || time < MIN_TEST_TIME || time > MAX_TEST_TIME)
154                 time = DEFAULT_TEST_TIME;
155
156         if(!opts_map[1] || bsize < MIN_BLOCK_SIZE || bsize > MAX_BLOCK_SIZE)
157                 bsize = DEFAULT_BLOCK_SIZE;
158
159         if (!opts_map[2] || mode >= RAM_PM_MAX)
160                 mode = RAM_PM_READ;
161
162         diag_printf("Start memory performance test (%s)...\n",
163                 mode_str[mode]);
164         switch(mode) {
165         case RAM_PM_READ:
166                 result = performance_read_write(time, bsize, 1);
167                 break;
168         case RAM_PM_WRITE:
169                 result = performance_read_write(time, bsize, 0);
170                 break;
171         case RAM_PM_COPY:
172                 result = performance_copy(time, bsize);
173                 break;
174         default:
175                 result = -1;
176         }
177         if (result < 0) {
178                 diag_printf("memory performance test fails\n");
179         } else {
180                 diag_printf("memory performance test success:%d.%d(MB/s)\n",
181                               result / 1024, (result % 1024));
182         }
183 }