Submit FS#11253. Rework of test_mem plugin to bench DRAM and IRAM. Also add ARM assem...
[kugel-rb.git] / apps / plugins / test_mem.c
blobe8f54c3ba6f676005bcde21c04d19bf6fe4ad26a
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Thomas Martitz, Andree Buschmann
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "plugin.h"
24 PLUGIN_HEADER
26 #define BUF_SIZE (1<<13) /* 32 KB = (1<<13)*sizeof(int) */
28 #define LOOP_REPEAT_DRAM 256
29 static volatile int buf_dram[BUF_SIZE];
31 #if defined(PLUGIN_USE_IRAM)
32 #define LOOP_REPEAT_IRAM 1024
33 static volatile int buf_iram[BUF_SIZE] IBSS_ATTR;
34 #endif
36 /* (Byte per loop * loops)>>20 * ticks per s * 10 / ticks = dMB per s */
37 #define dMB_PER_SEC(cnt, delta) ((((BUF_SIZE*sizeof(int)*cnt)>>20)*HZ*10)/delta)
39 void write_test(volatile int *buf, int buf_size, int loop_cnt,
40 int line, char *ramtype)
42 int delta, dMB;
43 int last_tick = *rb->current_tick;
45 #if defined(CPU_ARM)
46 asm volatile (
47 "mov r0, #0 \n"
48 "mov r1, #1 \n"
49 "mov r2, #2 \n"
50 "mov r3, #3 \n"
51 "mov r6, %[loops] \n"
52 ".outer_loop_read: \n"
53 "mov r4, %[buf_p] \n"
54 "mov r5, %[size] \n"
55 ".inner_loop_read: \n"
56 "stmia r4!, {r0-r3} \n"
57 "stmia r4!, {r0-r3} \n"
58 "subs r5, r5, #8 \n"
59 "bgt .inner_loop_read \n"
60 "subs r6, r6, #1 \n"
61 "bgt .outer_loop_read \n"
63 : [loops] "r" (loop_cnt), [size] "r" (buf_size), [buf_p] "r" (buf)
64 : "r0", "r1", "r2", "r3", "r4", "r5", "r6"
66 #else
67 int i, j;
68 for(i = 0; i < loop_cnt; i++)
70 for (j = 0; j < buf_size; j+=4)
72 buf[j ] = j;
73 buf[j+1] = j+1;
74 buf[j+2] = j+2;
75 buf[j+3] = j+3;
78 #endif
79 delta = *rb->current_tick - last_tick;
80 delta = delta>0 ? delta : delta+1;
81 dMB = dMB_PER_SEC(loop_cnt, delta);
82 rb->screens[0]->putsf(0, line, "%s wr: %3d.%d MB/s (%2d ticks for %d MB)",
83 ramtype, dMB/10, dMB%10, delta,
84 (loop_cnt*BUF_SIZE*4)>>20);
87 void read_test(volatile int *buf, int buf_size, int loop_cnt,
88 int line, char *ramtype)
90 int delta, dMB;
91 int last_tick = *rb->current_tick;
93 #if defined(CPU_ARM)
94 asm volatile (
95 "mov r6, %[loops] \n"
96 ".outer_loop_write: \n"
97 "mov r4, %[buf_p] \n"
98 "mov r5, %[size] \n"
99 ".inner_loop_write: \n"
100 "ldmia r4!, {r0-r3} \n"
101 "ldmia r4!, {r0-r3} \n"
102 "subs r5, r5, #8 \n"
103 "bgt .inner_loop_write \n"
104 "subs r6, r6, #1 \n"
105 "bgt .outer_loop_write \n"
107 : [loops] "r" (loop_cnt), [size] "r" (buf_size), [buf_p] "r" (buf)
108 : "r0", "r1", "r2", "r3", "r4", "r5", "r6"
110 #else
111 int i, j, x;
112 for(i = 0; i < loop_cnt; i++)
114 for(j = 0; j < buf_size; j+=4)
116 x = buf[j ];
117 x = buf[j+2];
118 x = buf[j+3];
119 x = buf[j+4];
122 #endif
123 delta = *rb->current_tick - last_tick;
124 delta = delta>0 ? delta : delta+1;
125 dMB = dMB_PER_SEC(loop_cnt, delta);
126 rb->screens[0]->putsf(0, line, "%s rd: %3d.%d MB/s (%2d ticks for %d MB)",
127 ramtype, dMB/10, dMB%10, delta,
128 (loop_cnt*BUF_SIZE*4)>>20);
132 enum plugin_status plugin_start(const void* parameter)
134 (void)parameter;
135 bool done = false;
136 bool boost = false;
137 int count = 0;
139 rb->lcd_setfont(FONT_SYSFIXED);
141 rb->screens[0]->clear_display();
142 rb->screens[0]->putsf(0, 0, "patience, may take some seconds...");
143 rb->screens[0]->update();
145 while (!done)
147 int line = 0;
149 rb->screens[0]->clear_display();
150 rb->screens[0]->putsf(0, line++, "%s", boost?"boosted":"unboosted");
151 #ifndef SIMULATOR
152 rb->screens[0]->putsf(0, line++, "clock: %d Hz", *rb->cpu_frequency);
153 #endif
154 rb->screens[0]->putsf(0, line++, "loop#: %d", ++count);
156 read_test (buf_dram, BUF_SIZE, LOOP_REPEAT_DRAM, line++, "DRAM");
157 write_test(buf_dram, BUF_SIZE, LOOP_REPEAT_DRAM, line++, "DRAM");
158 #if defined(PLUGIN_USE_IRAM)
159 read_test (buf_iram, BUF_SIZE, LOOP_REPEAT_IRAM, line++, "IRAM");
160 write_test(buf_iram, BUF_SIZE, LOOP_REPEAT_IRAM, line++, "IRAM");
161 #endif
163 rb->screens[0]->update();
165 switch (rb->get_action(CONTEXT_STD, HZ/5))
167 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
168 case ACTION_STD_PREV:
169 if (!boost)
171 rb->cpu_boost(true);
172 boost = true;
174 break;
176 case ACTION_STD_NEXT:
177 if (boost)
179 rb->cpu_boost(false);
180 boost = false;
182 break;
183 #endif
184 case ACTION_STD_CANCEL:
185 done = true;
186 break;
190 return PLUGIN_OK;