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)
8
+ MODE_WRITE_DMA_BUFFER,
20
+ OPT_WRITE_DMA_BUFFER,
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 },
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 },
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"
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 @@
56
+ err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_TODEVICE, block);
58
+ pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
59
+ Error("The synchronization of kernel buffer has failed\n");
63
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
69
+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) {
76
+ pcilib_kmem_handle_t *kbuf;
78
+ if (block == (size_t)-1) block = 0;
80
+ kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
82
+ Error("The specified kernel buffer is not allocated\n");
86
+ err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
88
+ pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
89
+ Error("The synchronization of kernel buffer has failed\n");
93
+ data = pcilib_kmem_get_block_ua(handle, kbuf, block);
95
+ size = pcilib_kmem_get_block_size(handle, kbuf, block);
96
+ if ((max_size)&&(size > max_size)) size = max_size;
98
+ err = posix_memalign( (void**)&buf, 256, size);
99
+ if ((err)||(!buf)) Error("Allocation of %i bytes of memory have failed", size);
103
+ for (i = 0; i < n; i++) {
104
+ src_value = max_size?src[i]:src[0];
107
+ case 1: res = sscanf(src_value, "%hhx", ((uint8_t*)buf)+i); break;
108
+ case 2: res = sscanf(src_value, "%hx", ((uint16_t*)buf)+i); break;
109
+ case 4: res = sscanf(src_value, "%x", ((uint32_t*)buf)+i); break;
110
+ case 8: res = sscanf(src_value, "%lx", ((uint64_t*)buf)+i); break;
111
+ default: Error("Unexpected data size (%lu)", access);
113
+ if ((res != 1)||(!isxnumber(src_value))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, src_value);
115
+ if (endianess) pcilib_swap(buf, buf, abs(access), n);
117
+ printf("%x %x %i %i\n", *((uint32_t*)buf), *((uint32_t*)data), n * access, access);
118
+ memcpy(data, buf, n * access);
119
+ printf("%x %x %i %i\n", *((uint32_t*)buf), *((uint32_t*)data), n * access, access);
121
+ pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
122
+ Error("The specified block is not existing\n");
126
+ pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
132
int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) {
133
@@ -2301,4 +2380,47 @@
135
return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
138
+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) {
140
+ pcilib_dma_engine_t dmaid;
141
+ pcilib_dma_engine_status_t status;
142
+ pcilib_dma_buffer_status_t *buffer;
144
+ dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
145
+ if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
147
+ err = pcilib_start_dma(handle, dmaid, 0);
148
+ if (err) Error("Error starting the specified DMA engine");
150
+ err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
151
+ if (err) Error("Failed to obtain status of the specified DMA engine");
153
+ buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
154
+ if (!buffer) Error("Failed to allocate memory for status buffer");
156
+ err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
157
+ if (err) Error("Failed to obtain extended status of the specified DMA engine");
159
+ if (block == (size_t)-1) {
164
+ if (size > buffer[block].size)
165
+ size = buffer[block].size;
168
+ // We don't care if extra space will be overwritten
170
+ size = buffer[block].size;
176
+ pcilib_stop_dma(handle, dmaid, 0);
178
+ 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);
181
@@ -2513,4 +2635,20 @@
182
dma_channel = optarg;
184
+ case OPT_WRITE_DMA_BUFFER:
185
+ if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
187
+ mode = MODE_WRITE_DMA_BUFFER;
189
+ num_offset = strchr(optarg, ':');
192
+ if (sscanf(num_offset + 1, "%zu", &block) != 1)
193
+ Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
195
+ *(char*)num_offset = 0;
196
+ } else block = (size_t)-1;
198
+ dma_channel = optarg;
201
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
202
@@ -2609,4 +2747,20 @@
203
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
204
mode = MODE_READ_KMEM;
206
+ num_offset = strchr(optarg, ':');
209
+ if (sscanf(num_offset + 1, "%zu", &block) != 1)
210
+ Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
212
+ *(char*)num_offset = 0;
216
+ useid = ParseUse(use);
218
+ case OPT_WRITE_KMEM:
219
+ if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
220
+ mode = MODE_WRITE_KMEM;
222
num_offset = strchr(optarg, ':');
223
@@ -2842,4 +2996,6 @@
226
+ case MODE_WRITE_DMA_BUFFER:
227
+ case MODE_WRITE_KMEM:
229
if (((argc - optind) == 1)&&(*argv[optind] == '*')) {
230
@@ -2864,4 +3020,6 @@
231
} else if ((argc - optind) == size) data = argv + optind;
232
else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size);
234
+ if (mode != MODE_WRITE) break;
237
@@ -2872,8 +3030,15 @@
241
+ if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
248
case MODE_LIST_DMA_BUFFERS:
249
case MODE_READ_DMA_BUFFER:
250
+ case MODE_WRITE_DMA_BUFFER:
251
if ((dma_channel)&&(*dma_channel)) {
252
itmp = strlen(dma_channel) - 1;
253
@@ -2900,5 +3065,5 @@
256
- if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
260
@@ -3057,4 +3222,7 @@
261
ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
263
+ case MODE_WRITE_DMA_BUFFER:
264
+ WriteBuffer(handle, fpga_device, model_info, dma, dma_direction, block, size_set?size:0, access, endianess, data);
267
StartStopDMA(handle, model_info, dma, dma_direction, 1);
268
@@ -3082,4 +3250,7 @@
269
ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
271
+ case MODE_WRITE_KMEM:
272
+ WriteKMEM(handle, fpga_device, useid, block, size_set?size:0, access, endianess, data);
274
case MODE_ALLOC_KMEM:
275
AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);