r3 release
[warm.git] / test.c
CommitLineData
38e809e1 1/*
2 * wARM functionality test
3 *
4 * written by GraÅžvydas "notaz" Ignotas
5 *
6 * see warm.c for license info
7 */
198a1649 8#include <stdio.h>
38e809e1 9#include <stdlib.h>
10#include <string.h>
11#include <sys/time.h>
12#include <time.h>
13#include <unistd.h>
87956811 14#include <sys/ioctl.h>
15#include <sys/mman.h>
16#include <sys/types.h>
17#include <sys/stat.h>
18#include <fcntl.h>
19#include <linux/fb.h>
38e809e1 20
21#if 1
198a1649 22#include "warm.h"
38e809e1 23#else
24#define warm_init(...) 0
25#define warm_finish(...)
26#define warm_cache_op_range(...)
27#define warm_change_cb_range(...)
28#endif
29
30typedef unsigned long long u64;
31static u64 start_time, end_time;
32
87956811 33static unsigned char buff[2 * 1024 * 1024] __attribute__((aligned(32)));
34static unsigned char *buff_mid = &buff[sizeof(buff) / 2];
35
36#define REP 32
38e809e1 37
38static u64 xtime(void)
39{
40 struct timeval tv;
41 gettimeofday(&tv, NULL);
42 return (u64)tv.tv_sec * 1000000 + tv.tv_usec;
43}
44
45static void test_start(void)
46{
47 start_time = xtime();
48}
49
50static void test_end(void)
51{
52 end_time = xtime();
53}
54
55static void show_result(const char *name, int bytes)
56{
57 double secs = (end_time - start_time) / 1000000.0;
58 printf("%-16s: %4.1fs, %5.1f MB/s\n", name, secs, bytes / secs / 1048576);
59}
60
61static void do_memset(void)
62{
63 memset(buff, 0, sizeof(buff));
64}
65
66static void byte_fill(void)
67{
68 char *p = (void *)buff;
69 int i;
70 for (i = sizeof(buff); i > 0; i--)
71 *p++ = 0;
72}
73
74static void word_fill(void)
75{
76 long *p = (void *)buff;
77 int i;
78 for (i = sizeof(buff) / sizeof(*p); i > 0; i--)
79 *p++ = 0;
80}
81
87956811 82static void cached_byte_fill(void)
83{
84 char *p = (void *)buff;
85 int i, j, v;
86
87 for (i = sizeof(buff) / 32; i > 0; i--) {
88 v += *p;
89 for (j = 32; j > 0; j--)
90 *p++ = v;
91 }
92}
93
38e809e1 94static void do_memcpy(void)
95{
96 memcpy(buff, buff_mid, sizeof(buff) / 2);
97}
98
99static void byte_cpy(void)
100{
101 char *d = (void *)buff;
102 char *s = (void *)buff_mid;
103 int i;
104 for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
105 *d++ = *s++;
106}
107
108static void word_cpy(void)
109{
110 long *d = (void *)buff;
111 long *s = (void *)buff_mid;
112 int i;
113 for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
114 *d++ = *s++;
115}
116
117static void word_inc(void)
118{
119 long *p = (void *)buff;
120 int i;
121
122 for (i = sizeof(buff) / sizeof(*p); i > 0; i--) {
123 (*p)++;
124 p++;
125 }
126}
127
87956811 128#define TEST_PAGE 4096
129
130static void page_writes_ref(void *buf)
131{
132 long *d = buf;
133 int i, j;
134
135 for (j = 0; j < 0x100000 / TEST_PAGE; j++)
136 for (i = 0; i < TEST_PAGE / 4; i++)
137 d[j * TEST_PAGE / 4 + i] = 0;
138}
139
140static void page_inc_ref(void *buf)
141{
142 long *d = buf;
143 int i, j;
144
145 for (j = 0; j < 0x100000 / TEST_PAGE; j++)
146 for (i = 0; i < TEST_PAGE / 4; i++)
147 d[j * TEST_PAGE / 4 + i]++;
148}
149
150static void page_writes(void *buf)
151{
152 long *d = buf;
153 int i, j;
154
155 for (i = 0; i < TEST_PAGE / 4; i++)
156 for (j = 0; j < 0x100000 / TEST_PAGE; j++)
157 d[j * TEST_PAGE / 4 + i] = 0;
158}
159
160static void page_inc(void *buf)
161{
162 long *d = buf;
163 int i, j;
164
165 for (i = 0; i < TEST_PAGE / 4; i++)
166 for (j = 0; j < 0x100000 / TEST_PAGE; j++)
167 d[j * TEST_PAGE / 4 + i]++;
168}
169
38e809e1 170#define ONE_TEST(count, func) \
171 test_start(); \
172 for (i = count; i > 0; i--) \
87956811 173 func; \
38e809e1 174 test_end()
175
176static void tests(void)
177{
178 int i;
179
87956811 180 ONE_TEST(REP, do_memset());
181 show_result("memset", sizeof(buff) * REP);
182
183 ONE_TEST(REP, byte_fill());
184 show_result("byte fill", sizeof(buff) * REP);
38e809e1 185
87956811 186 ONE_TEST(REP, word_fill());
187 show_result("word fill", sizeof(buff) * REP);
38e809e1 188
87956811 189 ONE_TEST(REP, cached_byte_fill());
190 show_result("c. byte fill", sizeof(buff) * REP);
38e809e1 191
87956811 192 ONE_TEST(REP * 2, do_memcpy());
193 show_result("memcpy", sizeof(buff) * REP);
38e809e1 194
87956811 195 ONE_TEST(REP * 2, byte_cpy());
196 show_result("byte copy", sizeof(buff) * REP);
38e809e1 197
87956811 198 ONE_TEST(REP * 2, word_cpy());
199 show_result("word copy", sizeof(buff) * REP);
38e809e1 200
87956811 201 ONE_TEST(REP, word_inc());
202 show_result("word inc", sizeof(buff) * REP);
38e809e1 203
204 usleep(200000);
205}
206
87956811 207static void page_tests(void *buf)
208{
209 int i;
210
211 ONE_TEST(REP, page_writes(buf));
212 show_result("page_writes", 0x100000 * REP);
213
214 ONE_TEST(REP, page_inc(buf));
215 show_result("page_inc", 0x100000 * REP);
216}
217
38e809e1 218#if 1
219#include <sys/types.h>
220#include <sys/stat.h>
221#include <fcntl.h>
222#include <sys/mman.h>
223
224void coherency_test(void)
225{
226 volatile unsigned char *buff_mapped;
227 volatile unsigned char *buff_vol;
cc951732 228 unsigned long buff_phys, mapped_phys, align;
229 unsigned char buff_mapped_vals[6];
38e809e1 230 unsigned char buff_vals[5];
231 int random_offs;
232 int memdev;
233
234 srand(time(NULL));
235
cc951732 236 buff_phys = warm_virt2phys(buff_mid);
38e809e1 237 align = buff_phys & 0xfff;
238
239 memdev = open("/dev/mem", O_RDONLY | O_SYNC);
240 if (memdev < 0) {
241 perror("open /dev/mem");
242 return;
243 }
244
cc951732 245 /* the mapping is valid for 1 page only.
246 * Also it doesn't work for GP2X F100 (2.4 kernels?),
247 * only upper mem maps correctly there. */
38e809e1 248 buff_mapped = mmap(NULL, 0x1000, PROT_READ,
249 MAP_SHARED, memdev, buff_phys & ~0xfff);
250 if (buff_mapped == MAP_FAILED) {
251 perror("mmap buff");
252 return;
253 }
254 buff_mapped += align;
255
cc951732 256 buff_mapped_vals[5] = buff_mapped[0]; /* touch */
257 mapped_phys = warm_virt2phys((void *)buff_mapped);
258 if (buff_phys != mapped_phys)
259 printf("warning: mmap requested %08lx, got %08lx\n", buff_phys, mapped_phys);
260
38e809e1 261 random_offs = rand() % (0x1000 - align);
262
cc951732 263 buff_vol = (volatile void *)buff_mid;
38e809e1 264 buff_vals[0] = buff_vol[random_offs]; buff_mapped_vals[0] = buff_mapped[random_offs];
265
266 /* incremented: */
267 buff_vol[random_offs]++;
268 buff_vals[1] = buff_vol[random_offs]; buff_mapped_vals[1] = buff_mapped[random_offs];
269
270 /* cleaned: */
271 warm_cache_op_range(WOP_D_CLEAN, (char *)buff_vol + random_offs, 32);
272 buff_vals[2] = buff_vol[random_offs]; buff_mapped_vals[2] = buff_mapped[random_offs];
273
274 /* incremented: */
275 buff_vol[random_offs]++;
276 buff_vals[3] = buff_vol[random_offs]; buff_mapped_vals[3] = buff_mapped[random_offs];
277
278 /* invalidated: */
279 warm_cache_op_range(WOP_D_INVALIDATE, (char *)buff_vol + random_offs, 32);
280 buff_vals[4] = buff_vol[random_offs]; buff_mapped_vals[4] = buff_mapped[random_offs];
281
282 printf("buff is @ %p -> %lx, mapped %p, random offset %x\n", buff_vol, buff_phys,
283 buff_mapped, random_offs);
284 printf("val: %02x, mmaped: %02x\n", buff_vals[0], buff_mapped_vals[0]);
285
286 printf("incremented:\n");
287 printf("val: %02x, mmaped: %02x\n", buff_vals[1], buff_mapped_vals[1]);
288
289 printf("cleaned:\n");
290 printf("val: %02x, mmaped: %02x\n", buff_vals[2], buff_mapped_vals[2]);
291
292 printf("incremented:\n");
293 printf("val: %02x, mmaped: %02x\n", buff_vals[3], buff_mapped_vals[3]);
294
295 printf("invalidated:\n");
296 printf("val: %02x, mmaped: %02x\n", buff_vals[4], buff_mapped_vals[4]);
297}
298#else
299#define coherency_test()
300#endif
198a1649 301
302int main()
303{
87956811 304 struct fb_fix_screeninfo fbfix;
305 void *mmap_mem;
306 void *section_mem;
307 int fbdev;
308 int i, ret;
38e809e1 309
310 ret = warm_init();
311 if (ret != 0)
312 {
313 printf("init failed.\n");
314 return 1;
315 }
316
317 printf("buff: %p - %p\n", buff, buff + sizeof(buff) - 1);
318
87956811 319 // prefault
320 do_memset();
321
38e809e1 322 printf("-- default --\n");
323 tests();
324
325 printf("-- ncnb --\n");
326 warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 0, buff, sizeof(buff));
327 tests();
328
329 printf("-- nc b --\n");
330 warm_change_cb_range(WCB_B_BIT, 1, buff, sizeof(buff));
331 tests();
332
333 printf("-- cnb --\n");
334 warm_change_cb_range(WCB_C_BIT, 1, buff, sizeof(buff));
335 warm_change_cb_range(WCB_B_BIT, 0, buff, sizeof(buff));
336 tests();
337
87956811 338 //printf("-- c b --\n");
38e809e1 339 warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 1, buff, sizeof(buff));
87956811 340 //tests();
341
38e809e1 342 coherency_test();
343
87956811 344 mmap_mem = mmap((void *)0x60000000, 0x100000, PROT_READ | PROT_WRITE,
345 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
346
347 // find safe location for section map, we'll use fb
348 fbdev = open("/dev/fb0", O_RDWR);
349 if (fbdev == -1) {
350 perror("fb open");
351 goto out;
352 }
353
354 ret = ioctl(fbdev, FBIOGET_FSCREENINFO, &fbfix);
355 if (ret == -1) {
356 perror("ioctl(fbdev)");
357 goto out;
358 }
359
360 section_mem = (void *)0x70000000;
361 ret = warm_mmap_section(section_mem, fbfix.smem_start, 0x100000,
362 WCB_C_BIT|WCB_B_BIT);
363 if (ret != 0) {
364 fprintf(stderr, "section map failed\n");
365 goto out;
366 }
367
368 // prefault
369 memset(mmap_mem, 0, 0x100000);
370 memset(section_mem, 0, 0x100000);
371
372 ONE_TEST(REP, page_writes_ref(mmap_mem));
373 show_result("page_wr_ref_m", 0x100000 * REP);
374
375 ONE_TEST(REP, page_inc_ref(mmap_mem));
376 show_result("page_inc_ref_m", 0x100000 * REP);
377
378 ONE_TEST(REP, page_writes_ref(section_mem));
379 show_result("page_wr_ref_s", 0x100000 * REP);
380
381 ONE_TEST(REP, page_inc_ref(section_mem));
382 show_result("page_inc_ref_s", 0x100000 * REP);
383
384 printf("== pages ==\n");
385 page_tests(mmap_mem);
386
387 printf("== section ==\n");
388 printf("-- default --\n");
389 page_tests(section_mem);
390
391 printf("-- ncnb --\n");
392 warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 0, section_mem, 0x100000);
393 page_tests(section_mem);
394
395 printf("-- nc b --\n");
396 warm_change_cb_range(WCB_B_BIT, 1, section_mem, 0x100000);
397 page_tests(section_mem);
398
399 printf("-- cnb --\n");
400 warm_change_cb_range(WCB_C_BIT, 1, section_mem, 0x100000);
401 warm_change_cb_range(WCB_B_BIT, 0, section_mem, 0x100000);
402 page_tests(section_mem);
403
404 warm_munmap_section(section_mem, 0x100000);
405
406out:
38e809e1 407 warm_finish();
198a1649 408
409 return 0;
410}
411