unload fix, manual unload
[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>
14
15#if 1
198a1649 16#include "warm.h"
38e809e1 17#else
18#define warm_init(...) 0
19#define warm_finish(...)
20#define warm_cache_op_range(...)
21#define warm_change_cb_range(...)
22#endif
23
24typedef unsigned long long u64;
25static u64 start_time, end_time;
26
27static unsigned char buff[8 * 1024 * 1024] __attribute__((aligned(32)));
28static unsigned char *buff_mid = &buff[8 * 1024 * 1024 / 2];
29
30static u64 xtime(void)
31{
32 struct timeval tv;
33 gettimeofday(&tv, NULL);
34 return (u64)tv.tv_sec * 1000000 + tv.tv_usec;
35}
36
37static void test_start(void)
38{
39 start_time = xtime();
40}
41
42static void test_end(void)
43{
44 end_time = xtime();
45}
46
47static void show_result(const char *name, int bytes)
48{
49 double secs = (end_time - start_time) / 1000000.0;
50 printf("%-16s: %4.1fs, %5.1f MB/s\n", name, secs, bytes / secs / 1048576);
51}
52
53static void do_memset(void)
54{
55 memset(buff, 0, sizeof(buff));
56}
57
58static void byte_fill(void)
59{
60 char *p = (void *)buff;
61 int i;
62 for (i = sizeof(buff); i > 0; i--)
63 *p++ = 0;
64}
65
66static void word_fill(void)
67{
68 long *p = (void *)buff;
69 int i;
70 for (i = sizeof(buff) / sizeof(*p); i > 0; i--)
71 *p++ = 0;
72}
73
74static void do_memcpy(void)
75{
76 memcpy(buff, buff_mid, sizeof(buff) / 2);
77}
78
79static void byte_cpy(void)
80{
81 char *d = (void *)buff;
82 char *s = (void *)buff_mid;
83 int i;
84 for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
85 *d++ = *s++;
86}
87
88static void word_cpy(void)
89{
90 long *d = (void *)buff;
91 long *s = (void *)buff_mid;
92 int i;
93 for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
94 *d++ = *s++;
95}
96
97static void word_inc(void)
98{
99 long *p = (void *)buff;
100 int i;
101
102 for (i = sizeof(buff) / sizeof(*p); i > 0; i--) {
103 (*p)++;
104 p++;
105 }
106}
107
108#define ONE_TEST(count, func) \
109 test_start(); \
110 for (i = count; i > 0; i--) \
111 func(); \
112 test_end()
113
114static void tests(void)
115{
116 int i;
117
118 ONE_TEST(64, do_memset);
119 show_result("memset", sizeof(buff) * 64);
120
121 ONE_TEST(64, byte_fill);
122 show_result("byte fill", sizeof(buff) * 64);
123
124 ONE_TEST(64, word_fill);
125 show_result("word fill", sizeof(buff) * 64);
126
127 ONE_TEST(128, do_memcpy);
128 show_result("memcpy", sizeof(buff) * 128 / 2);
129
130 ONE_TEST(128, byte_cpy);
131 show_result("byte copy", sizeof(buff) * 128 / 2);
132
133 ONE_TEST(128, word_cpy);
134 show_result("word copy", sizeof(buff) * 128 / 2);
135
136 ONE_TEST(64, word_inc);
137 show_result("word inc", sizeof(buff) * 64);
138
139 usleep(200000);
140}
141
142#if 1
143#include <sys/types.h>
144#include <sys/stat.h>
145#include <fcntl.h>
146#include <sys/mman.h>
147
148void coherency_test(void)
149{
150 volatile unsigned char *buff_mapped;
151 volatile unsigned char *buff_vol;
cc951732 152 unsigned long buff_phys, mapped_phys, align;
153 unsigned char buff_mapped_vals[6];
38e809e1 154 unsigned char buff_vals[5];
155 int random_offs;
156 int memdev;
157
158 srand(time(NULL));
159
cc951732 160 buff_phys = warm_virt2phys(buff_mid);
38e809e1 161 align = buff_phys & 0xfff;
162
163 memdev = open("/dev/mem", O_RDONLY | O_SYNC);
164 if (memdev < 0) {
165 perror("open /dev/mem");
166 return;
167 }
168
cc951732 169 /* the mapping is valid for 1 page only.
170 * Also it doesn't work for GP2X F100 (2.4 kernels?),
171 * only upper mem maps correctly there. */
38e809e1 172 buff_mapped = mmap(NULL, 0x1000, PROT_READ,
173 MAP_SHARED, memdev, buff_phys & ~0xfff);
174 if (buff_mapped == MAP_FAILED) {
175 perror("mmap buff");
176 return;
177 }
178 buff_mapped += align;
179
cc951732 180 buff_mapped_vals[5] = buff_mapped[0]; /* touch */
181 mapped_phys = warm_virt2phys((void *)buff_mapped);
182 if (buff_phys != mapped_phys)
183 printf("warning: mmap requested %08lx, got %08lx\n", buff_phys, mapped_phys);
184
38e809e1 185 random_offs = rand() % (0x1000 - align);
186
cc951732 187 buff_vol = (volatile void *)buff_mid;
38e809e1 188 buff_vals[0] = buff_vol[random_offs]; buff_mapped_vals[0] = buff_mapped[random_offs];
189
190 /* incremented: */
191 buff_vol[random_offs]++;
192 buff_vals[1] = buff_vol[random_offs]; buff_mapped_vals[1] = buff_mapped[random_offs];
193
194 /* cleaned: */
195 warm_cache_op_range(WOP_D_CLEAN, (char *)buff_vol + random_offs, 32);
196 buff_vals[2] = buff_vol[random_offs]; buff_mapped_vals[2] = buff_mapped[random_offs];
197
198 /* incremented: */
199 buff_vol[random_offs]++;
200 buff_vals[3] = buff_vol[random_offs]; buff_mapped_vals[3] = buff_mapped[random_offs];
201
202 /* invalidated: */
203 warm_cache_op_range(WOP_D_INVALIDATE, (char *)buff_vol + random_offs, 32);
204 buff_vals[4] = buff_vol[random_offs]; buff_mapped_vals[4] = buff_mapped[random_offs];
205
206 printf("buff is @ %p -> %lx, mapped %p, random offset %x\n", buff_vol, buff_phys,
207 buff_mapped, random_offs);
208 printf("val: %02x, mmaped: %02x\n", buff_vals[0], buff_mapped_vals[0]);
209
210 printf("incremented:\n");
211 printf("val: %02x, mmaped: %02x\n", buff_vals[1], buff_mapped_vals[1]);
212
213 printf("cleaned:\n");
214 printf("val: %02x, mmaped: %02x\n", buff_vals[2], buff_mapped_vals[2]);
215
216 printf("incremented:\n");
217 printf("val: %02x, mmaped: %02x\n", buff_vals[3], buff_mapped_vals[3]);
218
219 printf("invalidated:\n");
220 printf("val: %02x, mmaped: %02x\n", buff_vals[4], buff_mapped_vals[4]);
221}
222#else
223#define coherency_test()
224#endif
198a1649 225
226int main()
227{
38e809e1 228 int ret;
229
230 ret = warm_init();
231 if (ret != 0)
232 {
233 printf("init failed.\n");
234 return 1;
235 }
236
237 printf("buff: %p - %p\n", buff, buff + sizeof(buff) - 1);
238
239 printf("-- default --\n");
240 tests();
241
242 printf("-- ncnb --\n");
243 warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 0, buff, sizeof(buff));
244 tests();
245
246 printf("-- nc b --\n");
247 warm_change_cb_range(WCB_B_BIT, 1, buff, sizeof(buff));
248 tests();
249
250 printf("-- cnb --\n");
251 warm_change_cb_range(WCB_C_BIT, 1, buff, sizeof(buff));
252 warm_change_cb_range(WCB_B_BIT, 0, buff, sizeof(buff));
253 tests();
254
255 warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 1, buff, sizeof(buff));
256 coherency_test();
257
258 warm_finish();
198a1649 259
260 return 0;
261}
262