PageRenderTime 44ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/warm/test.c

https://github.com/nirvous/gpsp_lf1000
C | 262 lines | 194 code | 54 blank | 14 comment | 13 complexity | 4bdcaab45d7236272a3e4e4e2f499e9d MD5 | raw file
Possible License(s): GPL-2.0
  1. /*
  2. * wARM functionality test
  3. *
  4. * written by GraÅžvydas "notaz" Ignotas
  5. *
  6. * see warm.c for license info
  7. */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <sys/time.h>
  12. #include <time.h>
  13. #include <unistd.h>
  14. #if 1
  15. #include "warm.h"
  16. #else
  17. #define warm_init(...) 0
  18. #define warm_finish(...)
  19. #define warm_cache_op_range(...)
  20. #define warm_change_cb_range(...)
  21. #endif
  22. typedef unsigned long long u64;
  23. static u64 start_time, end_time;
  24. static unsigned char buff[8 * 1024 * 1024] __attribute__((aligned(32)));
  25. static unsigned char *buff_mid = &buff[8 * 1024 * 1024 / 2];
  26. static u64 xtime(void)
  27. {
  28. struct timeval tv;
  29. gettimeofday(&tv, NULL);
  30. return (u64)tv.tv_sec * 1000000 + tv.tv_usec;
  31. }
  32. static void test_start(void)
  33. {
  34. start_time = xtime();
  35. }
  36. static void test_end(void)
  37. {
  38. end_time = xtime();
  39. }
  40. static void show_result(const char *name, int bytes)
  41. {
  42. double secs = (end_time - start_time) / 1000000.0;
  43. printf("%-16s: %4.1fs, %5.1f MB/s\n", name, secs, bytes / secs / 1048576);
  44. }
  45. static void do_memset(void)
  46. {
  47. memset(buff, 0, sizeof(buff));
  48. }
  49. static void byte_fill(void)
  50. {
  51. char *p = (void *)buff;
  52. int i;
  53. for (i = sizeof(buff); i > 0; i--)
  54. *p++ = 0;
  55. }
  56. static void word_fill(void)
  57. {
  58. long *p = (void *)buff;
  59. int i;
  60. for (i = sizeof(buff) / sizeof(*p); i > 0; i--)
  61. *p++ = 0;
  62. }
  63. static void do_memcpy(void)
  64. {
  65. memcpy(buff, buff_mid, sizeof(buff) / 2);
  66. }
  67. static void byte_cpy(void)
  68. {
  69. char *d = (void *)buff;
  70. char *s = (void *)buff_mid;
  71. int i;
  72. for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
  73. *d++ = *s++;
  74. }
  75. static void word_cpy(void)
  76. {
  77. long *d = (void *)buff;
  78. long *s = (void *)buff_mid;
  79. int i;
  80. for (i = sizeof(buff) / sizeof(*d) / 2; i > 0; i--)
  81. *d++ = *s++;
  82. }
  83. static void word_inc(void)
  84. {
  85. long *p = (void *)buff;
  86. int i;
  87. for (i = sizeof(buff) / sizeof(*p); i > 0; i--) {
  88. (*p)++;
  89. p++;
  90. }
  91. }
  92. #define ONE_TEST(count, func) \
  93. test_start(); \
  94. for (i = count; i > 0; i--) \
  95. func(); \
  96. test_end()
  97. static void tests(void)
  98. {
  99. int i;
  100. ONE_TEST(64, do_memset);
  101. show_result("memset", sizeof(buff) * 64);
  102. ONE_TEST(64, byte_fill);
  103. show_result("byte fill", sizeof(buff) * 64);
  104. ONE_TEST(64, word_fill);
  105. show_result("word fill", sizeof(buff) * 64);
  106. ONE_TEST(128, do_memcpy);
  107. show_result("memcpy", sizeof(buff) * 128 / 2);
  108. ONE_TEST(128, byte_cpy);
  109. show_result("byte copy", sizeof(buff) * 128 / 2);
  110. ONE_TEST(128, word_cpy);
  111. show_result("word copy", sizeof(buff) * 128 / 2);
  112. ONE_TEST(64, word_inc);
  113. show_result("word inc", sizeof(buff) * 64);
  114. usleep(200000);
  115. }
  116. #if 1
  117. #include <sys/types.h>
  118. #include <sys/stat.h>
  119. #include <fcntl.h>
  120. #include <sys/mman.h>
  121. void coherency_test(void)
  122. {
  123. volatile unsigned char *buff_mapped;
  124. volatile unsigned char *buff_vol;
  125. unsigned long buff_phys, mapped_phys, align;
  126. unsigned char buff_mapped_vals[6];
  127. unsigned char buff_vals[5];
  128. int random_offs;
  129. int memdev;
  130. srand(time(NULL));
  131. buff_phys = warm_virt2phys(buff_mid);
  132. align = buff_phys & 0xfff;
  133. memdev = open("/dev/mem", O_RDONLY | O_SYNC);
  134. if (memdev < 0) {
  135. perror("open /dev/mem");
  136. return;
  137. }
  138. /* the mapping is valid for 1 page only.
  139. * Also it doesn't work for GP2X F100 (2.4 kernels?),
  140. * only upper mem maps correctly there. */
  141. buff_mapped = mmap(NULL, 0x1000, PROT_READ,
  142. MAP_SHARED, memdev, buff_phys & ~0xfff);
  143. if (buff_mapped == MAP_FAILED) {
  144. perror("mmap buff");
  145. return;
  146. }
  147. buff_mapped += align;
  148. buff_mapped_vals[5] = buff_mapped[0]; /* touch */
  149. mapped_phys = warm_virt2phys((void *)buff_mapped);
  150. if (buff_phys != mapped_phys)
  151. printf("warning: mmap requested %08lx, got %08lx\n", buff_phys, mapped_phys);
  152. random_offs = rand() % (0x1000 - align);
  153. buff_vol = (volatile void *)buff_mid;
  154. buff_vals[0] = buff_vol[random_offs]; buff_mapped_vals[0] = buff_mapped[random_offs];
  155. /* incremented: */
  156. buff_vol[random_offs]++;
  157. buff_vals[1] = buff_vol[random_offs]; buff_mapped_vals[1] = buff_mapped[random_offs];
  158. /* cleaned: */
  159. warm_cache_op_range(WOP_D_CLEAN, (char *)buff_vol + random_offs, 32);
  160. buff_vals[2] = buff_vol[random_offs]; buff_mapped_vals[2] = buff_mapped[random_offs];
  161. /* incremented: */
  162. buff_vol[random_offs]++;
  163. buff_vals[3] = buff_vol[random_offs]; buff_mapped_vals[3] = buff_mapped[random_offs];
  164. /* invalidated: */
  165. warm_cache_op_range(WOP_D_INVALIDATE, (char *)buff_vol + random_offs, 32);
  166. buff_vals[4] = buff_vol[random_offs]; buff_mapped_vals[4] = buff_mapped[random_offs];
  167. printf("buff is @ %p -> %lx, mapped %p, random offset %x\n", buff_vol, buff_phys,
  168. buff_mapped, random_offs);
  169. printf("val: %02x, mmaped: %02x\n", buff_vals[0], buff_mapped_vals[0]);
  170. printf("incremented:\n");
  171. printf("val: %02x, mmaped: %02x\n", buff_vals[1], buff_mapped_vals[1]);
  172. printf("cleaned:\n");
  173. printf("val: %02x, mmaped: %02x\n", buff_vals[2], buff_mapped_vals[2]);
  174. printf("incremented:\n");
  175. printf("val: %02x, mmaped: %02x\n", buff_vals[3], buff_mapped_vals[3]);
  176. printf("invalidated:\n");
  177. printf("val: %02x, mmaped: %02x\n", buff_vals[4], buff_mapped_vals[4]);
  178. }
  179. #else
  180. #define coherency_test()
  181. #endif
  182. int main()
  183. {
  184. int ret;
  185. ret = warm_init();
  186. if (ret != 0)
  187. {
  188. printf("init failed.\n");
  189. return 1;
  190. }
  191. printf("buff: %p - %p\n", buff, buff + sizeof(buff) - 1);
  192. printf("-- default --\n");
  193. tests();
  194. printf("-- ncnb --\n");
  195. warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 0, buff, sizeof(buff));
  196. tests();
  197. printf("-- nc b --\n");
  198. warm_change_cb_range(WCB_B_BIT, 1, buff, sizeof(buff));
  199. tests();
  200. printf("-- cnb --\n");
  201. warm_change_cb_range(WCB_C_BIT, 1, buff, sizeof(buff));
  202. warm_change_cb_range(WCB_B_BIT, 0, buff, sizeof(buff));
  203. tests();
  204. warm_change_cb_range(WCB_C_BIT|WCB_B_BIT, 1, buff, sizeof(buff));
  205. coherency_test();
  206. warm_finish();
  207. return 0;
  208. }