pcitool-r221-kmem_writes.diff 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. Index: pcitool-kmemwrite/cli.c
  2. ===================================================================
  3. --- pcitool-kmemwrite/cli.c (revision pcitool-kmemwrite,197)
  4. +++ pcitool-kmemwrite/cli.c (revision pcitool-kmemwrite,222)
  5. @@ -78,4 +78,5 @@
  6. MODE_LIST_DMA_BUFFERS,
  7. MODE_READ_DMA_BUFFER,
  8. + MODE_WRITE_DMA_BUFFER,
  9. MODE_ENABLE_IRQ,
  10. MODE_DISABLE_IRQ,
  11. @@ -85,4 +86,5 @@
  12. MODE_LIST_KMEM,
  13. MODE_READ_KMEM,
  14. + MODE_WRITE_KMEM,
  15. MODE_FREE_KMEM
  16. } MODE;
  17. @@ -145,4 +147,5 @@
  18. OPT_LIST_DMA_BUFFERS,
  19. OPT_READ_DMA_BUFFER,
  20. + OPT_WRITE_DMA_BUFFER,
  21. OPT_START_DMA,
  22. OPT_STOP_DMA,
  23. @@ -156,4 +159,5 @@
  24. OPT_FREE_KMEM,
  25. OPT_READ_KMEM,
  26. + OPT_WRITE_KMEM,
  27. OPT_BLOCK_SIZE,
  28. OPT_ALIGNMENT,
  29. @@ -197,4 +201,5 @@
  30. {"list-dma-buffers", required_argument, 0, OPT_LIST_DMA_BUFFERS },
  31. {"read-dma-buffer", required_argument, 0, OPT_READ_DMA_BUFFER },
  32. + {"write-dma-buffer", required_argument, 0, OPT_WRITE_DMA_BUFFER },
  33. {"enable-irq", optional_argument, 0, OPT_ENABLE_IRQ },
  34. {"disable-irq", optional_argument, 0, OPT_DISABLE_IRQ },
  35. @@ -203,4 +208,5 @@
  36. {"list-kernel-memory", optional_argument, 0, OPT_LIST_KMEM },
  37. {"read-kernel-memory", required_argument, 0, OPT_READ_KMEM },
  38. + {"write-kernel-memory", required_argument, 0, OPT_WRITE_KMEM },
  39. {"alloc-kernel-memory", required_argument, 0, OPT_ALLOC_KMEM },
  40. {"free-kernel-memory", required_argument, 0, OPT_FREE_KMEM },
  41. @@ -261,4 +267,5 @@
  42. " --list-dma-buffers <dma> - List buffers for specified DMA engine\n"
  43. " --read-dma-buffer <dma:buf> - Read the specified buffer\n"
  44. +" --write-dma-buffer <dma:buf>- Write the specified buffer\n"
  45. "\n"
  46. " Kernel Modes:\n"
  47. @@ -266,4 +273,5 @@
  48. " --read-kernel-memory <blk> - Read the specified block of the kernel memory\n"
  49. " block is specified as: use:block_number\n"
  50. +" --write-kernel-memory <blk> - Write the specified block of the kernel memory\n"
  51. " --alloc-kernel-memory <use> - Allocate kernel buffers (DANGEROUS)\n"
  52. " --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n"
  53. @@ -2061,8 +2069,79 @@
  54. }
  55. + err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_TODEVICE, block);
  56. + if (err) {
  57. + pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
  58. + Error("The synchronization of kernel buffer has failed\n");
  59. + return 0;
  60. + }
  61. +
  62. pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
  63. return 0;
  64. }
  65. +
  66. +
  67. +int WriteKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size_t block, size_t max_size, access_t access, int endianess, char **src) {
  68. + int err;
  69. + void *data;
  70. + void *buf;
  71. + char *src_value;
  72. + int res = 0, i;
  73. + size_t n, size;
  74. + pcilib_kmem_handle_t *kbuf;
  75. +
  76. + if (block == (size_t)-1) block = 0;
  77. +
  78. + kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
  79. + if (!kbuf) {
  80. + Error("The specified kernel buffer is not allocated\n");
  81. + return 0;
  82. + }
  83. +
  84. + err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
  85. + if (err) {
  86. + pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
  87. + Error("The synchronization of kernel buffer has failed\n");
  88. + return 0;
  89. + }
  90. +
  91. + data = pcilib_kmem_get_block_ua(handle, kbuf, block);
  92. + if (data) {
  93. + size = pcilib_kmem_get_block_size(handle, kbuf, block);
  94. + if ((max_size)&&(size > max_size)) size = max_size;
  95. +
  96. + err = posix_memalign( (void**)&buf, 256, size);
  97. + if ((err)||(!buf)) Error("Allocation of %i bytes of memory have failed", size);
  98. +
  99. + n = size / access;
  100. +
  101. + for (i = 0; i < n; i++) {
  102. + src_value = max_size?src[i]:src[0];
  103. +
  104. + switch (access) {
  105. + case 1: res = sscanf(src_value, "%hhx", ((uint8_t*)buf)+i); break;
  106. + case 2: res = sscanf(src_value, "%hx", ((uint16_t*)buf)+i); break;
  107. + case 4: res = sscanf(src_value, "%x", ((uint32_t*)buf)+i); break;
  108. + case 8: res = sscanf(src_value, "%lx", ((uint64_t*)buf)+i); break;
  109. + default: Error("Unexpected data size (%lu)", access);
  110. + }
  111. + if ((res != 1)||(!isxnumber(src_value))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, src_value);
  112. + }
  113. + if (endianess) pcilib_swap(buf, buf, abs(access), n);
  114. +
  115. + printf("%x %x %i %i\n", *((uint32_t*)buf), *((uint32_t*)data), n * access, access);
  116. + memcpy(data, buf, n * access);
  117. + printf("%x %x %i %i\n", *((uint32_t*)buf), *((uint32_t*)data), n * access, access);
  118. + } else {
  119. + pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
  120. + Error("The specified block is not existing\n");
  121. + return 0;
  122. + }
  123. +
  124. + pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
  125. +
  126. + return 0;
  127. +}
  128. +
  129. int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) {
  130. @@ -2301,4 +2380,47 @@
  131. return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
  132. +}
  133. +
  134. +int WriteBuffer(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, size_t block, size_t size, access_t access, int endianess, char **src) {
  135. + int err;
  136. + pcilib_dma_engine_t dmaid;
  137. + pcilib_dma_engine_status_t status;
  138. + pcilib_dma_buffer_status_t *buffer;
  139. +
  140. + dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
  141. + if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
  142. +
  143. + err = pcilib_start_dma(handle, dmaid, 0);
  144. + if (err) Error("Error starting the specified DMA engine");
  145. +
  146. + err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
  147. + if (err) Error("Failed to obtain status of the specified DMA engine");
  148. +
  149. + buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
  150. + if (!buffer) Error("Failed to allocate memory for status buffer");
  151. +
  152. + err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
  153. + if (err) Error("Failed to obtain extended status of the specified DMA engine");
  154. +
  155. + if (block == (size_t)-1) {
  156. + // get current
  157. + }
  158. +
  159. + if (size) {
  160. + if (size > buffer[block].size)
  161. + size = buffer[block].size;
  162. + }
  163. +/*
  164. + // We don't care if extra space will be overwritten
  165. + else {
  166. + size = buffer[block].size;
  167. + }
  168. +*/
  169. +
  170. + free(buffer);
  171. +
  172. + pcilib_stop_dma(handle, dmaid, 0);
  173. +
  174. + return WriteKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, access, endianess, src);
  175. }
  176. @@ -2513,4 +2635,20 @@
  177. dma_channel = optarg;
  178. break;
  179. + case OPT_WRITE_DMA_BUFFER:
  180. + if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
  181. +
  182. + mode = MODE_WRITE_DMA_BUFFER;
  183. +
  184. + num_offset = strchr(optarg, ':');
  185. +
  186. + if (num_offset) {
  187. + if (sscanf(num_offset + 1, "%zu", &block) != 1)
  188. + Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
  189. +
  190. + *(char*)num_offset = 0;
  191. + } else block = (size_t)-1;
  192. +
  193. + dma_channel = optarg;
  194. + break;
  195. case OPT_START_DMA:
  196. if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
  197. @@ -2609,4 +2747,20 @@
  198. if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
  199. mode = MODE_READ_KMEM;
  200. +
  201. + num_offset = strchr(optarg, ':');
  202. +
  203. + if (num_offset) {
  204. + if (sscanf(num_offset + 1, "%zu", &block) != 1)
  205. + Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
  206. +
  207. + *(char*)num_offset = 0;
  208. + }
  209. +
  210. + use = optarg;
  211. + useid = ParseUse(use);
  212. + break;
  213. + case OPT_WRITE_KMEM:
  214. + if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
  215. + mode = MODE_WRITE_KMEM;
  216. num_offset = strchr(optarg, ':');
  217. @@ -2842,4 +2996,6 @@
  218. switch (mode) {
  219. + case MODE_WRITE_DMA_BUFFER:
  220. + case MODE_WRITE_KMEM:
  221. case MODE_WRITE:
  222. if (((argc - optind) == 1)&&(*argv[optind] == '*')) {
  223. @@ -2864,4 +3020,6 @@
  224. } else if ((argc - optind) == size) data = argv + optind;
  225. else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size);
  226. +
  227. + if (mode != MODE_WRITE) break;
  228. case MODE_READ:
  229. if (!addr) {
  230. @@ -2872,8 +3030,15 @@
  231. }
  232. break;
  233. + default:
  234. + if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
  235. + }
  236. +
  237. +
  238. + switch (mode) {
  239. case MODE_START_DMA:
  240. case MODE_STOP_DMA:
  241. case MODE_LIST_DMA_BUFFERS:
  242. case MODE_READ_DMA_BUFFER:
  243. + case MODE_WRITE_DMA_BUFFER:
  244. if ((dma_channel)&&(*dma_channel)) {
  245. itmp = strlen(dma_channel) - 1;
  246. @@ -2900,5 +3065,5 @@
  247. break;
  248. default:
  249. - if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
  250. + ;
  251. }
  252. @@ -3057,4 +3222,7 @@
  253. ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
  254. break;
  255. + case MODE_WRITE_DMA_BUFFER:
  256. + WriteBuffer(handle, fpga_device, model_info, dma, dma_direction, block, size_set?size:0, access, endianess, data);
  257. + break;
  258. case MODE_START_DMA:
  259. StartStopDMA(handle, model_info, dma, dma_direction, 1);
  260. @@ -3082,4 +3250,7 @@
  261. ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
  262. break;
  263. + case MODE_WRITE_KMEM:
  264. + WriteKMEM(handle, fpga_device, useid, block, size_set?size:0, access, endianess, data);
  265. + break;
  266. case MODE_ALLOC_KMEM:
  267. AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);