/libion_ti/ion_test.c

https://gitlab.com/SOKP/device_samsung_omap4-common · C · 319 lines · 285 code · 28 blank · 6 comment · 39 complexity · 4f87aa8e9391431b1852aa4c8f81540c MD5 · raw file

  1. #include <errno.h>
  2. #include <fcntl.h>
  3. #include <getopt.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <sys/mman.h>
  8. #include <sys/ioctl.h>
  9. #include <sys/socket.h>
  10. #include <sys/stat.h>
  11. #include <sys/types.h>
  12. #include <unistd.h>
  13. #include "ion.h"
  14. size_t len = 1024*1024, align = 0;
  15. int prot = PROT_READ | PROT_WRITE;
  16. int map_flags = MAP_SHARED;
  17. int alloc_flags = 0;
  18. int test = -1;
  19. size_t width = 1024*1024, height = 1024*1024;
  20. int fmt = TILER_PIXEL_FMT_32BIT;
  21. int tiler_test = 0;
  22. size_t stride;
  23. int _ion_alloc_test(int *fd, struct ion_handle **handle)
  24. {
  25. int ret;
  26. *fd = ion_open();
  27. if (*fd < 0)
  28. return *fd;
  29. if (tiler_test)
  30. ret = ion_alloc_tiler(*fd, width, height, fmt, alloc_flags,
  31. handle, &stride);
  32. else
  33. ret = ion_alloc(*fd, len, align, alloc_flags, handle);
  34. if (ret)
  35. printf("%s failed: %s\n", __func__, strerror(ret));
  36. return ret;
  37. }
  38. void ion_alloc_test()
  39. {
  40. int fd, ret;
  41. struct ion_handle *handle;
  42. if(_ion_alloc_test(&fd, &handle))
  43. return;
  44. ret = ion_free(fd, handle);
  45. if (ret) {
  46. printf("%s failed: %s %p\n", __func__, strerror(ret), handle);
  47. return;
  48. }
  49. ion_close(fd);
  50. printf("ion alloc test: passed\n");
  51. }
  52. void _ion_tiler_map_test(unsigned char *ptr)
  53. {
  54. size_t row, col;
  55. for (row = 0; row < height; row++)
  56. for (col = 0; col < width; col++) {
  57. int i = (row * stride) + col;
  58. ptr[i] = (unsigned char)i;
  59. }
  60. for (row = 0; row < height; row++)
  61. for (col = 0; col < width; col++) {
  62. int i = (row * stride) + col;
  63. if (ptr[i] != (unsigned char)i)
  64. printf("%s failed wrote %d read %d from mapped "
  65. "memory\n", __func__, i, ptr[i]);
  66. }
  67. }
  68. void ion_map_test()
  69. {
  70. int fd, map_fd, ret;
  71. size_t i;
  72. struct ion_handle *handle;
  73. unsigned char *ptr;
  74. if(_ion_alloc_test(&fd, &handle))
  75. return;
  76. if (tiler_test)
  77. len = height * stride;
  78. ret = ion_map(fd, handle, len, prot, map_flags, 0, &ptr, &map_fd);
  79. if (ret)
  80. return;
  81. if (tiler_test)
  82. _ion_tiler_map_test(ptr);
  83. else {
  84. for (i = 0; i < len; i++) {
  85. ptr[i] = (unsigned char)i;
  86. }
  87. for (i = 0; i < len; i++)
  88. if (ptr[i] != (unsigned char)i)
  89. printf("%s failed wrote %d read %d from mapped "
  90. "memory\n", __func__, i, ptr[i]);
  91. }
  92. /* clean up properly */
  93. ret = ion_free(fd, handle);
  94. ion_close(fd);
  95. munmap(ptr, len);
  96. close(map_fd);
  97. _ion_alloc_test(&fd, &handle);
  98. close(fd);
  99. #if 0
  100. munmap(ptr, len);
  101. close(map_fd);
  102. ion_close(fd);
  103. _ion_alloc_test(len, align, flags, &fd, &handle);
  104. close(map_fd);
  105. ret = ion_map(fd, handle, len, prot, flags, 0, &ptr, &map_fd);
  106. /* don't clean up */
  107. #endif
  108. }
  109. void ion_share_test()
  110. {
  111. struct ion_handle *handle;
  112. int sd[2];
  113. int num_fd = 1;
  114. struct iovec count_vec = {
  115. .iov_base = &num_fd,
  116. .iov_len = sizeof num_fd,
  117. };
  118. char buf[CMSG_SPACE(sizeof(int))];
  119. socketpair(AF_UNIX, SOCK_STREAM, 0, sd);
  120. if (fork()) {
  121. struct msghdr msg = {
  122. .msg_control = buf,
  123. .msg_controllen = sizeof buf,
  124. .msg_iov = &count_vec,
  125. .msg_iovlen = 1,
  126. };
  127. struct cmsghdr *cmsg;
  128. int fd, share_fd, ret;
  129. char *ptr;
  130. /* parent */
  131. if(_ion_alloc_test(&fd, &handle))
  132. return;
  133. ret = ion_share(fd, handle, &share_fd);
  134. if (ret)
  135. printf("share failed %s\n", strerror(errno));
  136. ptr = mmap(NULL, len, prot, map_flags, share_fd, 0);
  137. if (ptr == MAP_FAILED) {
  138. return;
  139. }
  140. strcpy(ptr, "master");
  141. cmsg = CMSG_FIRSTHDR(&msg);
  142. cmsg->cmsg_level = SOL_SOCKET;
  143. cmsg->cmsg_type = SCM_RIGHTS;
  144. cmsg->cmsg_len = CMSG_LEN(sizeof(int));
  145. *(int *)CMSG_DATA(cmsg) = share_fd;
  146. /* send the fd */
  147. printf("master? [%10s] should be [master]\n", ptr);
  148. printf("master sending msg 1\n");
  149. sendmsg(sd[0], &msg, 0);
  150. if (recvmsg(sd[0], &msg, 0) < 0)
  151. perror("master recv msg 2");
  152. printf("master? [%10s] should be [child]\n", ptr);
  153. /* send ping */
  154. sendmsg(sd[0], &msg, 0);
  155. printf("master->master? [%10s]\n", ptr);
  156. if (recvmsg(sd[0], &msg, 0) < 0)
  157. perror("master recv 1");
  158. } else {
  159. struct msghdr msg;
  160. struct cmsghdr *cmsg;
  161. char* ptr;
  162. int fd, recv_fd;
  163. char* child_buf[100];
  164. /* child */
  165. struct iovec count_vec = {
  166. .iov_base = child_buf,
  167. .iov_len = sizeof child_buf,
  168. };
  169. struct msghdr child_msg = {
  170. .msg_control = buf,
  171. .msg_controllen = sizeof buf,
  172. .msg_iov = &count_vec,
  173. .msg_iovlen = 1,
  174. };
  175. if (recvmsg(sd[1], &child_msg, 0) < 0)
  176. perror("child recv msg 1");
  177. cmsg = CMSG_FIRSTHDR(&child_msg);
  178. if (cmsg == NULL) {
  179. printf("no cmsg rcvd in child");
  180. return;
  181. }
  182. recv_fd = *(int*)CMSG_DATA(cmsg);
  183. if (recv_fd < 0) {
  184. printf("could not get recv_fd from socket");
  185. return;
  186. }
  187. printf("child %d\n", recv_fd);
  188. fd = ion_open();
  189. ptr = mmap(NULL, len, prot, map_flags, recv_fd, 0);
  190. if (ptr == MAP_FAILED) {
  191. return;
  192. }
  193. printf("child? [%10s] should be [master]\n", ptr);
  194. strcpy(ptr, "child");
  195. printf("child sending msg 2\n");
  196. sendmsg(sd[1], &child_msg, 0);
  197. }
  198. }
  199. int main(int argc, char* argv[]) {
  200. int c;
  201. enum tests {
  202. ALLOC_TEST = 0, MAP_TEST, SHARE_TEST,
  203. };
  204. while (1) {
  205. static struct option opts[] = {
  206. {"alloc", no_argument, 0, 'a'},
  207. {"alloc_flags", required_argument, 0, 'f'},
  208. {"map", no_argument, 0, 'm'},
  209. {"share", no_argument, 0, 's'},
  210. {"len", required_argument, 0, 'l'},
  211. {"align", required_argument, 0, 'g'},
  212. {"map_flags", required_argument, 0, 'z'},
  213. {"prot", required_argument, 0, 'p'},
  214. {"alloc_tiler", no_argument, 0, 't'},
  215. {"width", required_argument, 0, 'w'},
  216. {"height", required_argument, 0, 'h'},
  217. {"fmt", required_argument, 0, 'r'},
  218. };
  219. int i = 0;
  220. c = getopt_long(argc, argv, "af:h:l:mr:stw:", opts, &i);
  221. if (c == -1)
  222. break;
  223. switch (c) {
  224. case 'l':
  225. len = atol(optarg);
  226. break;
  227. case 'g':
  228. align = atol(optarg);
  229. break;
  230. case 'z':
  231. map_flags = 0;
  232. map_flags |= strstr(optarg, "PROT_EXEC") ?
  233. PROT_EXEC : 0;
  234. map_flags |= strstr(optarg, "PROT_READ") ?
  235. PROT_READ: 0;
  236. map_flags |= strstr(optarg, "PROT_WRITE") ?
  237. PROT_WRITE: 0;
  238. map_flags |= strstr(optarg, "PROT_NONE") ?
  239. PROT_NONE: 0;
  240. break;
  241. case 'p':
  242. prot = 0;
  243. prot |= strstr(optarg, "MAP_PRIVATE") ?
  244. MAP_PRIVATE : 0;
  245. prot |= strstr(optarg, "MAP_SHARED") ?
  246. MAP_PRIVATE : 0;
  247. break;
  248. case 'f':
  249. alloc_flags = atol(optarg);
  250. break;
  251. case 'a':
  252. test = ALLOC_TEST;
  253. break;
  254. case 'm':
  255. test = MAP_TEST;
  256. break;
  257. case 'r':
  258. fmt = atol(optarg);
  259. break;
  260. case 's':
  261. test = SHARE_TEST;
  262. break;
  263. case 'w':
  264. width = atol(optarg);
  265. break;
  266. case 'h':
  267. height = atol(optarg);
  268. break;
  269. case 't':
  270. tiler_test = 1;
  271. break;
  272. }
  273. }
  274. printf("test %d, len %u, width %u, height %u fmt %u align %u, "
  275. "map_flags %d, prot %d, alloc_flags %d\n", test, len, width,
  276. height, fmt, align, map_flags, prot, alloc_flags);
  277. switch (test) {
  278. case ALLOC_TEST:
  279. ion_alloc_test();
  280. break;
  281. case MAP_TEST:
  282. ion_map_test();
  283. break;
  284. case SHARE_TEST:
  285. ion_share_test();
  286. break;
  287. default:
  288. printf("must specify a test (alloc, map, share)\n");
  289. }
  290. return 0;
  291. }