/alps/pcitool

To get this branch, use:
bzr branch http://darksoft.org/webbzr/alps/pcitool

« back to all changes in this revision

Viewing changes to patches/pcitool-r221-kmem_writes.diff

  • Committer: Suren A. Chilingaryan
  • Date: 2018-07-06 10:01:12 UTC
  • Revision ID: csa@suren.me-20180706100112-w0xk2n8lwbxwpuqn
Added patch to r221 enabling kmem writes (for future reference)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
56
+    err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_TODEVICE, block);
 
57
+    if (err) {
 
58
+       pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
 
59
+       Error("The synchronization of kernel buffer has failed\n");
 
60
+       return 0;
 
61
+    }
 
62
+
 
63
     pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
 
64
 
 
65
     return 0;
 
66
 }
 
67
+
 
68
+
 
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) {
 
70
+    int err;
 
71
+    void *data;
 
72
+    void *buf;
 
73
+    char *src_value;
 
74
+    int res = 0, i;
 
75
+    size_t n, size;
 
76
+    pcilib_kmem_handle_t *kbuf;
 
77
+
 
78
+    if (block == (size_t)-1) block = 0;
 
79
+
 
80
+    kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
 
81
+    if (!kbuf) {
 
82
+       Error("The specified kernel buffer is not allocated\n");
 
83
+       return 0;
 
84
+    }
 
85
+
 
86
+    err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
 
87
+    if (err) {
 
88
+       pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
 
89
+       Error("The synchronization of kernel buffer has failed\n");
 
90
+       return 0;
 
91
+    }
 
92
+
 
93
+    data = pcilib_kmem_get_block_ua(handle, kbuf, block);
 
94
+    if (data) {
 
95
+       size = pcilib_kmem_get_block_size(handle, kbuf, block);
 
96
+       if ((max_size)&&(size > max_size)) size = max_size;
 
97
+       
 
98
+       err = posix_memalign( (void**)&buf, 256, size);
 
99
+       if ((err)||(!buf)) Error("Allocation of %i bytes of memory have failed", size);
 
100
+
 
101
+       n = size / access;
 
102
+
 
103
+        for (i = 0; i < n; i++) {
 
104
+           src_value = max_size?src[i]:src[0];
 
105
+           
 
106
+           switch (access) {
 
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);
 
112
+           }
 
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);
 
114
+       }
 
115
+       if (endianess) pcilib_swap(buf, buf, abs(access), n);
 
116
+
 
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);
 
120
+    } else {
 
121
+       pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
 
122
+       Error("The specified block is not existing\n");
 
123
+       return 0;
 
124
+    }
 
125
+
 
126
+    pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
 
127
+
 
128
+    return 0;
 
129
+}
 
130
+
 
131
 
 
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 @@
 
134
 
 
135
     return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
 
136
+}
 
137
+
 
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) {
 
139
+    int err;
 
140
+    pcilib_dma_engine_t dmaid;
 
141
+    pcilib_dma_engine_status_t status;
 
142
+    pcilib_dma_buffer_status_t *buffer;
 
143
+
 
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");
 
146
+
 
147
+    err = pcilib_start_dma(handle, dmaid, 0);
 
148
+    if (err) Error("Error starting the specified DMA engine");
 
149
+    
 
150
+    err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
 
151
+    if (err) Error("Failed to obtain status of the specified DMA engine");
 
152
+    
 
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");
 
155
+
 
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");
 
158
+
 
159
+    if (block == (size_t)-1) {
 
160
+       // get current 
 
161
+    }
 
162
+
 
163
+    if (size) {
 
164
+        if (size > buffer[block].size)
 
165
+           size = buffer[block].size;
 
166
+    } 
 
167
+/*
 
168
+    // We don't care if extra space will be overwritten    
 
169
+    else {
 
170
+       size = buffer[block].size;
 
171
+    }
 
172
+*/
 
173
+
 
174
+    free(buffer);
 
175
+
 
176
+    pcilib_stop_dma(handle, dmaid, 0);
 
177
+
 
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);
 
179
 }
 
180
 
 
181
@@ -2513,4 +2635,20 @@
 
182
                dma_channel = optarg;
 
183
            break;
 
184
+           case OPT_WRITE_DMA_BUFFER:
 
185
+               if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
 
186
+               
 
187
+               mode = MODE_WRITE_DMA_BUFFER;
 
188
+
 
189
+               num_offset = strchr(optarg, ':');
 
190
+
 
191
+               if (num_offset) {
 
192
+                   if (sscanf(num_offset + 1, "%zu", &block) != 1)
 
193
+                       Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
 
194
+
 
195
+                   *(char*)num_offset = 0;
 
196
+               } else block = (size_t)-1;
 
197
+               
 
198
+               dma_channel = optarg;
 
199
+           break;
 
200
            case OPT_START_DMA:
 
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;
 
205
+
 
206
+               num_offset = strchr(optarg, ':');
 
207
+
 
208
+               if (num_offset) {
 
209
+                   if (sscanf(num_offset + 1, "%zu", &block) != 1)
 
210
+                       Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
 
211
+
 
212
+                   *(char*)num_offset = 0;
 
213
+               }
 
214
+               
 
215
+               use = optarg;
 
216
+               useid = ParseUse(use);
 
217
+           break;
 
218
+           case OPT_WRITE_KMEM:
 
219
+               if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
 
220
+               mode = MODE_WRITE_KMEM;
 
221
 
 
222
                num_offset = strchr(optarg, ':');
 
223
@@ -2842,4 +2996,6 @@
 
224
 
 
225
     switch (mode) {
 
226
+     case MODE_WRITE_DMA_BUFFER:
 
227
+     case MODE_WRITE_KMEM:
 
228
      case MODE_WRITE:
 
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);
 
233
+        
 
234
+        if (mode != MODE_WRITE) break;
 
235
      case MODE_READ:
 
236
         if (!addr) {
 
237
@@ -2872,8 +3030,15 @@
 
238
        }
 
239
      break;
 
240
+     default:
 
241
+        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
 
242
+    }
 
243
+
 
244
+
 
245
+    switch (mode) {
 
246
      case MODE_START_DMA:
 
247
      case MODE_STOP_DMA:
 
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 @@
 
254
      break;
 
255
      default:
 
256
-        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
 
257
+        ;
 
258
     }
 
259
 
 
260
@@ -3057,4 +3222,7 @@
 
261
         ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
 
262
      break;
 
263
+     case MODE_WRITE_DMA_BUFFER:
 
264
+        WriteBuffer(handle, fpga_device, model_info, dma, dma_direction, block, size_set?size:0, access, endianess, data);
 
265
+     break;
 
266
      case MODE_START_DMA:
 
267
         StartStopDMA(handle, model_info, dma, dma_direction, 1);
 
268
@@ -3082,4 +3250,7 @@
 
269
         ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
 
270
      break;
 
271
+     case MODE_WRITE_KMEM:
 
272
+        WriteKMEM(handle, fpga_device, useid, block, size_set?size:0, access, endianess, data);
 
273
+     break;
 
274
      case MODE_ALLOC_KMEM:
 
275
         AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);