bzr branch
http://suren.me/webbzr/alps/pcitool
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1 |
#define _POSIX_C_SOURCE 200112L
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2 |
|
3 |
#include <stdio.h> |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
4 |
#include <stdlib.h> |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
5 |
#include <string.h> |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
6 |
#include <strings.h> |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
7 |
#include <stdint.h> |
8 |
#include <stdarg.h> |
|
9 |
#include <fcntl.h> |
|
10 |
#include <unistd.h> |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
11 |
#include <sys/time.h> |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
12 |
#include <sys/ioctl.h> |
13 |
#include <sys/mman.h> |
|
14 |
#include <errno.h> |
|
15 |
#include <alloca.h> |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
16 |
#include <arpa/inet.h> |
80
by Suren A. Chilingaryan
List kernel buffers |
17 |
#include <sys/types.h> |
18 |
#include <dirent.h> |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
19 |
#include <pthread.h> |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
20 |
|
21 |
#include <getopt.h> |
|
22 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
23 |
#include "pcitool/sysinfo.h" |
24 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
25 |
//#include "pci.h"
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
26 |
#include "tools.h" |
7.1.6
by Suren A. Chilingaryan
Provide single header for library |
27 |
#include "kernel.h" |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
28 |
#include "error.h" |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
29 |
|
30 |
/* defines */
|
|
31 |
#define MAX_KBUF 14
|
|
32 |
//#define BIGBUFSIZE (512*1024*1024)
|
|
33 |
#define BIGBUFSIZE (1024*1024)
|
|
34 |
||
35 |
||
36 |
#define DEFAULT_FPGA_DEVICE "/dev/fpga0"
|
|
37 |
||
38 |
#define LINE_WIDTH 80
|
|
39 |
#define SEPARATOR_WIDTH 2
|
|
40 |
#define BLOCK_SEPARATOR_WIDTH 2
|
|
41 |
#define BLOCK_SIZE 8
|
|
42 |
#define BENCHMARK_ITERATIONS 128
|
|
43 |
||
7.1.5
by Suren A. Chilingaryan
Support for FPGA registers |
44 |
#define isnumber pcilib_isnumber
|
45 |
#define isxnumber pcilib_isxnumber
|
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
46 |
#define isnumber_n pcilib_isnumber_n
|
47 |
#define isxnumber_n pcilib_isxnumber_n
|
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
48 |
|
49 |
typedef uint8_t access_t; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
50 |
|
51 |
typedef enum { |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
52 |
GRAB_MODE_GRAB = 1, |
53 |
GRAB_MODE_TRIGGER = 2 |
|
54 |
} GRAB_MODE; |
|
55 |
||
56 |
typedef enum { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
57 |
MODE_INVALID, |
58 |
MODE_INFO, |
|
59 |
MODE_LIST, |
|
60 |
MODE_BENCHMARK, |
|
61 |
MODE_READ, |
|
62 |
MODE_READ_REGISTER, |
|
63 |
MODE_WRITE, |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
64 |
MODE_WRITE_REGISTER, |
65 |
MODE_RESET, |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
66 |
MODE_GRAB, |
67 |
MODE_START_DMA, |
|
68 |
MODE_STOP_DMA, |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
69 |
MODE_LIST_DMA, |
70 |
MODE_LIST_DMA_BUFFERS, |
|
71 |
MODE_READ_DMA_BUFFER, |
|
80
by Suren A. Chilingaryan
List kernel buffers |
72 |
MODE_WAIT_IRQ, |
73 |
MODE_LIST_KMEM, |
|
100
by root
Support exporting data from kernel buffers |
74 |
MODE_READ_KMEM, |
80
by Suren A. Chilingaryan
List kernel buffers |
75 |
MODE_FREE_KMEM
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
76 |
} MODE; |
77 |
||
78 |
typedef enum { |
|
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
79 |
ACCESS_BAR, |
80 |
ACCESS_DMA, |
|
81 |
ACCESS_FIFO
|
|
82 |
} ACCESS_MODE; |
|
83 |
||
84 |
typedef enum { |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
85 |
FLAG_MULTIPACKET = 1, |
86 |
FLAG_WAIT = 2 |
|
87 |
} FLAGS; |
|
88 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
89 |
|
90 |
typedef enum { |
|
91 |
FORMAT_RAW, |
|
92 |
FORMAT_HEADER, |
|
93 |
FORMAT_RINGFS
|
|
94 |
} FORMAT; |
|
95 |
||
96 |
typedef enum { |
|
97 |
PARTITION_UNKNOWN, |
|
98 |
PARTITION_RAW, |
|
99 |
PARTITION_EXT4
|
|
100 |
} PARTITION; |
|
101 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
102 |
typedef enum { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
103 |
OPT_DEVICE = 'd', |
104 |
OPT_MODEL = 'm', |
|
105 |
OPT_BAR = 'b', |
|
106 |
OPT_ACCESS = 'a', |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
107 |
OPT_ENDIANESS = 'e', |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
108 |
OPT_SIZE = 's', |
15
by Suren A. Chilingaryan
Infrastructure for event API |
109 |
OPT_OUTPUT = 'o', |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
110 |
OPT_TIMEOUT = 't', |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
111 |
OPT_INFO = 'i', |
100
by root
Support exporting data from kernel buffers |
112 |
OPT_LIST = 'l', |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
113 |
OPT_READ = 'r', |
114 |
OPT_WRITE = 'w', |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
115 |
OPT_GRAB = 'g', |
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
116 |
OPT_QUIETE = 'q', |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
117 |
OPT_HELP = 'h', |
15
by Suren A. Chilingaryan
Infrastructure for event API |
118 |
OPT_RESET = 128, |
101
by root
Remove short option for benchmark in cli |
119 |
OPT_BENCHMARK, |
117
by Suren A. Chilingaryan
new event architecture, first trial |
120 |
OPT_TRIGGER, |
121 |
OPT_DATA_TYPE, |
|
122 |
OPT_EVENT, |
|
123 |
OPT_TRIGGER_RATE, |
|
124 |
OPT_TRIGGER_TIME, |
|
125 |
OPT_RUN_TIME, |
|
126 |
OPT_FORMAT, |
|
127 |
OPT_BUFFER, |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
128 |
OPT_LIST_DMA, |
129 |
OPT_LIST_DMA_BUFFERS, |
|
130 |
OPT_READ_DMA_BUFFER, |
|
80
by Suren A. Chilingaryan
List kernel buffers |
131 |
OPT_START_DMA, |
132 |
OPT_STOP_DMA, |
|
133 |
OPT_WAIT_IRQ, |
|
134 |
OPT_ITERATIONS, |
|
135 |
OPT_LIST_KMEM, |
|
136 |
OPT_FREE_KMEM, |
|
100
by root
Support exporting data from kernel buffers |
137 |
OPT_READ_KMEM, |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
138 |
OPT_FORCE, |
139 |
OPT_WAIT, |
|
140 |
OPT_MULTIPACKET
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
141 |
} OPTIONS; |
142 |
||
143 |
static struct option long_options[] = { |
|
144 |
{"device", required_argument, 0, OPT_DEVICE }, |
|
145 |
{"model", required_argument, 0, OPT_MODEL }, |
|
146 |
{"bar", required_argument, 0, OPT_BAR }, |
|
147 |
{"access", required_argument, 0, OPT_ACCESS }, |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
148 |
{"endianess", required_argument, 0, OPT_ENDIANESS }, |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
149 |
{"size", required_argument, 0, OPT_SIZE }, |
16
by Suren A. Chilingaryan
Prototype of IPECamera image protocol |
150 |
{"output", required_argument, 0, OPT_OUTPUT }, |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
151 |
{"timeout", required_argument, 0, OPT_TIMEOUT }, |
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
152 |
{"iterations", required_argument, 0, OPT_ITERATIONS }, |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
153 |
{"info", no_argument, 0, OPT_INFO }, |
154 |
{"list", no_argument, 0, OPT_LIST }, |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
155 |
{"reset", no_argument, 0, OPT_RESET }, |
45
by root
North West Logick DMA implementation |
156 |
{"benchmark", optional_argument, 0, OPT_BENCHMARK }, |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
157 |
{"read", optional_argument, 0, OPT_READ }, |
158 |
{"write", optional_argument, 0, OPT_WRITE }, |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
159 |
{"grab", optional_argument, 0, OPT_GRAB }, |
117
by Suren A. Chilingaryan
new event architecture, first trial |
160 |
{"trigger", optional_argument, 0, OPT_TRIGGER }, |
161 |
{"data", required_argument, 0, OPT_DATA_TYPE }, |
|
162 |
{"event", required_argument, 0, OPT_EVENT }, |
|
163 |
{"run-time", required_argument, 0, OPT_RUN_TIME }, |
|
164 |
{"trigger-rate", required_argument, 0, OPT_TRIGGER_RATE }, |
|
165 |
{"trigger-time", required_argument, 0, OPT_TRIGGER_TIME }, |
|
166 |
{"format", required_argument, 0, OPT_FORMAT }, |
|
167 |
{"buffer", optional_argument, 0, OPT_BUFFER }, |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
168 |
{"start-dma", required_argument, 0, OPT_START_DMA }, |
169 |
{"stop-dma", optional_argument, 0, OPT_STOP_DMA }, |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
170 |
{"list-dma-engines", no_argument, 0, OPT_LIST_DMA }, |
171 |
{"list-dma-buffers", required_argument, 0, OPT_LIST_DMA_BUFFERS }, |
|
172 |
{"read-dma-buffer", required_argument, 0, OPT_READ_DMA_BUFFER }, |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
173 |
{"wait-irq", optional_argument, 0, OPT_WAIT_IRQ }, |
80
by Suren A. Chilingaryan
List kernel buffers |
174 |
{"list-kernel-memory", no_argument, 0, OPT_LIST_KMEM }, |
100
by root
Support exporting data from kernel buffers |
175 |
{"read-kernel-memory", required_argument, 0, OPT_READ_KMEM }, |
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
176 |
{"free-kernel-memory", required_argument, 0, OPT_FREE_KMEM }, |
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
177 |
{"quiete", no_argument, 0, OPT_QUIETE }, |
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
178 |
{"force", no_argument, 0, OPT_FORCE }, |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
179 |
{"multipacket", no_argument, 0, OPT_MULTIPACKET }, |
180 |
{"wait", no_argument, 0, OPT_WAIT }, |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
181 |
{"help", no_argument, 0, OPT_HELP }, |
182 |
{ 0, 0, 0, 0 } |
|
183 |
};
|
|
184 |
||
185 |
||
186 |
void Usage(int argc, char *argv[], const char *format, ...) { |
|
187 |
if (format) { |
|
188 |
va_list ap; |
|
189 |
||
190 |
va_start(ap, format); |
|
191 |
printf("Error %i: ", errno); |
|
192 |
vprintf(format, ap); |
|
193 |
printf("\n"); |
|
194 |
va_end(ap); |
|
195 |
||
196 |
printf("\n"); |
|
197 |
}
|
|
198 |
||
199 |
||
200 |
printf( |
|
201 |
"Usage:\n" |
|
202 |
" %s <mode> [options] [hex data]\n" |
|
203 |
" Modes:\n" |
|
80
by Suren A. Chilingaryan
List kernel buffers |
204 |
" -i - Device Info\n" |
205 |
" -l[l] - List (detailed) Data Banks & Registers\n" |
|
206 |
" -r <addr|reg|dmaX> - Read Data/Register\n" |
|
207 |
" -w <addr|reg|dmaX> - Write Data/Register\n" |
|
101
by root
Remove short option for benchmark in cli |
208 |
" --benchmark <barX|dmaX> - Performance Evaluation\n" |
80
by Suren A. Chilingaryan
List kernel buffers |
209 |
" --reset - Reset board\n" |
210 |
" --help - Help message\n" |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
211 |
"\n" |
117
by Suren A. Chilingaryan
new event architecture, first trial |
212 |
" Event Modes:\n" |
213 |
" --trigger [event] - Trigger Events\n" |
|
214 |
" -g [event] - Grab Events\n" |
|
215 |
"\n" |
|
59
by Suren A. Chilingaryan
Reorganization of NWL engine, step 1 |
216 |
" DMA Modes:\n" |
80
by Suren A. Chilingaryan
List kernel buffers |
217 |
" --start-dma <num>[r|w] - Start specified DMA engine\n" |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
218 |
" --stop-dma [num[r|w]] - Stop specified engine or DMA subsystem\n" |
219 |
" --list-dma-engines - List active DMA engines\n" |
|
220 |
" --list-dma-buffers <dma> - List buffers for specified DMA engine\n" |
|
221 |
" --read-dma-buffer <dma:buf> - Read the specified buffer\n" |
|
80
by Suren A. Chilingaryan
List kernel buffers |
222 |
" --wait-irq <source> - Wait for IRQ\n" |
223 |
"\n" |
|
224 |
" Kernel Modes:\n" |
|
225 |
" --list-kernel-memory - List kernel buffers\n" |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
226 |
" --read-kernel-memory <blk> - Read the specified block of the kernel memory\n" |
100
by root
Support exporting data from kernel buffers |
227 |
" block is specified as: use:block_number\n" |
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
228 |
" --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n" |
229 |
" dma - Remove all buffers allocated by DMA subsystem\n" |
|
230 |
" #number - Remove all buffers with the specified use id\n" |
|
59
by Suren A. Chilingaryan
Reorganization of NWL engine, step 1 |
231 |
"\n" |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
232 |
" Addressing:\n" |
80
by Suren A. Chilingaryan
List kernel buffers |
233 |
" -d <device> - FPGA device (/dev/fpga0)\n" |
234 |
" -m <model> - Memory model (autodetected)\n" |
|
235 |
" pci - Plain\n" |
|
236 |
" ipecamera - IPE Camera\n" |
|
237 |
" -b <bank> - PCI bar, Register bank, or DMA channel\n" |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
238 |
"\n" |
239 |
" Options:\n" |
|
80
by Suren A. Chilingaryan
List kernel buffers |
240 |
" -s <size> - Number of words (default: 1)\n" |
241 |
" -a [fifo|dma]<bits> - Access type and bits per word (default: 32)\n" |
|
242 |
" -e <l|b> - Endianess Little/Big (default: host)\n" |
|
87
by Suren A. Chilingaryan
Support writting output to file |
243 |
" -o <file> - Append output to file (default: stdout)\n" |
80
by Suren A. Chilingaryan
List kernel buffers |
244 |
" -t <timeout> - Timeout in microseconds\n" |
14
by Suren A. Chilingaryan
Support memset operation |
245 |
"\n" |
117
by Suren A. Chilingaryan
new event architecture, first trial |
246 |
" Event Options:\n" |
247 |
" --event <evt> - Specifies event for trigger and grab modes\n" |
|
248 |
" --data <type> - Data type to request for the events\n" |
|
249 |
" --run-time <us> - Grab/trigger events during the specified time\n" |
|
250 |
" --trigger-rate <tps> - Generate tps triggers per second\n" |
|
251 |
" --trigger-time <us> - Specifies delay between triggers in microseconds\n" |
|
252 |
" -s <num|unlimited> - Number of events to grab and trigger\n" |
|
253 |
" --format [type] - Specifies how event data should be stored\n" |
|
254 |
" raw - Just write all events sequentially\n" |
|
255 |
" add_header - Prefix events with 256 bit header\n" |
|
256 |
" ringfs - Write to RingFS\n" |
|
257 |
" --buffer [size] - Request data buffering, size in MB\n" |
|
258 |
"\n" |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
259 |
" DMA Options:\n" |
260 |
" --multipacket - Read multiple packets\n" |
|
261 |
" --wait - Wait until data arrives\n" |
|
262 |
"\n" |
|
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
263 |
" Information:\n" |
80
by Suren A. Chilingaryan
List kernel buffers |
264 |
" -q - Quiete mode (suppress warnings)\n" |
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
265 |
"\n" |
14
by Suren A. Chilingaryan
Support memset operation |
266 |
" Data:\n" |
267 |
" Data can be specified as sequence of hexdecimal number or\n" |
|
268 |
" a single value prefixed with '*'. In this case it will be\n" |
|
269 |
" replicated the specified amount of times\n" |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
270 |
"\n\n", |
271 |
argv[0]); |
|
272 |
||
273 |
exit(0); |
|
274 |
}
|
|
275 |
||
276 |
void Error(const char *format, ...) { |
|
277 |
va_list ap; |
|
278 |
||
279 |
va_start(ap, format); |
|
280 |
printf("Error %i: ", errno); |
|
281 |
vprintf(format, ap); |
|
282 |
if (errno) printf("\n errno: %s", strerror(errno)); |
|
283 |
printf("\n\n"); |
|
284 |
va_end(ap); |
|
285 |
||
286 |
exit(-1); |
|
287 |
}
|
|
288 |
||
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
289 |
void Silence(const char *format, ...) { |
290 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
291 |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
292 |
void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) { |
117
by Suren A. Chilingaryan
new event architecture, first trial |
293 |
int i,j; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
294 |
pcilib_register_bank_description_t *banks; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
295 |
pcilib_register_description_t *registers; |
41
by root
A bit of DMA infrastructure |
296 |
pcilib_event_description_t *events; |
117
by Suren A. Chilingaryan
new event architecture, first trial |
297 |
pcilib_event_data_type_description_t *types; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
298 |
|
41
by root
A bit of DMA infrastructure |
299 |
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); |
300 |
const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle); |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
301 |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
302 |
for (i = 0; i < PCILIB_MAX_BANKS; i++) { |
303 |
if (board_info->bar_length[i] > 0) { |
|
304 |
printf(" BAR %d - ", i); |
|
305 |
||
306 |
switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) { |
|
307 |
case IORESOURCE_IO: printf(" IO"); break; |
|
308 |
case IORESOURCE_MEM: printf("MEM"); break; |
|
309 |
case IORESOURCE_IRQ: printf("IRQ"); break; |
|
310 |
case IORESOURCE_DMA: printf("DMA"); break; |
|
311 |
}
|
|
312 |
||
313 |
if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64"); |
|
314 |
else printf("32"); |
|
315 |
||
316 |
printf(", Start: 0x%08lx, Length: 0x%8lx, Flags: 0x%08lx\n", board_info->bar_start[i], board_info->bar_length[i], board_info->bar_flags[i] ); |
|
317 |
}
|
|
318 |
}
|
|
319 |
printf("\n"); |
|
41
by root
A bit of DMA infrastructure |
320 |
|
321 |
if ((dma_info)&&(dma_info->engines)) { |
|
322 |
printf("DMA Engines: \n"); |
|
323 |
for (i = 0; dma_info->engines[i]; i++) { |
|
324 |
pcilib_dma_engine_description_t *engine = dma_info->engines[i]; |
|
325 |
printf(" DMA %2d ", engine->addr); |
|
326 |
switch (engine->direction) { |
|
327 |
case PCILIB_DMA_FROM_DEVICE: |
|
328 |
printf("C2S"); |
|
329 |
break; |
|
330 |
case PCILIB_DMA_TO_DEVICE: |
|
331 |
printf("S2C"); |
|
332 |
break; |
|
333 |
case PCILIB_DMA_BIDIRECTIONAL: |
|
334 |
printf("BI "); |
|
335 |
break; |
|
336 |
}
|
|
337 |
printf(" - Type: "); |
|
338 |
switch (engine->type) { |
|
339 |
case PCILIB_DMA_TYPE_BLOCK: |
|
340 |
printf("Block"); |
|
341 |
break; |
|
342 |
case PCILIB_DMA_TYPE_PACKET: |
|
343 |
printf("Packet"); |
|
344 |
break; |
|
345 |
}
|
|
346 |
||
43
by root
Enumerate DMA engines |
347 |
printf(", Address Width: %02lu bits\n", engine->addr_bits); |
41
by root
A bit of DMA infrastructure |
348 |
}
|
43
by root
Enumerate DMA engines |
349 |
printf("\n"); |
41
by root
A bit of DMA infrastructure |
350 |
}
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
351 |
|
352 |
if ((bank)&&(bank != (char*)-1)) banks = NULL; |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
353 |
else banks = model_info->banks; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
354 |
|
355 |
if (banks) { |
|
356 |
printf("Banks: \n"); |
|
357 |
for (i = 0; banks[i].access; i++) { |
|
358 |
printf(" 0x%02x %s", banks[i].addr, banks[i].name); |
|
359 |
if ((banks[i].description)&&(banks[i].description[0])) { |
|
360 |
printf(": %s", banks[i].description); |
|
361 |
}
|
|
362 |
printf("\n"); |
|
363 |
}
|
|
364 |
printf("\n"); |
|
365 |
}
|
|
366 |
||
367 |
if (bank == (char*)-1) registers = NULL; |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
368 |
else registers = model_info->registers; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
369 |
|
370 |
if (registers) { |
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
371 |
pcilib_register_bank_addr_t bank_addr; |
372 |
if (bank) { |
|
373 |
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank); |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
374 |
pcilib_register_bank_description_t *b = model_info->banks + bank_id; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
375 |
|
376 |
bank_addr = b->addr; |
|
377 |
if (b->description) printf("%s:\n", b->description); |
|
378 |
else if (b->name) printf("Registers of bank %s:\n", b->name); |
|
379 |
else printf("Registers of bank 0x%x:\n", b->addr); |
|
380 |
} else { |
|
381 |
printf("Registers: \n"); |
|
382 |
}
|
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
383 |
for (i = 0; registers[i].bits; i++) { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
384 |
const char *mode; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
385 |
|
386 |
if ((bank)&&(registers[i].bank != bank_addr)) continue; |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
387 |
if (registers[i].type == PCILIB_REGISTER_BITS) { |
388 |
if (!details) continue; |
|
389 |
||
390 |
if (registers[i].bits > 1) { |
|
391 |
printf(" [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name); |
|
392 |
} else { |
|
393 |
printf(" [ %2u] - %s\n", registers[i].offset, registers[i].name); |
|
394 |
}
|
|
395 |
||
396 |
continue; |
|
397 |
}
|
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
398 |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
399 |
if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW"; |
400 |
else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R "; |
|
401 |
else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W"; |
|
402 |
else mode = " "; |
|
403 |
||
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
404 |
printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
405 |
if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
406 |
printf(": %s", registers[i].description); |
407 |
}
|
|
408 |
printf("\n"); |
|
409 |
||
410 |
}
|
|
411 |
printf("\n"); |
|
412 |
}
|
|
41
by root
A bit of DMA infrastructure |
413 |
|
414 |
if (bank == (char*)-1) events = NULL; |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
415 |
else { |
416 |
events = model_info->events; |
|
417 |
types = model_info->data_types; |
|
418 |
}
|
|
41
by root
A bit of DMA infrastructure |
419 |
|
420 |
if (events) { |
|
421 |
printf("Events: \n"); |
|
422 |
for (i = 0; events[i].name; i++) { |
|
423 |
printf(" %s", events[i].name); |
|
424 |
if ((events[i].description)&&(events[i].description[0])) { |
|
425 |
printf(": %s", events[i].description); |
|
426 |
}
|
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
427 |
|
428 |
if (types) { |
|
429 |
for (j = 0; types[j].name; j++) { |
|
430 |
if (types[j].evid & events[i].evid) { |
|
431 |
printf("\n %s", types[j].name); |
|
432 |
if ((types[j].description)&&(types[j].description[0])) { |
|
433 |
printf(": %s", types[j].description); |
|
434 |
}
|
|
435 |
}
|
|
436 |
}
|
|
437 |
}
|
|
41
by root
A bit of DMA infrastructure |
438 |
}
|
439 |
printf("\n"); |
|
440 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
441 |
}
|
442 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
443 |
void Info(pcilib_t *handle, pcilib_model_description_t *model_info) { |
41
by root
A bit of DMA infrastructure |
444 |
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
445 |
|
446 |
printf("Vendor: %x, Device: %x, Interrupt Pin: %i, Interrupt Line: %i\n", board_info->vendor_id, board_info->device_id, board_info->interrupt_pin, board_info->interrupt_line); |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
447 |
List(handle, model_info, (char*)-1, 0); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
448 |
}
|
449 |
||
450 |
||
71
by Suren A. Chilingaryan
First iteration of work to preserve DMA state between executions |
451 |
#define BENCH_MAX_DMA_SIZE 4 * 1024 * 1024
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
452 |
#define BENCH_MAX_FIFO_SIZE 1024 * 1024
|
453 |
||
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
454 |
int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, size_t iterations) { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
455 |
int err; |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
456 |
int i, j, errors; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
457 |
void *data, *buf, *check; |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
458 |
void *fifo; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
459 |
struct timeval start, end; |
460 |
unsigned long time; |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
461 |
size_t size, min_size, max_size; |
45
by root
North West Logick DMA implementation |
462 |
double mbs_in, mbs_out, mbs; |
55
by Suren A. Chilingaryan
IRQ support in NWL DMA engine |
463 |
size_t irqs; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
464 |
|
41
by root
A bit of DMA infrastructure |
465 |
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle); |
45
by root
North West Logick DMA implementation |
466 |
|
467 |
if (mode == ACCESS_DMA) { |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
468 |
if (n) { |
469 |
min_size = n * access; |
|
470 |
max_size = n * access; |
|
471 |
} else { |
|
472 |
min_size = 1024; |
|
473 |
max_size = BENCH_MAX_DMA_SIZE; |
|
474 |
}
|
|
475 |
||
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
476 |
for (size = min_size; size <= max_size; size *= 4) { |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
477 |
mbs_in = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_FROM_DEVICE); |
478 |
mbs_out = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_TO_DEVICE); |
|
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
479 |
mbs = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_BIDIRECTIONAL); |
55
by Suren A. Chilingaryan
IRQ support in NWL DMA engine |
480 |
err = pcilib_wait_irq(handle, 0, 0, &irqs); |
481 |
if (err) irqs = 0; |
|
482 |
||
45
by root
North West Logick DMA implementation |
483 |
printf("%8i KB - ", size / 1024); |
484 |
||
485 |
printf("RW: "); |
|
486 |
if (mbs < 0) printf("failed ... "); |
|
487 |
else printf("%8.2lf MB/s", mbs); |
|
488 |
||
489 |
printf(", R: "); |
|
490 |
if (mbs_in < 0) printf("failed ... "); |
|
491 |
else printf("%8.2lf MB/s", mbs_in); |
|
492 |
||
493 |
printf(", W: "); |
|
494 |
if (mbs_out < 0) printf("failed ... "); |
|
495 |
else printf("%8.2lf MB/s", mbs_out); |
|
55
by Suren A. Chilingaryan
IRQ support in NWL DMA engine |
496 |
|
497 |
if (irqs) { |
|
498 |
printf(", IRQs: %lu", irqs); |
|
499 |
}
|
|
45
by root
North West Logick DMA implementation |
500 |
|
501 |
printf("\n"); |
|
502 |
}
|
|
503 |
||
504 |
return 0; |
|
505 |
}
|
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
506 |
|
507 |
if (bar == PCILIB_BAR_INVALID) { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
508 |
unsigned long maxlength = 0; |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
509 |
|
510 |
||
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
511 |
for (i = 0; i < PCILIB_MAX_BANKS; i++) { |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
512 |
if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + access))) { |
513 |
bar = i; |
|
514 |
break; |
|
515 |
}
|
|
516 |
||
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
517 |
if (board_info->bar_length[i] > maxlength) { |
518 |
maxlength = board_info->bar_length[i]; |
|
519 |
bar = i; |
|
520 |
}
|
|
521 |
}
|
|
522 |
||
523 |
if (bar < 0) Error("Data banks are not available"); |
|
524 |
}
|
|
525 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
526 |
if (n) { |
527 |
if ((mode == ACCESS_BAR)&&(n * access > board_info->bar_length[bar])) Error("The specified size (%i) exceeds the size of bar (%i)", n * access, board_info->bar_length[bar]); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
528 |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
529 |
min_size = n * access; |
530 |
max_size = n * access; |
|
531 |
} else { |
|
532 |
min_size = access; |
|
533 |
if (mode == ACCESS_BAR) max_size = board_info->bar_length[bar]; |
|
534 |
else max_size = BENCH_MAX_FIFO_SIZE; |
|
535 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
536 |
|
537 |
err = posix_memalign( (void**)&buf, 256, max_size ); |
|
538 |
if (!err) err = posix_memalign( (void**)&check, 256, max_size ); |
|
539 |
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size); |
|
540 |
||
541 |
data = pcilib_map_bar(handle, bar); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
542 |
if (!data) Error("Can't map bar %i", bar); |
543 |
||
544 |
if (mode == ACCESS_FIFO) { |
|
545 |
fifo = data + (addr - board_info->bar_start[bar]) + (board_info->bar_start[bar] & pcilib_get_page_mask()); |
|
546 |
// pcilib_resolve_register_address(handle, bar, addr);
|
|
547 |
if (!fifo) Error("Can't resolve address (%lx) in bar (%u)", addr, bar); |
|
548 |
}
|
|
549 |
||
550 |
if (mode == ACCESS_FIFO) |
|
551 |
printf("Transfer time (Bank: %i, Fifo: %lx):\n", bar, addr); |
|
552 |
else
|
|
553 |
printf("Transfer time (Bank: %i):\n", bar); |
|
554 |
||
555 |
for (size = min_size ; size < max_size; size *= 8) { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
556 |
gettimeofday(&start,NULL); |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
557 |
if (mode == ACCESS_BAR) { |
558 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
559 |
pcilib_memcpy(buf, data, size); |
|
560 |
}
|
|
561 |
} else { |
|
562 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
563 |
for (j = 0; j < (size/access); j++) { |
|
564 |
pcilib_memcpy(buf + j * access, fifo, access); |
|
565 |
}
|
|
566 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
567 |
}
|
568 |
gettimeofday(&end,NULL); |
|
569 |
||
570 |
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
571 |
printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
572 |
|
573 |
fflush(0); |
|
574 |
||
575 |
gettimeofday(&start,NULL); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
576 |
if (mode == ACCESS_BAR) { |
577 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
578 |
pcilib_memcpy(data, buf, size); |
|
579 |
}
|
|
580 |
} else { |
|
581 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
582 |
for (j = 0; j < (size/access); j++) { |
|
583 |
pcilib_memcpy(fifo, buf + j * access, access); |
|
584 |
}
|
|
585 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
586 |
}
|
587 |
gettimeofday(&end,NULL); |
|
588 |
||
589 |
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
590 |
printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
591 |
}
|
592 |
||
593 |
pcilib_unmap_bar(handle, bar, data); |
|
594 |
||
595 |
printf("\n\nOpen-Transfer-Close time: \n"); |
|
596 |
||
597 |
for (size = 4 ; size < max_size; size *= 8) { |
|
598 |
gettimeofday(&start,NULL); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
599 |
if (mode == ACCESS_BAR) { |
600 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
601 |
pcilib_read(handle, bar, 0, size, buf); |
|
602 |
}
|
|
603 |
} else { |
|
604 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
605 |
pcilib_read_fifo(handle, bar, addr, access, size / access, buf); |
|
606 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
607 |
}
|
608 |
gettimeofday(&end,NULL); |
|
609 |
||
610 |
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
611 |
printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
612 |
|
613 |
fflush(0); |
|
614 |
||
615 |
gettimeofday(&start,NULL); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
616 |
if (mode == ACCESS_BAR) { |
617 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
618 |
pcilib_write(handle, bar, 0, size, buf); |
|
619 |
}
|
|
620 |
} else { |
|
621 |
for (i = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
622 |
pcilib_write_fifo(handle, bar, addr, access, size / access, buf); |
|
623 |
}
|
|
624 |
}
|
|
625 |
||
626 |
gettimeofday(&end,NULL); |
|
627 |
||
628 |
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); |
|
629 |
printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); |
|
630 |
||
631 |
if (mode == ACCESS_BAR) { |
|
632 |
gettimeofday(&start,NULL); |
|
633 |
for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) { |
|
634 |
pcilib_write(handle, bar, 0, size, buf); |
|
635 |
pcilib_read(handle, bar, 0, size, check); |
|
636 |
if (memcmp(buf, check, size)) ++errors; |
|
637 |
}
|
|
638 |
gettimeofday(&end,NULL); |
|
639 |
||
640 |
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); |
|
641 |
printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.)); |
|
642 |
if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS); |
|
643 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
644 |
printf("\n"); |
645 |
}
|
|
646 |
||
647 |
printf("\n\n"); |
|
648 |
||
649 |
free(check); |
|
650 |
free(buf); |
|
651 |
}
|
|
652 |
||
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
653 |
#define pci2host16(endianess, value) endianess?
|
654 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
655 |
/*
|
656 |
typedef struct {
|
|
657 |
size_t size;
|
|
658 |
void *data;
|
|
659 |
size_t pos;
|
|
660 |
||
661 |
int multi_mode;
|
|
662 |
} DMACallbackContext;
|
|
663 |
||
664 |
static int DMACallback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
|
|
665 |
DMACallbackContext *ctx = (DMACallbackContext*)arg;
|
|
666 |
|
|
667 |
if ((ctx->pos + bufsize > ctx->size)||(!ctx->data)) {
|
|
668 |
ctx->size *= 2;
|
|
669 |
ctx->data = realloc(ctx->data, ctx->size);
|
|
670 |
if (!ctx->data) {
|
|
671 |
Error("Allocation of %i bytes of memory have failed", ctx->size);
|
|
672 |
return 0;
|
|
673 |
}
|
|
674 |
}
|
|
675 |
|
|
676 |
memcpy(ctx->data + ctx->pos, buf, bufsize);
|
|
677 |
ctx->pos += bufsize;
|
|
678 |
||
679 |
if (flags & PCILIB_DMA_FLAG_EOP) return 0;
|
|
680 |
return 1;
|
|
681 |
}
|
|
682 |
*/
|
|
683 |
||
684 |
||
685 |
int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, size_t timeout, FILE *o) { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
686 |
void *buf; |
687 |
int i, err; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
688 |
size_t ret, bytes; |
112
by Suren A. Chilingaryan
Fix allocation of big memory buffers for DMA readout in pcitool |
689 |
size_t size = n * abs(access); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
690 |
int block_width, blocks_per_line; |
691 |
int numbers_per_block, numbers_per_line; |
|
49
by Suren A. Chilingaryan
A bit of renaming |
692 |
pcilib_dma_engine_t dmaid; |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
693 |
pcilib_dma_flags_t dma_flags = 0; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
694 |
|
695 |
numbers_per_block = BLOCK_SIZE / access; |
|
696 |
||
697 |
block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH); |
|
698 |
blocks_per_line = (LINE_WIDTH - 10) / (block_width + BLOCK_SEPARATOR_WIDTH); |
|
699 |
if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; |
|
700 |
numbers_per_line = blocks_per_line * numbers_per_block; |
|
701 |
||
109
by Suren A. Chilingaryan
Improvements of DMA engine |
702 |
if (size) { |
703 |
buf = malloc(size); |
|
112
by Suren A. Chilingaryan
Fix allocation of big memory buffers for DMA readout in pcitool |
704 |
if (!buf) Error("Allocation of %zu bytes of memory has failed", size); |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
705 |
} else { |
706 |
buf = NULL; |
|
707 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
708 |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
709 |
switch (mode) { |
710 |
case ACCESS_DMA: |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
711 |
if (timeout == (size_t)-1) timeout = PCILIB_DMA_TIMEOUT; |
712 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
713 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
714 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma); |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
715 |
|
716 |
if (flags&FLAG_MULTIPACKET) dma_flags |= PCILIB_DMA_FLAG_MULTIPACKET; |
|
717 |
if (flags&FLAG_WAIT) dma_flags |= PCILIB_DMA_FLAG_WAIT; |
|
718 |
||
719 |
if (size) { |
|
720 |
err = pcilib_read_dma_custom(handle, dmaid, addr, size, dma_flags, timeout, buf, &bytes); |
|
721 |
if (err) Error("Error (%i) is reported by DMA engine", err); |
|
722 |
} else { |
|
723 |
dma_flags |= PCILIB_DMA_FLAG_IGNORE_ERRORS; |
|
724 |
||
725 |
size = 2048; bytes = 0; |
|
726 |
do { |
|
727 |
size *= 2; |
|
728 |
buf = realloc(buf, size); |
|
112
by Suren A. Chilingaryan
Fix allocation of big memory buffers for DMA readout in pcitool |
729 |
if (!buf) Error("Allocation of %zu bytes of memory has failed", size); |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
730 |
err = pcilib_read_dma_custom(handle, dmaid, addr, size - bytes, dma_flags, timeout, buf + bytes, &ret); |
731 |
bytes += ret; |
|
732 |
||
733 |
if ((!err)&&(flags&FLAG_MULTIPACKET)) { |
|
734 |
err = PCILIB_ERROR_TOOBIG; |
|
735 |
if ((flags&FLAG_WAIT)==0) timeout = 0; |
|
736 |
}
|
|
737 |
} while (err == PCILIB_ERROR_TOOBIG); |
|
738 |
}
|
|
739 |
if (bytes <= 0) Error("No data is returned by DMA engine"); |
|
740 |
size = bytes; |
|
741 |
n = bytes / abs(access); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
742 |
addr = 0; |
743 |
break; |
|
744 |
case ACCESS_FIFO: |
|
745 |
pcilib_read_fifo(handle, bar, addr, access, n, buf); |
|
746 |
addr = 0; |
|
747 |
break; |
|
748 |
default: |
|
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
749 |
pcilib_read(handle, bar, addr, size, buf); |
750 |
}
|
|
87
by Suren A. Chilingaryan
Support writting output to file |
751 |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
752 |
if (endianess) pcilib_swap(buf, buf, abs(access), n); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
753 |
|
87
by Suren A. Chilingaryan
Support writting output to file |
754 |
if (o) { |
755 |
printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access)); |
|
756 |
fwrite(buf, abs(access), n, o); |
|
757 |
} else { |
|
758 |
for (i = 0; i < n; i++) { |
|
759 |
if (i) { |
|
760 |
if (i%numbers_per_line == 0) printf("\n"); |
|
761 |
else { |
|
762 |
printf("%*s", SEPARATOR_WIDTH, ""); |
|
763 |
if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); |
|
764 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
765 |
}
|
766 |
||
87
by Suren A. Chilingaryan
Support writting output to file |
767 |
if (i%numbers_per_line == 0) printf("%8lx: ", addr + i * abs(access)); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
768 |
|
87
by Suren A. Chilingaryan
Support writting output to file |
769 |
switch (access) { |
770 |
case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break; |
|
771 |
case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break; |
|
772 |
case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break; |
|
773 |
case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break; |
|
774 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
775 |
}
|
87
by Suren A. Chilingaryan
Support writting output to file |
776 |
printf("\n\n"); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
777 |
}
|
778 |
||
779 |
||
780 |
free(buf); |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
781 |
return 0; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
782 |
}
|
783 |
||
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
784 |
|
785 |
||
786 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
787 |
int ReadRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg) { |
39
by root
Move to new FPGA design |
788 |
int i; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
789 |
int err; |
39
by root
Move to new FPGA design |
790 |
const char *format; |
791 |
||
792 |
pcilib_register_bank_t bank_id; |
|
793 |
pcilib_register_bank_addr_t bank_addr; |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
794 |
|
795 |
pcilib_register_value_t value; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
796 |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
797 |
if (reg) { |
39
by root
Move to new FPGA design |
798 |
pcilib_register_t regid = pcilib_find_register(handle, bank, reg); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
799 |
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank); |
800 |
format = model_info->banks[bank_id].format; |
|
39
by root
Move to new FPGA design |
801 |
if (!format) format = "%lu"; |
802 |
||
803 |
err = pcilib_read_register_by_id(handle, regid, &value); |
|
804 |
// err = pcilib_read_register(handle, bank, reg, &value);
|
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
805 |
if (err) printf("Error reading register %s\n", reg); |
39
by root
Move to new FPGA design |
806 |
else { |
807 |
printf("%s = ", reg); |
|
808 |
printf(format, value); |
|
809 |
printf("\n"); |
|
810 |
}
|
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
811 |
} else { |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
812 |
// Adding DMA registers
|
813 |
pcilib_get_dma_info(handle); |
|
814 |
||
815 |
if (model_info->registers) { |
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
816 |
if (bank) { |
817 |
bank_id = pcilib_find_bank(handle, bank); |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
818 |
bank_addr = model_info->banks[bank_id].addr; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
819 |
}
|
820 |
||
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
821 |
printf("Registers:\n"); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
822 |
for (i = 0; model_info->registers[i].bits; i++) { |
823 |
if ((model_info->registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(model_info->registers[i].bank == bank_addr))&&(model_info->registers[i].type != PCILIB_REGISTER_BITS)) { |
|
824 |
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[i].bank); |
|
825 |
format = model_info->banks[bank_id].format; |
|
39
by root
Move to new FPGA design |
826 |
if (!format) format = "%lu"; |
827 |
||
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
828 |
err = pcilib_read_register_by_id(handle, i, &value); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
829 |
if (err) printf(" %s = error reading value", model_info->registers[i].name); |
39
by root
Move to new FPGA design |
830 |
else { |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
831 |
printf(" %s = ", model_info->registers[i].name); |
39
by root
Move to new FPGA design |
832 |
printf(format, value); |
833 |
}
|
|
834 |
||
835 |
printf(" ["); |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
836 |
printf(format, model_info->registers[i].defvalue); |
39
by root
Move to new FPGA design |
837 |
printf("]"); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
838 |
printf("\n"); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
839 |
}
|
840 |
}
|
|
841 |
} else { |
|
842 |
printf("No registers"); |
|
843 |
}
|
|
844 |
printf("\n"); |
|
845 |
}
|
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
846 |
|
847 |
return 0; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
848 |
}
|
849 |
||
87
by Suren A. Chilingaryan
Support writting output to file |
850 |
#define WRITE_REGVAL(buf, n, access, o) {\
|
851 |
uint##access##_t tbuf[n]; \
|
|
852 |
for (i = 0; i < n; i++) { \
|
|
853 |
tbuf[i] = (uint##access##_t)buf[i]; \
|
|
854 |
} \
|
|
855 |
fwrite(tbuf, access/8, n, o); \
|
|
856 |
}
|
|
857 |
||
858 |
int ReadRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, size_t n, FILE *o) { |
|
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
859 |
int err; |
860 |
int i; |
|
861 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
862 |
pcilib_register_bank_description_t *banks = model_info->banks; |
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
863 |
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank); |
864 |
||
865 |
if (bank_id == PCILIB_REGISTER_BANK_INVALID) { |
|
866 |
if (bank) Error("Invalid register bank is specified (%s)", bank); |
|
867 |
else Error("Register bank should be specified"); |
|
868 |
}
|
|
869 |
||
870 |
int access = banks[bank_id].access / 8; |
|
871 |
int size = n * abs(access); |
|
872 |
int block_width, blocks_per_line; |
|
873 |
int numbers_per_block, numbers_per_line; |
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
874 |
|
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
875 |
numbers_per_block = BLOCK_SIZE / access; |
876 |
||
877 |
block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH); |
|
878 |
blocks_per_line = (LINE_WIDTH - 6) / (block_width + BLOCK_SEPARATOR_WIDTH); |
|
879 |
if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; |
|
880 |
numbers_per_line = blocks_per_line * numbers_per_block; |
|
881 |
||
882 |
||
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
883 |
pcilib_register_value_t buf[n]; |
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
884 |
err = pcilib_read_register_space(handle, bank, addr, n, buf); |
885 |
if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); |
|
886 |
||
887 |
||
87
by Suren A. Chilingaryan
Support writting output to file |
888 |
if (o) { |
889 |
printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access)); |
|
890 |
switch (access) { |
|
891 |
case 1: WRITE_REGVAL(buf, n, 8, o) break; |
|
892 |
case 2: WRITE_REGVAL(buf, n, 16, o) break; |
|
893 |
case 4: WRITE_REGVAL(buf, n, 32, o) break; |
|
894 |
case 8: WRITE_REGVAL(buf, n, 64, o) break; |
|
895 |
}
|
|
896 |
} else { |
|
897 |
for (i = 0; i < n; i++) { |
|
898 |
if (i) { |
|
899 |
if (i%numbers_per_line == 0) printf("\n"); |
|
900 |
else { |
|
901 |
printf("%*s", SEPARATOR_WIDTH, ""); |
|
902 |
if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); |
|
903 |
}
|
|
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
904 |
}
|
905 |
||
87
by Suren A. Chilingaryan
Support writting output to file |
906 |
if (i%numbers_per_line == 0) printf("%4lx: ", addr + i); |
907 |
printf("%0*lx", access * 2, (unsigned long)buf[i]); |
|
908 |
}
|
|
909 |
printf("\n\n"); |
|
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
910 |
}
|
87
by Suren A. Chilingaryan
Support writting output to file |
911 |
|
912 |
return 0; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
913 |
}
|
914 |
||
49
by Suren A. Chilingaryan
A bit of renaming |
915 |
int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma, pcilib_bar_t bar, uintptr_t addr, size_t n, access_t access, int endianess, char ** data) { |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
916 |
int read_back = 0; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
917 |
void *buf, *check; |
918 |
int res, i, err; |
|
919 |
int size = n * abs(access); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
920 |
size_t ret; |
49
by Suren A. Chilingaryan
A bit of renaming |
921 |
pcilib_dma_engine_t dmaid; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
922 |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
923 |
err = posix_memalign( (void**)&buf, 256, size ); |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
924 |
if (!err) err = posix_memalign( (void**)&check, 256, size ); |
925 |
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
926 |
|
927 |
for (i = 0; i < n; i++) { |
|
928 |
switch (access) { |
|
929 |
case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break; |
|
930 |
case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break; |
|
931 |
case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break; |
|
932 |
case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break; |
|
933 |
}
|
|
7.1.5
by Suren A. Chilingaryan
Support for FPGA registers |
934 |
if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
935 |
}
|
936 |
||
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
937 |
if (endianess) pcilib_swap(buf, buf, abs(access), n); |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
938 |
|
939 |
switch (mode) { |
|
940 |
case ACCESS_DMA: |
|
941 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
942 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma); |
58
by Suren A. Chilingaryan
Wait for the completion of DMA operations during writes |
943 |
err = pcilib_write_dma(handle, dmaid, addr, size, buf, &ret); |
944 |
if ((err)||(ret != size)) { |
|
89
by Suren A. Chilingaryan
Few fixes for IPE Camera modification |
945 |
if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout writting the data to DMA"); |
946 |
else if (err) Error("DMA engine returned a error while writing the data"); |
|
947 |
else if (!ret) Error("No data is written by DMA engine"); |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
948 |
else Error("Only %lu bytes of %lu is written by DMA engine", ret, size); |
949 |
}
|
|
950 |
break; |
|
951 |
case ACCESS_FIFO: |
|
952 |
pcilib_write_fifo(handle, bar, addr, access, n, buf); |
|
953 |
break; |
|
954 |
default: |
|
955 |
pcilib_write(handle, bar, addr, size, buf); |
|
956 |
pcilib_read(handle, bar, addr, size, check); |
|
957 |
read_back = 1; |
|
958 |
}
|
|
959 |
||
960 |
if ((read_back)&&(memcmp(buf, check, size))) { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
961 |
printf("Write failed: the data written and read differ, the foolowing is read back:\n"); |
7.1.3
by Suren A. Chilingaryan
Fixes write verification failure if byte-swapping is in force |
962 |
if (endianess) pcilib_swap(check, check, abs(access), n); |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
963 |
ReadData(handle, mode, 0, dma, bar, addr, n, access, endianess, (size_t)-1, NULL); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
964 |
exit(-1); |
965 |
}
|
|
966 |
||
967 |
free(check); |
|
968 |
free(buf); |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
969 |
|
970 |
return 0; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
971 |
}
|
972 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
973 |
int WriteRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, size_t n, char ** data) { |
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
974 |
pcilib_register_value_t *buf, *check; |
975 |
int res, i, err; |
|
976 |
unsigned long value; |
|
977 |
int size = n * sizeof(pcilib_register_value_t); |
|
978 |
||
979 |
err = posix_memalign( (void**)&buf, 256, size ); |
|
980 |
if (!err) err = posix_memalign( (void**)&check, 256, size ); |
|
981 |
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); |
|
982 |
||
983 |
for (i = 0; i < n; i++) { |
|
984 |
res = sscanf(data[i], "%lx", &value); |
|
7.1.5
by Suren A. Chilingaryan
Support for FPGA registers |
985 |
if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); |
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
986 |
buf[i] = value; |
987 |
}
|
|
988 |
||
989 |
err = pcilib_write_register_space(handle, bank, addr, n, buf); |
|
990 |
if (err) Error("Error writting register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); |
|
991 |
||
992 |
err = pcilib_read_register_space(handle, bank, addr, n, check); |
|
993 |
if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n); |
|
994 |
||
995 |
if (memcmp(buf, check, size)) { |
|
996 |
printf("Write failed: the data written and read differ, the foolowing is read back:\n"); |
|
87
by Suren A. Chilingaryan
Support writting output to file |
997 |
ReadRegisterRange(handle, model_info, bank, addr, n, NULL); |
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
998 |
exit(-1); |
999 |
}
|
|
1000 |
||
1001 |
free(check); |
|
1002 |
free(buf); |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
1003 |
|
1004 |
return 0; |
|
7.1.4
by Suren A. Chilingaryan
Support writting and reading of register ranges |
1005 |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1006 |
}
|
1007 |
||
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
1008 |
int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg, char ** data) { |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1009 |
int err; |
1010 |
int i; |
|
1011 |
||
1012 |
unsigned long val; |
|
1013 |
pcilib_register_value_t value; |
|
66
by Suren A. Chilingaryan
Few fixes |
1014 |
|
67
by Suren A. Chilingaryan
Report writted register in hex if it was specified in hex |
1015 |
const char *format; |
1016 |
||
1017 |
pcilib_register_t regid = pcilib_find_register(handle, bank, reg); |
|
1018 |
if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected"); |
|
82
by Suren A. Chilingaryan
Do not try to verify write-only registers |
1019 |
|
1020 |
/*
|
|
1021 |
pcilib_register_bank_t bank_id;
|
|
1022 |
pcilib_register_bank_addr_t bank_addr;
|
|
1023 |
||
67
by Suren A. Chilingaryan
Report writted register in hex if it was specified in hex |
1024 |
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
|
1025 |
if (bank_id == PCILIB_REGISTER_BANK_INVALID) Error("Can't find bank of the register (%s)", reg);
|
|
1026 |
format = model_info->banks[bank_id].format;
|
|
1027 |
if (!format) format = "%lu";
|
|
1028 |
*/
|
|
1029 |
||
1030 |
if (isnumber(*data)) { |
|
66
by Suren A. Chilingaryan
Few fixes |
1031 |
if (sscanf(*data, "%li", &val) != 1) { |
1032 |
Error("Can't parse data value (%s) is not valid decimal number", *data); |
|
1033 |
}
|
|
67
by Suren A. Chilingaryan
Report writted register in hex if it was specified in hex |
1034 |
|
1035 |
format = "%li"; |
|
1036 |
} else if (isxnumber(*data)) { |
|
66
by Suren A. Chilingaryan
Few fixes |
1037 |
if (sscanf(*data, "%lx", &val) != 1) { |
1038 |
Error("Can't parse data value (%s) is not valid decimal number", *data); |
|
1039 |
}
|
|
67
by Suren A. Chilingaryan
Report writted register in hex if it was specified in hex |
1040 |
|
1041 |
format = "0x%lx"; |
|
66
by Suren A. Chilingaryan
Few fixes |
1042 |
} else { |
1043 |
Error("Can't parse data value (%s) is not valid decimal number", *data); |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1044 |
}
|
1045 |
||
1046 |
value = val; |
|
1047 |
||
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
1048 |
err = pcilib_write_register(handle, bank, reg, value); |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1049 |
if (err) Error("Error writting register %s\n", reg); |
1050 |
||
82
by Suren A. Chilingaryan
Do not try to verify write-only registers |
1051 |
if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) { |
1052 |
err = pcilib_read_register(handle, bank, reg, &value); |
|
1053 |
if (err) Error("Error reading back register %s for verification\n", reg); |
|
1054 |
||
1055 |
if (val != value) { |
|
1056 |
Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value); |
|
1057 |
} else { |
|
1058 |
printf("%s = ", reg); |
|
1059 |
printf(format, value); |
|
1060 |
printf("\n"); |
|
1061 |
}
|
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1062 |
} else { |
82
by Suren A. Chilingaryan
Do not try to verify write-only registers |
1063 |
printf("%s is written\n ", reg); |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1064 |
}
|
1065 |
||
1066 |
return 0; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1067 |
}
|
1068 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
1069 |
typedef struct { |
1070 |
pcilib_t *handle; |
|
1071 |
pcilib_event_t event; |
|
1072 |
pcilib_event_data_type_t data; |
|
1073 |
FILE *output; |
|
1074 |
||
1075 |
size_t run_time; |
|
1076 |
size_t trigger_time; |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1077 |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
1078 |
int run_flag; |
1079 |
} GRABContext; |
|
1080 |
||
1081 |
int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) { |
|
1082 |
/* int err;
|
|
1083 |
void *data;
|
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1084 |
size_t size, written;
|
1085 |
|
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
1086 |
GRABContext *ctx = (GRABContext*)user;
|
1087 |
pcilib_t *handle = ctx->handle;
|
|
1088 |
FILE *o = ctx->output;
|
|
1089 |
|
|
1090 |
data = pcilib_get_data(handle, ctx->event, ctx->data, &size);
|
|
1091 |
if (!data) Error("Internal Error: No data is provided to event callback");
|
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1092 |
|
87
by Suren A. Chilingaryan
Support writting output to file |
1093 |
if (o) printf("Writting %zu bytes into file...\n", size);
|
1094 |
else o = stdout;
|
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1095 |
|
1096 |
written = fwrite(data, 1, size, o);
|
|
1097 |
if (written != size) {
|
|
1098 |
if (written > 0) Error("Write failed, only %z bytes out of %z are stored", written, size);
|
|
1099 |
else Error("Write failed");
|
|
1100 |
}
|
|
1101 |
|
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
1102 |
pcilib_return_data(handle, ctx->event, data);
|
1103 |
*/
|
|
1104 |
||
1105 |
printf("data callback: %lu\n", event_id); |
|
1106 |
}
|
|
1107 |
||
1108 |
int raw_data(pcilib_event_id_t event_id, pcilib_event_info_t *info, pcilib_event_flags_t flags, size_t size, void *data, void *user) { |
|
1109 |
// printf("%i\n", event_id);
|
|
1110 |
}
|
|
1111 |
||
1112 |
void *Trigger(void *user) { |
|
1113 |
GRABContext *ctx = (GRABContext*)user; |
|
1114 |
||
1115 |
pcilib_trigger(ctx->handle, PCILIB_EVENT0, 0, NULL); |
|
1116 |
usleep(3000); |
|
1117 |
pcilib_trigger(ctx->handle, PCILIB_EVENT0, 0, NULL); |
|
1118 |
||
1119 |
return NULL; |
|
1120 |
}
|
|
1121 |
||
1122 |
int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *event, const char *data_type, size_t num, size_t run_time, size_t trigger_time, PARTITION partition, FORMAT format, size_t buffer_size, FILE *ofile) { |
|
1123 |
int err; |
|
1124 |
GRABContext ctx; |
|
1125 |
void *data = NULL; |
|
1126 |
size_t size, written; |
|
1127 |
||
1128 |
pthread_t trigger_thread; |
|
1129 |
||
1130 |
ctx.handle = handle; |
|
1131 |
ctx.output = ofile; |
|
1132 |
ctx.event = PCILIB_EVENT0; |
|
1133 |
ctx.run_time = run_time; |
|
1134 |
ctx.trigger_time = trigger_time; |
|
1135 |
||
1136 |
ctx.run_flag = 1; |
|
1137 |
||
1138 |
// ignoring event for now
|
|
1139 |
pcilib_configure_autostop(handle, 2, 1000000);//PCILIB_TIMEOUT_TRIGGER); |
|
1140 |
pcilib_configure_rawdata_callback(handle, &raw_data, NULL); |
|
1141 |
||
1142 |
err = pcilib_start(handle, PCILIB_EVENTS_ALL, PCILIB_EVENT_FLAGS_DEFAULT); |
|
1143 |
if (err) Error("Failed to start event engine, error %i", err); |
|
1144 |
||
1145 |
if (pthread_create(&trigger_thread, NULL, Trigger, (void*)&ctx)) |
|
1146 |
Error("Error starting trigger thread"); |
|
1147 |
||
1148 |
// sleep(1);
|
|
1149 |
err = pcilib_stream(handle, &GrabCallback, &ctx); |
|
1150 |
if (err) Error("Error streaming events, error %i", err); |
|
1151 |
||
1152 |
pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT); |
|
1153 |
||
1154 |
/*
|
|
1155 |
err = pcilib_grab(handle, PCILIB_EVENTS_ALL, &size, &data, PCILIB_TIMEOUT_TRIGGER);
|
|
1156 |
if (err) {
|
|
1157 |
Error("Grabbing event is failed");
|
|
1158 |
}
|
|
1159 |
*/
|
|
1160 |
ctx.run_flag = 0; |
|
1161 |
pthread_join(trigger_thread, NULL); |
|
1162 |
||
15
by Suren A. Chilingaryan
Infrastructure for event API |
1163 |
return 0; |
1164 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1165 |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
1166 |
/*
|
1167 |
int Trigger(pcilib_t *handle, const char *event, size_t triggers, size_t run_time, size_t trigger_time) {
|
|
1168 |
//
|
|
1169 |
}
|
|
1170 |
*/
|
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1171 |
int StartStopDMA(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction, int start) { |
1172 |
int err; |
|
1173 |
pcilib_dma_engine_t dmaid; |
|
1174 |
||
75
by Suren A. Chilingaryan
Few fixes |
1175 |
if (dma == PCILIB_DMA_ENGINE_ADDR_INVALID) { |
1176 |
const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle); |
|
1177 |
||
1178 |
if (start) Error("DMA engine should be specified"); |
|
1179 |
||
1180 |
for (dmaid = 0; dma_info->engines[dmaid]; dmaid++) { |
|
1181 |
err = pcilib_start_dma(handle, dmaid, 0); |
|
1182 |
if (err) Error("Error starting DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr); |
|
1183 |
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); |
|
1184 |
if (err) Error("Error stopping DMA Engine (%s %i)", ((dma_info->engines[dmaid]->direction == PCILIB_DMA_FROM_DEVICE)?"C2S":"S2C"), dma_info->engines[dmaid]->addr); |
|
1185 |
}
|
|
1186 |
||
1187 |
return 0; |
|
1188 |
}
|
|
1189 |
||
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1190 |
if (dma_direction&PCILIB_DMA_FROM_DEVICE) { |
75
by Suren A. Chilingaryan
Few fixes |
1191 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma); |
1192 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (C2S %lu) is specified", dma); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1193 |
|
1194 |
if (start) { |
|
74
by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation |
1195 |
err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1196 |
if (err) Error("Error starting DMA engine (C2S %lu)", dma); |
1197 |
} else { |
|
75
by Suren A. Chilingaryan
Few fixes |
1198 |
err = pcilib_start_dma(handle, dmaid, 0); |
1199 |
if (err) Error("Error starting DMA engine (C2S %lu)", dma); |
|
74
by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation |
1200 |
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1201 |
if (err) Error("Error stopping DMA engine (C2S %lu)", dma); |
1202 |
}
|
|
1203 |
}
|
|
75
by Suren A. Chilingaryan
Few fixes |
1204 |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1205 |
if (dma_direction&PCILIB_DMA_TO_DEVICE) { |
75
by Suren A. Chilingaryan
Few fixes |
1206 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma); |
1207 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (S2C %lu) is specified", dma); |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1208 |
|
1209 |
if (start) { |
|
74
by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation |
1210 |
err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1211 |
if (err) Error("Error starting DMA engine (S2C %lu)", dma); |
1212 |
} else { |
|
75
by Suren A. Chilingaryan
Few fixes |
1213 |
err = pcilib_start_dma(handle, dmaid, 0); |
1214 |
if (err) Error("Error starting DMA engine (S2C %lu)", dma); |
|
74
by Suren A. Chilingaryan
Implement DMA access synchronization for NWL implementation |
1215 |
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1216 |
if (err) Error("Error stopping DMA engine (S2C %lu)", dma); |
1217 |
}
|
|
1218 |
}
|
|
1219 |
||
1220 |
return 0; |
|
1221 |
}
|
|
1222 |
||
80
by Suren A. Chilingaryan
List kernel buffers |
1223 |
|
1224 |
typedef struct { |
|
1225 |
unsigned long use; |
|
1226 |
||
1227 |
int referenced; |
|
1228 |
int hw_lock; |
|
1229 |
int reusable; |
|
1230 |
int persistent; |
|
1231 |
int open; |
|
1232 |
||
1233 |
size_t count; |
|
1234 |
size_t size; |
|
1235 |
} kmem_use_info_t; |
|
1236 |
||
1237 |
#define MAX_USES 64
|
|
1238 |
||
1239 |
size_t FindUse(size_t *n_uses, kmem_use_info_t *uses, unsigned long use) { |
|
1240 |
size_t i, n = *n_uses; |
|
1241 |
||
1242 |
if (uses[n - 1].use == use) return n - 1; |
|
1243 |
||
1244 |
for (i = 1; i < (n - 1); i++) { |
|
1245 |
if (uses[i].use == use) return i; |
|
1246 |
}
|
|
1247 |
||
1248 |
if (n == MAX_USES) return 0; |
|
1249 |
||
1250 |
uses[n].use = use; |
|
1251 |
return (*n_uses)++; |
|
1252 |
}
|
|
1253 |
||
1254 |
char *PrintSize(char *str, size_t size) { |
|
1255 |
if (size >= 1073741824) sprintf(str, "%.1lf GB", 1.*size / 1073741824); |
|
1256 |
else if (size >= 1048576) sprintf(str, "%.1lf MB", 1.*size / 1048576); |
|
1257 |
else if (size >= 1024) sprintf(str, "%lu KB", size / 1024); |
|
1258 |
else sprintf(str, "%lu B ", size); |
|
1259 |
||
1260 |
return str; |
|
1261 |
}
|
|
1262 |
||
1263 |
int ListKMEM(pcilib_t *handle, const char *device) { |
|
1264 |
DIR *dir; |
|
1265 |
struct dirent *entry; |
|
1266 |
const char *pos; |
|
1267 |
char sysdir[256]; |
|
1268 |
char fname[256]; |
|
1269 |
char info[256]; |
|
1270 |
char stmp[256]; |
|
1271 |
||
1272 |
size_t useid, i, n_uses = 1; // Use 0 is for others |
|
1273 |
kmem_use_info_t uses[MAX_USES]; |
|
1274 |
||
1275 |
memset(uses, 0, sizeof(uses)); |
|
1276 |
||
1277 |
pos = strrchr(device, '/'); |
|
1278 |
if (pos) ++pos; |
|
1279 |
else pos = device; |
|
1280 |
||
1281 |
snprintf(sysdir, 255, "/sys/class/fpga/%s", pos); |
|
1282 |
||
1283 |
dir = opendir(sysdir); |
|
1284 |
if (!dir) Error("Can't open directory (%s)", sysdir); |
|
1285 |
||
1286 |
while ((entry = readdir(dir)) != NULL) { |
|
1287 |
FILE *f; |
|
1288 |
unsigned long use; |
|
1289 |
unsigned long size; |
|
1290 |
unsigned long refs; |
|
1291 |
unsigned long mode; |
|
1292 |
unsigned long hwref; |
|
1293 |
||
1294 |
if (strncmp(entry->d_name, "kbuf", 4)) continue; |
|
1295 |
if (!isnumber(entry->d_name+4)) continue; |
|
1296 |
||
1297 |
snprintf(fname, 255, "%s/%s", sysdir, entry->d_name); |
|
1298 |
f = fopen(fname, "r"); |
|
1299 |
if (!f) Error("Can't access file (%s)", fname); |
|
1300 |
||
1301 |
while(!feof(f)) { |
|
1302 |
fgets(info, 256, f); |
|
1303 |
if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16); |
|
1304 |
if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10); |
|
1305 |
if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10); |
|
1306 |
if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16); |
|
1307 |
if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10); |
|
1308 |
}
|
|
1309 |
fclose(f); |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1310 |
|
80
by Suren A. Chilingaryan
List kernel buffers |
1311 |
useid = FindUse(&n_uses, uses, use); |
1312 |
uses[useid].count++; |
|
1313 |
uses[useid].size += size; |
|
1314 |
if (refs) uses[useid].referenced = 1; |
|
1315 |
if (hwref) uses[useid].hw_lock = 1; |
|
1316 |
if (mode&KMEM_MODE_REUSABLE) uses[useid].reusable = 1; |
|
1317 |
if (mode&KMEM_MODE_PERSISTENT) uses[useid].persistent = 1; |
|
1318 |
if (mode&KMEM_MODE_COUNT) uses[useid].open = 1; |
|
1319 |
}
|
|
1320 |
closedir(dir); |
|
1321 |
||
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
1322 |
if ((n_uses == 1)&&(uses[0].count == 0)) { |
1323 |
printf("No kernel memory is allocated\n"); |
|
1324 |
return 0; |
|
1325 |
}
|
|
1326 |
||
100
by root
Support exporting data from kernel buffers |
1327 |
printf("Use Type Count Total Size REF Mode \n"); |
80
by Suren A. Chilingaryan
List kernel buffers |
1328 |
printf("--------------------------------------------------------------------------------\n"); |
1329 |
for (useid = 0; useid < n_uses; useid++) { |
|
1330 |
if (useid + 1 == n_uses) { |
|
1331 |
if (!uses[0].count) continue; |
|
1332 |
i = 0; |
|
1333 |
} else i = useid + 1; |
|
1334 |
||
100
by root
Support exporting data from kernel buffers |
1335 |
printf("%08lx ", uses[i].use); |
1336 |
if (!i) printf("All Others "); |
|
1337 |
else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_RING) printf("DMA%u %s Ring ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S")); |
|
1338 |
else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_DMA_PAGES) printf("DMA%u %s Pages ", uses[i].use&0x7F, ((uses[i].use&0x80)?"S2C":"C2S")); |
|
1339 |
else printf (" ", uses[i].use); |
|
1340 |
printf(" "); |
|
1341 |
printf("% 6lu", uses[i].count); |
|
80
by Suren A. Chilingaryan
List kernel buffers |
1342 |
printf(" "); |
100
by root
Support exporting data from kernel buffers |
1343 |
printf("% 10s", PrintSize(stmp, uses[i].size)); |
1344 |
printf(" "); |
|
80
by Suren A. Chilingaryan
List kernel buffers |
1345 |
if (uses[i].referenced&&uses[i].hw_lock) printf("HW+SW"); |
1346 |
else if (uses[i].referenced) printf(" SW"); |
|
1347 |
else if (uses[i].hw_lock) printf("HW "); |
|
1348 |
else printf(" - "); |
|
100
by root
Support exporting data from kernel buffers |
1349 |
printf(" "); |
80
by Suren A. Chilingaryan
List kernel buffers |
1350 |
if (uses[i].persistent) printf("Persistent"); |
1351 |
else if (uses[i].open) printf("Open "); |
|
1352 |
else if (uses[i].reusable) printf("Reusable "); |
|
1353 |
else printf("Closed "); |
|
1354 |
printf("\n"); |
|
1355 |
}
|
|
1356 |
printf("--------------------------------------------------------------------------------\n"); |
|
1357 |
printf("REF - Software/Hardware Reference, MODE - Reusable/Persistent/Open\n"); |
|
1358 |
||
1359 |
||
1360 |
return 0; |
|
1361 |
}
|
|
1362 |
||
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1363 |
int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t use, size_t block, size_t max_size, FILE *o) { |
100
by root
Support exporting data from kernel buffers |
1364 |
void *data; |
1365 |
size_t size; |
|
1366 |
pcilib_kmem_handle_t *kbuf; |
|
1367 |
||
1368 |
kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, use, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY); |
|
1369 |
if (!kbuf) { |
|
1370 |
printf("The specified kernel buffer is not allocated\n"); |
|
1371 |
return 0; |
|
1372 |
}
|
|
1373 |
||
1374 |
data = pcilib_kmem_get_block_ua(handle, kbuf, block); |
|
1375 |
if (data) { |
|
1376 |
size = pcilib_kmem_get_block_size(handle, kbuf, block); |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1377 |
if ((max_size)&&(size > max_size)) size = max_size; |
100
by root
Support exporting data from kernel buffers |
1378 |
fwrite(data, 1, size, o?o:stdout); |
1379 |
} else { |
|
1380 |
printf("The specified block is not existing\n"); |
|
1381 |
}
|
|
1382 |
||
1383 |
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE); |
|
1384 |
}
|
|
1385 |
||
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
1386 |
int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) { |
1387 |
int err; |
|
1388 |
int i; |
|
1389 |
||
1390 |
unsigned long useid; |
|
1391 |
||
1392 |
pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; |
|
1393 |
if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well. |
|
1394 |
||
1395 |
if (!strcasecmp(use, "dma")) { |
|
1396 |
for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) { |
|
1397 |
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags); |
|
1398 |
if (err) Error("Error cleaning DMA%i C2S Ring buffer", i); |
|
1399 |
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags); |
|
1400 |
if (err) Error("Error cleaning DMA%i S2C Ring buffer", i); |
|
1401 |
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags); |
|
1402 |
if (err) Error("Error cleaning DMA%i C2S Page buffers", i); |
|
1403 |
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags); |
|
1404 |
if (err) Error("Error cleaning DMA%i S2C Page buffers", i); |
|
1405 |
}
|
|
1406 |
||
1407 |
return 0; |
|
1408 |
}
|
|
1409 |
||
1410 |
if ((!isxnumber(use))||(sscanf(use, "%lx", &useid) != 1)) Error("Invalid use (%s) is specified", use); |
|
1411 |
||
1412 |
err = pcilib_clean_kernel_memory(handle, useid, flags); |
|
1413 |
if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid); |
|
1414 |
||
1415 |
return 0; |
|
1416 |
}
|
|
1417 |
||
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1418 |
int ListDMA(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info) { |
1419 |
int err; |
|
1420 |
||
1421 |
DIR *dir; |
|
1422 |
struct dirent *entry; |
|
1423 |
const char *pos; |
|
1424 |
char sysdir[256]; |
|
1425 |
char fname[256]; |
|
1426 |
char info[256]; |
|
1427 |
char stmp[256]; |
|
1428 |
||
1429 |
pcilib_dma_engine_t dmaid; |
|
1430 |
pcilib_dma_engine_status_t status; |
|
1431 |
||
1432 |
pos = strrchr(device, '/'); |
|
1433 |
if (pos) ++pos; |
|
1434 |
else pos = device; |
|
1435 |
||
1436 |
snprintf(sysdir, 255, "/sys/class/fpga/%s", pos); |
|
1437 |
||
1438 |
dir = opendir(sysdir); |
|
1439 |
if (!dir) Error("Can't open directory (%s)", sysdir); |
|
1440 |
||
104
by Suren A. Chilingaryan
Precisely estimate used buffers for C2S engines |
1441 |
printf("DMA Engine Status Total Size Buffer Ring (1st used - 1st free)\n"); |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1442 |
printf("--------------------------------------------------------------------------------\n"); |
1443 |
while ((entry = readdir(dir)) != NULL) { |
|
1444 |
FILE *f; |
|
1445 |
unsigned long use; |
|
1446 |
unsigned long size; |
|
1447 |
unsigned long refs; |
|
1448 |
unsigned long mode; |
|
1449 |
unsigned long hwref; |
|
1450 |
||
1451 |
if (strncmp(entry->d_name, "kbuf", 4)) continue; |
|
1452 |
if (!isnumber(entry->d_name+4)) continue; |
|
1453 |
||
1454 |
snprintf(fname, 255, "%s/%s", sysdir, entry->d_name); |
|
1455 |
f = fopen(fname, "r"); |
|
1456 |
if (!f) Error("Can't access file (%s)", fname); |
|
1457 |
||
1458 |
while(!feof(f)) { |
|
1459 |
fgets(info, 256, f); |
|
1460 |
if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16); |
|
1461 |
if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10); |
|
1462 |
if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10); |
|
1463 |
if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16); |
|
1464 |
if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10); |
|
1465 |
}
|
|
1466 |
fclose(f); |
|
1467 |
||
1468 |
if ((mode&(KMEM_MODE_REUSABLE|KMEM_MODE_PERSISTENT|KMEM_MODE_COUNT)) == 0) continue; // closed |
|
1469 |
if ((use >> 16) != PCILIB_KMEM_USE_DMA_RING) continue; |
|
1470 |
||
1471 |
if (use&0x80) { |
|
1472 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, use&0x7F); |
|
1473 |
} else { |
|
1474 |
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, use&0x7F); |
|
1475 |
}
|
|
1476 |
||
1477 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) continue; |
|
1478 |
||
1479 |
||
1480 |
printf("DMA%u %s ", use&0x7F, (use&0x80)?"S2C":"C2S"); |
|
1481 |
err = pcilib_start_dma(handle, dmaid, 0); |
|
1482 |
if (err) { |
|
1483 |
printf("-- Wrong state, start is failed\n"); |
|
1484 |
continue; |
|
1485 |
}
|
|
1486 |
||
1487 |
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); |
|
1488 |
if (err) { |
|
1489 |
printf("-- Wrong state, failed to obtain status\n"); |
|
1490 |
pcilib_stop_dma(handle, dmaid, 0); |
|
1491 |
continue; |
|
1492 |
}
|
|
1493 |
||
1494 |
pcilib_stop_dma(handle, dmaid, 0); |
|
1495 |
||
1496 |
if (status.started) printf("S"); |
|
1497 |
else printf(" "); |
|
1498 |
||
1499 |
if (status.ring_head == status.ring_tail) printf(" "); |
|
1500 |
else printf("D"); |
|
1501 |
||
1502 |
printf(" "); |
|
1503 |
printf("% 10s", PrintSize(stmp, status.ring_size * status.buffer_size)); |
|
1504 |
||
1505 |
printf(" "); |
|
1506 |
printf("%zu - %zu (of %zu)", status.ring_tail, status.ring_head, status.ring_size); |
|
1507 |
||
1508 |
printf("\n"); |
|
1509 |
||
1510 |
}
|
|
1511 |
closedir(dir); |
|
1512 |
||
1513 |
printf("--------------------------------------------------------------------------------\n"); |
|
1514 |
printf("S - Started, D - Data in buffers\n"); |
|
1515 |
||
1516 |
return 0; |
|
1517 |
}
|
|
1518 |
||
1519 |
int ListBuffers(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info, pcilib_dma_engine_addr_t dma, pcilib_dma_direction_t dma_direction) { |
|
1520 |
int err; |
|
1521 |
size_t i; |
|
1522 |
pcilib_dma_engine_t dmaid; |
|
1523 |
pcilib_dma_engine_status_t status; |
|
1524 |
pcilib_dma_buffer_status_t *buffer; |
|
1525 |
char stmp[256]; |
|
1526 |
||
1527 |
dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma); |
|
1528 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found"); |
|
1529 |
||
1530 |
err = pcilib_start_dma(handle, dmaid, 0); |
|
1531 |
if (err) Error("Error starting the specified DMA engine"); |
|
1532 |
||
1533 |
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); |
|
1534 |
if (err) Error("Failed to obtain status of the specified DMA engine"); |
|
1535 |
||
1536 |
buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t)); |
|
1537 |
if (!buffer) Error("Failed to allocate memory for status buffer"); |
|
1538 |
||
1539 |
err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer); |
|
1540 |
if (err) Error("Failed to obtain extended status of the specified DMA engine"); |
|
1541 |
||
1542 |
||
1543 |
printf("Buffer Status Total Size \n"); |
|
1544 |
printf("--------------------------------------------------------------------------------\n"); |
|
1545 |
||
1546 |
for (i = 0; i < status.ring_size; i++) { |
|
1547 |
printf("%8zu ", i); |
|
1548 |
printf("%c%c %c%c ", buffer[i].used?'U':' ', buffer[i].error?'E':' ', buffer[i].first?'F':' ', buffer[i].last?'L':' '); |
|
1549 |
printf("% 10s", PrintSize(stmp, buffer[i].size)); |
|
1550 |
printf("\n"); |
|
1551 |
}
|
|
1552 |
||
1553 |
printf("--------------------------------------------------------------------------------\n"); |
|
1554 |
printf("U - Used, E - Error, F - First block, L - Last Block\n"); |
|
1555 |
||
1556 |
free(buffer); |
|
1557 |
||
1558 |
pcilib_stop_dma(handle, dmaid, 0); |
|
1559 |
||
1560 |
}
|
|
1561 |
||
1562 |
int ReadBuffer(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, FILE *o) { |
|
1563 |
int err; |
|
1564 |
size_t i; |
|
1565 |
pcilib_dma_engine_t dmaid; |
|
1566 |
pcilib_dma_engine_status_t status; |
|
1567 |
pcilib_dma_buffer_status_t *buffer; |
|
1568 |
size_t size; |
|
1569 |
char stmp[256]; |
|
1570 |
||
1571 |
dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma); |
|
1572 |
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found"); |
|
1573 |
||
1574 |
err = pcilib_start_dma(handle, dmaid, 0); |
|
1575 |
if (err) Error("Error starting the specified DMA engine"); |
|
1576 |
||
1577 |
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL); |
|
1578 |
if (err) Error("Failed to obtain status of the specified DMA engine"); |
|
1579 |
||
1580 |
buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t)); |
|
1581 |
if (!buffer) Error("Failed to allocate memory for status buffer"); |
|
1582 |
||
1583 |
err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer); |
|
1584 |
if (err) Error("Failed to obtain extended status of the specified DMA engine"); |
|
1585 |
||
1586 |
if (block == (size_t)-1) { |
|
1587 |
// get current
|
|
1588 |
}
|
|
1589 |
||
1590 |
size = buffer[block].size; |
|
1591 |
||
1592 |
free(buffer); |
|
1593 |
||
1594 |
pcilib_stop_dma(handle, dmaid, 0); |
|
1595 |
||
1596 |
||
1597 |
||
1598 |
// printf("%i %i\n", dma, buffer);
|
|
1599 |
// printf("%lx\n", ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16));
|
|
1600 |
return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o); |
|
1601 |
}
|
|
1602 |
||
1603 |
||
1604 |
||
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
1605 |
int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) { |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1606 |
int err; |
1607 |
size_t count; |
|
1608 |
||
63
by Suren A. Chilingaryan
Provide IRQ enable/disable call |
1609 |
err = pcilib_enable_irq(handle, PCILIB_EVENT_IRQ, 0); |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1610 |
if (err) Error("Error enabling IRQs"); |
1611 |
||
1612 |
err = pcilib_wait_irq(handle, irq_source, timeout, &count); |
|
1613 |
if (err) { |
|
1614 |
if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout waiting for IRQ"); |
|
1615 |
else Error("Error waiting for IRQ"); |
|
1616 |
}
|
|
1617 |
||
1618 |
return 0; |
|
1619 |
}
|
|
1620 |
||
1621 |
||
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1622 |
int main(int argc, char **argv) { |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1623 |
int i; |
1624 |
long itmp; |
|
100
by root
Support exporting data from kernel buffers |
1625 |
unsigned long utmp; |
117
by Suren A. Chilingaryan
new event architecture, first trial |
1626 |
size_t ztmp; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1627 |
unsigned char c; |
1628 |
||
117
by Suren A. Chilingaryan
new event architecture, first trial |
1629 |
const char *stmp; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1630 |
const char *num_offset; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1631 |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
1632 |
int details = 0; |
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
1633 |
int quiete = 0; |
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
1634 |
int force = 0; |
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
1635 |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1636 |
pcilib_model_t model = PCILIB_MODEL_DETECT; |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
1637 |
pcilib_model_description_t *model_info; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1638 |
MODE mode = MODE_INVALID; |
117
by Suren A. Chilingaryan
new event architecture, first trial |
1639 |
GRAB_MODE grab_mode = 0; |
1640 |
size_t trigger_time = 0; |
|
1641 |
size_t run_time = 0; |
|
1642 |
size_t buffer = 0; |
|
1643 |
FORMAT format = FORMAT_RAW; |
|
1644 |
PARTITION partition = PARTITION_UNKNOWN; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
1645 |
FLAGS flags = 0; |
60
by Suren A. Chilingaryan
Fix compilation issues |
1646 |
const char *type = NULL; |
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
1647 |
ACCESS_MODE amode = ACCESS_BAR; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1648 |
const char *fpga_device = DEFAULT_FPGA_DEVICE; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1649 |
pcilib_bar_t bar = PCILIB_BAR_DETECT; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1650 |
const char *addr = NULL; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1651 |
const char *reg = NULL; |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
1652 |
const char *bank = NULL; |
14
by Suren A. Chilingaryan
Support memset operation |
1653 |
char **data = NULL; |
15
by Suren A. Chilingaryan
Infrastructure for event API |
1654 |
const char *event = NULL; |
117
by Suren A. Chilingaryan
new event architecture, first trial |
1655 |
const char *data_type = NULL; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1656 |
const char *dma_channel = NULL; |
80
by Suren A. Chilingaryan
List kernel buffers |
1657 |
const char *use = NULL; |
100
by root
Support exporting data from kernel buffers |
1658 |
pcilib_kmem_use_t use_id; |
1659 |
size_t block = 0; |
|
88
by Suren A. Chilingaryan
IRQ acknowledgement support in the engine API |
1660 |
pcilib_irq_hw_source_t irq_source; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1661 |
pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL; |
14
by Suren A. Chilingaryan
Support memset operation |
1662 |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1663 |
pcilib_dma_engine_addr_t dma = PCILIB_DMA_ENGINE_ADDR_INVALID; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1664 |
uintptr_t start = -1; |
1665 |
size_t size = 1; |
|
1666 |
access_t access = 4; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1667 |
int skip = 0; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1668 |
int endianess = 0; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1669 |
size_t timeout = 0; |
15
by Suren A. Chilingaryan
Infrastructure for event API |
1670 |
const char *output = NULL; |
87
by Suren A. Chilingaryan
Support writting output to file |
1671 |
FILE *ofile = NULL; |
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
1672 |
size_t iterations = BENCHMARK_ITERATIONS; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1673 |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1674 |
pcilib_t *handle; |
1675 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
1676 |
int size_set = 0; |
109
by Suren A. Chilingaryan
Improvements of DMA engine |
1677 |
int timeout_set = 0; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1678 |
|
101
by root
Remove short option for benchmark in cli |
1679 |
while ((c = getopt_long(argc, argv, "hqilr::w::g::d:m:t:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1680 |
extern int optind; |
1681 |
switch (c) { |
|
1682 |
case OPT_HELP: |
|
1683 |
Usage(argc, argv, NULL); |
|
1684 |
break; |
|
1685 |
case OPT_INFO: |
|
1686 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1687 |
||
1688 |
mode = MODE_INFO; |
|
1689 |
break; |
|
1690 |
case OPT_LIST: |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
1691 |
if (mode == MODE_LIST) details++; |
1692 |
else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1693 |
|
1694 |
mode = MODE_LIST; |
|
1695 |
break; |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1696 |
case OPT_RESET: |
1697 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1698 |
||
1699 |
mode = MODE_RESET; |
|
1700 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1701 |
case OPT_BENCHMARK: |
1702 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1703 |
||
1704 |
mode = MODE_BENCHMARK; |
|
45
by root
North West Logick DMA implementation |
1705 |
|
1706 |
if (optarg) addr = optarg; |
|
1707 |
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1708 |
break; |
1709 |
case OPT_READ: |
|
1710 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1711 |
||
1712 |
mode = MODE_READ; |
|
1713 |
if (optarg) addr = optarg; |
|
1714 |
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; |
|
1715 |
break; |
|
1716 |
case OPT_WRITE: |
|
1717 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1718 |
||
1719 |
mode = MODE_WRITE; |
|
1720 |
if (optarg) addr = optarg; |
|
1721 |
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; |
|
1722 |
break; |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1723 |
case OPT_GRAB: |
117
by Suren A. Chilingaryan
new event architecture, first trial |
1724 |
if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported"); |
1725 |
||
1726 |
mode = MODE_GRAB; |
|
1727 |
grab_mode |= GRAB_MODE_GRAB; |
|
1728 |
||
1729 |
stmp = NULL; |
|
1730 |
if (optarg) stmp = optarg; |
|
1731 |
else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; |
|
1732 |
||
1733 |
if (stmp) { |
|
1734 |
if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); |
|
1735 |
event = stmp; |
|
1736 |
}
|
|
1737 |
break; |
|
1738 |
case OPT_TRIGGER: |
|
1739 |
if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported"); |
|
1740 |
||
1741 |
mode = MODE_GRAB; |
|
1742 |
grab_mode |= GRAB_MODE_TRIGGER; |
|
1743 |
||
1744 |
stmp = NULL; |
|
1745 |
if (optarg) stmp = optarg; |
|
1746 |
else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++]; |
|
1747 |
||
1748 |
if (stmp) { |
|
1749 |
if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event"); |
|
1750 |
event = stmp; |
|
1751 |
}
|
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1752 |
break; |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1753 |
case OPT_LIST_DMA: |
1754 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1755 |
||
1756 |
mode = MODE_LIST_DMA; |
|
1757 |
break; |
|
1758 |
case OPT_LIST_DMA_BUFFERS: |
|
1759 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1760 |
||
1761 |
mode = MODE_LIST_DMA_BUFFERS; |
|
1762 |
dma_channel = optarg; |
|
1763 |
break; |
|
1764 |
case OPT_READ_DMA_BUFFER: |
|
1765 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1766 |
||
1767 |
mode = MODE_READ_DMA_BUFFER; |
|
1768 |
||
1769 |
num_offset = strchr(optarg, ':'); |
|
1770 |
||
1771 |
if (num_offset) { |
|
1772 |
if (sscanf(num_offset + 1, "%zu", &block) != 1) |
|
1773 |
Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1); |
|
1774 |
||
1775 |
*(char*)num_offset = 0; |
|
1776 |
} else block = (size_t)-1; |
|
1777 |
||
1778 |
dma_channel = optarg; |
|
1779 |
break; |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1780 |
case OPT_START_DMA: |
1781 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1782 |
||
1783 |
mode = MODE_START_DMA; |
|
1784 |
if (optarg) dma_channel = optarg; |
|
1785 |
else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++]; |
|
1786 |
break; |
|
1787 |
case OPT_STOP_DMA: |
|
1788 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1789 |
||
1790 |
mode = MODE_STOP_DMA; |
|
1791 |
if (optarg) dma_channel = optarg; |
|
1792 |
else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++]; |
|
1793 |
break; |
|
1794 |
case OPT_WAIT_IRQ: |
|
1795 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1796 |
||
1797 |
mode = MODE_WAIT_IRQ; |
|
1798 |
if (optarg) num_offset = optarg; |
|
1799 |
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; |
|
1800 |
||
1801 |
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) |
|
1802 |
Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset); |
|
1803 |
||
1804 |
irq_source = itmp; |
|
1805 |
break; |
|
80
by Suren A. Chilingaryan
List kernel buffers |
1806 |
case OPT_LIST_KMEM: |
1807 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1808 |
mode = MODE_LIST_KMEM; |
|
1809 |
break; |
|
100
by root
Support exporting data from kernel buffers |
1810 |
case OPT_READ_KMEM: |
1811 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1812 |
mode = MODE_READ_KMEM; |
|
1813 |
||
1814 |
num_offset = strchr(optarg, ':'); |
|
1815 |
||
1816 |
if (num_offset) { |
|
1817 |
if (sscanf(num_offset + 1, "%zu", &block) != 1) |
|
1818 |
Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1); |
|
1819 |
||
1820 |
*(char*)num_offset = 0; |
|
1821 |
}
|
|
1822 |
||
1823 |
if (sscanf(optarg, "%lx", &utmp) != 1) |
|
1824 |
Usage(argc, argv, "Invalid USE number is specified (%s)", optarg); |
|
1825 |
||
1826 |
if (!utmp) |
|
1827 |
Usage(argc, argv, "Can't read buffer with the unspecific use (use number is 0)"); |
|
1828 |
||
1829 |
use_id = utmp; |
|
1830 |
break; |
|
80
by Suren A. Chilingaryan
List kernel buffers |
1831 |
case OPT_FREE_KMEM: |
1832 |
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); |
|
1833 |
mode = MODE_FREE_KMEM; |
|
1834 |
||
1835 |
if (optarg) use = optarg; |
|
1836 |
else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++]; |
|
1837 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1838 |
case OPT_DEVICE: |
1839 |
fpga_device = optarg; |
|
1840 |
break; |
|
1841 |
case OPT_MODEL: |
|
1842 |
if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI; |
|
1843 |
else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA; |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
1844 |
else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg); |
1845 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1846 |
case OPT_BAR: |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
1847 |
bank = optarg; |
1848 |
// if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
|
|
1849 |
// else bar = itmp;
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1850 |
break; |
1851 |
case OPT_ACCESS: |
|
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1852 |
if (!strncasecmp(optarg, "fifo", 4)) { |
57
by Suren A. Chilingaryan
Minor improvement |
1853 |
type = "fifo"; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1854 |
num_offset = optarg + 4; |
1855 |
amode = ACCESS_FIFO; |
|
1856 |
} else if (!strncasecmp(optarg, "dma", 3)) { |
|
57
by Suren A. Chilingaryan
Minor improvement |
1857 |
type = "dma"; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1858 |
num_offset = optarg + 3; |
1859 |
amode = ACCESS_DMA; |
|
1860 |
} else if (!strncasecmp(optarg, "bar", 3)) { |
|
57
by Suren A. Chilingaryan
Minor improvement |
1861 |
type = "plain"; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1862 |
num_offset = optarg + 3; |
1863 |
amode = ACCESS_BAR; |
|
1864 |
} else if (!strncasecmp(optarg, "plain", 5)) { |
|
57
by Suren A. Chilingaryan
Minor improvement |
1865 |
type = "plain"; |
56
by Suren A. Chilingaryan
Change cli parameters (reserve -t parameter for future use as timeout) |
1866 |
num_offset = optarg + 5; |
1867 |
amode = ACCESS_BAR; |
|
1868 |
} else { |
|
1869 |
num_offset = optarg; |
|
1870 |
}
|
|
1871 |
||
1872 |
if (*num_offset) { |
|
1873 |
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1)) |
|
1874 |
Usage(argc, argv, "Invalid access type (%s) is specified", optarg); |
|
1875 |
||
1876 |
switch (itmp) { |
|
1877 |
case 8: access = 1; break; |
|
1878 |
case 16: access = 2; break; |
|
1879 |
case 32: access = 4; break; |
|
1880 |
case 64: access = 8; break; |
|
1881 |
default: Usage(argc, argv, "Invalid data width (%s) is specified", num_offset); |
|
1882 |
}
|
|
1883 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1884 |
break; |
1885 |
case OPT_SIZE: |
|
7.1.5
by Suren A. Chilingaryan
Support for FPGA registers |
1886 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) |
117
by Suren A. Chilingaryan
new event architecture, first trial |
1887 |
if (strcasecmp(optarg, "unlimited")) |
1888 |
Usage(argc, argv, "Invalid size is specified (%s)", optarg); |
|
1889 |
else
|
|
1890 |
size = (size_t)-1; |
|
1891 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
1892 |
size_set = 1; |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1893 |
break; |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1894 |
case OPT_ENDIANESS: |
1895 |
if ((*optarg == 'b')||(*optarg == 'B')) { |
|
1896 |
if (ntohs(1) == 1) endianess = 0; |
|
1897 |
else endianess = 1; |
|
1898 |
} else if ((*optarg == 'l')||(*optarg == 'L')) { |
|
1899 |
if (ntohs(1) == 1) endianess = 1; |
|
1900 |
else endianess = 0; |
|
1901 |
} else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg); |
|
1902 |
||
1903 |
break; |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1904 |
case OPT_TIMEOUT: |
1905 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &timeout) != 1)) |
|
1906 |
Usage(argc, argv, "Invalid timeout is specified (%s)", optarg); |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
1907 |
timeout_set = 1; |
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
1908 |
break; |
15
by Suren A. Chilingaryan
Infrastructure for event API |
1909 |
case OPT_OUTPUT: |
1910 |
output = optarg; |
|
1911 |
break; |
|
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
1912 |
case OPT_ITERATIONS: |
1913 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1)) |
|
1914 |
Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg); |
|
1915 |
break; |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
1916 |
case OPT_EVENT: |
1917 |
event = optarg; |
|
1918 |
break; |
|
1919 |
case OPT_DATA_TYPE: |
|
1920 |
data_type = optarg; |
|
1921 |
break; |
|
1922 |
case OPT_RUN_TIME: |
|
1923 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) |
|
1924 |
Usage(argc, argv, "Invalid timeout is specified (%s)", optarg); |
|
1925 |
break; |
|
1926 |
case OPT_TRIGGER_TIME: |
|
1927 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1)) |
|
1928 |
Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg); |
|
1929 |
break; |
|
1930 |
case OPT_TRIGGER_RATE: |
|
1931 |
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1)) |
|
1932 |
Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg); |
|
1933 |
||
1934 |
trigger_time = 1000000 / ztmp + (1000000 % ztmp)?1:0; |
|
1935 |
break; |
|
1936 |
case OPT_BUFFER: |
|
1937 |
if (optarg) num_offset = optarg; |
|
1938 |
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++]; |
|
1939 |
else num_offset = NULL; |
|
1940 |
||
1941 |
if (num_offset) { |
|
1942 |
if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1)) |
|
1943 |
Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset); |
|
1944 |
buffer *= 1024 * 1024; |
|
1945 |
} else { |
|
1946 |
buffer = get_free_memory(); |
|
1947 |
if (buffer < 256) Error("Not enough free memory (%lz MB) for buffering", buffer / 1024 / 1024); |
|
1948 |
||
1949 |
buffer -= 128 + buffer/16; |
|
1950 |
}
|
|
1951 |
break; |
|
1952 |
case OPT_FORMAT: |
|
1953 |
if (!strcasecmp(optarg, "add_header")) format = FORMAT_HEADER; |
|
1954 |
else if (!strcasecmp(optarg, "ringfs")) format = FORMAT_RINGFS; |
|
1955 |
else if (strcasecmp(optarg, "raw")) Error("Invalid format (%s) is specified", optarg); |
|
1956 |
break; |
|
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
1957 |
case OPT_QUIETE: |
1958 |
quiete = 1; |
|
1959 |
break; |
|
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
1960 |
case OPT_FORCE: |
1961 |
force = 1; |
|
1962 |
break; |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
1963 |
case OPT_MULTIPACKET: |
1964 |
flags |= FLAG_MULTIPACKET; |
|
1965 |
break; |
|
1966 |
case OPT_WAIT: |
|
1967 |
flags |= FLAG_WAIT; |
|
1968 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1969 |
default: |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
1970 |
Usage(argc, argv, "Unknown option (%s) with argument (%s)", optarg?argv[optind-2]:argv[optind-1], optarg?optarg:"(null)"); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1971 |
}
|
1972 |
}
|
|
1973 |
||
1974 |
if (mode == MODE_INVALID) { |
|
1975 |
if (argc > 1) Usage(argc, argv, "Operation is not specified"); |
|
1976 |
else Usage(argc, argv, NULL); |
|
1977 |
}
|
|
1978 |
||
25
by Suren A. Chilingaryan
Support quiete mode to suppress warnings |
1979 |
pcilib_set_error_handler(&Error, quiete?Silence:NULL); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1980 |
|
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1981 |
handle = pcilib_open(fpga_device, model); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1982 |
if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device); |
1983 |
||
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
1984 |
model = pcilib_get_model(handle); |
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
1985 |
model_info = pcilib_get_model_description(handle); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
1986 |
|
1987 |
switch (mode) { |
|
1988 |
case MODE_WRITE: |
|
1989 |
if (!addr) Usage(argc, argv, "The address is not specified"); |
|
14
by Suren A. Chilingaryan
Support memset operation |
1990 |
if (((argc - optind) == 1)&&(*argv[optind] == '*')) { |
1991 |
int vallen = strlen(argv[optind]); |
|
15
by Suren A. Chilingaryan
Infrastructure for event API |
1992 |
if (vallen > 1) { |
1993 |
data = (char**)malloc(size * (vallen + sizeof(char*))); |
|
1994 |
if (!data) Error("Error allocating memory for data array"); |
|
1995 |
||
1996 |
for (i = 0; i < size; i++) { |
|
1997 |
data[i] = ((char*)data) + size * sizeof(char*) + i * vallen; |
|
1998 |
strcpy(data[i], argv[optind] + 1); |
|
1999 |
}
|
|
2000 |
} else { |
|
2001 |
data = (char**)malloc(size * (9 + sizeof(char*))); |
|
2002 |
if (!data) Error("Error allocating memory for data array"); |
|
2003 |
||
2004 |
for (i = 0; i < size; i++) { |
|
2005 |
data[i] = ((char*)data) + size * sizeof(char*) + i * 9; |
|
2006 |
sprintf(data[i], "%x", i); |
|
2007 |
}
|
|
14
by Suren A. Chilingaryan
Support memset operation |
2008 |
}
|
2009 |
} else if ((argc - optind) == size) data = argv + optind; |
|
2010 |
else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2011 |
break; |
2012 |
case MODE_READ: |
|
2013 |
if (!addr) { |
|
2014 |
if (model == PCILIB_MODEL_PCI) { |
|
2015 |
Usage(argc, argv, "The address is not specified"); |
|
2016 |
} else ++mode; |
|
2017 |
}
|
|
2018 |
break; |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
2019 |
case MODE_START_DMA: |
2020 |
case MODE_STOP_DMA: |
|
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
2021 |
case MODE_LIST_DMA_BUFFERS: |
2022 |
case MODE_READ_DMA_BUFFER: |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
2023 |
if ((dma_channel)&&(*dma_channel)) { |
2024 |
itmp = strlen(dma_channel) - 1; |
|
2025 |
if (dma_channel[itmp] == 'r') dma_direction = PCILIB_DMA_FROM_DEVICE; |
|
2026 |
else if (dma_channel[itmp] == 'w') dma_direction = PCILIB_DMA_TO_DEVICE; |
|
2027 |
||
2028 |
if (dma_direction != PCILIB_DMA_BIDIRECTIONAL) itmp--; |
|
2029 |
||
2030 |
if (strncmp(dma_channel, "dma", 3)) num_offset = dma_channel; |
|
2031 |
else { |
|
2032 |
num_offset = dma_channel + 3; |
|
2033 |
itmp -= 3; |
|
2034 |
}
|
|
2035 |
||
2036 |
if (bank) { |
|
2037 |
if (strncmp(num_offset, bank, itmp)) Usage(argc, argv, "Conflicting DMA channels are specified in mode parameter (%s) and bank parameter (%s)", dma_channel, bank); |
|
2038 |
}
|
|
2039 |
||
2040 |
if (!isnumber_n(num_offset, itmp)) |
|
2041 |
Usage(argc, argv, "Invalid DMA channel (%s) is specified", dma_channel); |
|
2042 |
||
2043 |
dma = atoi(num_offset); |
|
2044 |
}
|
|
2045 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2046 |
default: |
2047 |
if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied"); |
|
2048 |
}
|
|
2049 |
||
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2050 |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2051 |
if (addr) { |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2052 |
if ((!strncmp(addr, "dma", 3))&&((addr[3]==0)||isnumber(addr+3))) { |
57
by Suren A. Chilingaryan
Minor improvement |
2053 |
if ((type)&&(amode != ACCESS_DMA)) Usage(argc, argv, "Conflicting access modes, the DMA read is requested, but access type is (%s)", type); |
51
by Suren A. Chilingaryan
Fix segmentation failure in DMA access mode |
2054 |
if (bank) { |
2055 |
if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting DMA channels are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank); |
|
2056 |
} else { |
|
2057 |
if (addr[3] == 0) Usage(argc, argv, "The DMA channel is not specified"); |
|
2058 |
}
|
|
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
2059 |
dma = atoi(addr + 3); |
2060 |
amode = ACCESS_DMA; |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2061 |
} else if ((!strncmp(addr, "bar", 3))&&((addr[3]==0)||isnumber(addr+3))) { |
57
by Suren A. Chilingaryan
Minor improvement |
2062 |
if ((type)&&(amode != ACCESS_BAR)) Usage(argc, argv, "Conflicting access modes, the plain PCI read is requested, but access type is (%s)", type); |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2063 |
if ((addr[3] != 0)&&(strcmp(addr + 3, bank))) Usage(argc, argv, "Conflicting PCI bars are specified in read parameter (%s) and bank parameter (%s)", addr + 3, bank); |
45
by root
North West Logick DMA implementation |
2064 |
bar = atoi(addr + 3); |
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2065 |
amode = ACCESS_BAR; |
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
2066 |
} else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) { |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2067 |
// check if the address in the register range
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
2068 |
pcilib_register_range_t *ranges = model_info->ranges; |
37
by Suren A. Chilingaryan
Do not crash if model is not defined |
2069 |
|
2070 |
if (ranges) { |
|
2071 |
for (i = 0; ranges[i].start != ranges[i].end; i++) |
|
2072 |
if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break; |
|
2073 |
||
2074 |
// register access in plain mode
|
|
102
by Suren A. Chilingaryan
Accept short addresses for IPECamera FPGA registers |
2075 |
if (ranges[i].start != ranges[i].end) { |
2076 |
pcilib_register_bank_t regbank = pcilib_find_bank_by_addr(handle, ranges[i].bank); |
|
2077 |
if (regbank == PCILIB_REGISTER_BANK_INVALID) Error("Configuration error: register bank specified in the address range is not found"); |
|
2078 |
||
2079 |
bank = model_info->banks[regbank].name; |
|
2080 |
start += ranges[i].addr_shift; |
|
2081 |
++mode; |
|
2082 |
}
|
|
37
by Suren A. Chilingaryan
Do not crash if model is not defined |
2083 |
}
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2084 |
} else { |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
2085 |
if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) { |
7.1.1
by Suren A. Chilingaryan
Initial support of IPECamera protocol |
2086 |
Usage(argc, argv, "Invalid address (%s) is specified", addr); |
2087 |
} else { |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2088 |
reg = addr; |
2089 |
++mode; |
|
2090 |
}
|
|
2091 |
}
|
|
2092 |
}
|
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
2093 |
|
2094 |
if (mode == MODE_GRAB) { |
|
2095 |
if (output) { |
|
2096 |
char fsname[128]; |
|
2097 |
if (!get_file_fs(output, 127, fsname)) { |
|
2098 |
if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4; |
|
2099 |
else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW; |
|
2100 |
}
|
|
2101 |
}
|
|
2102 |
}
|
|
2103 |
||
2104 |
if (mode != MODE_GRAB) { |
|
2105 |
if (size == (size_t)-1) |
|
2106 |
Usage(argc, argv, "Unlimited size is not supported in selected operation mode"); |
|
2107 |
}
|
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
2108 |
|
47
by Suren A. Chilingaryan
Support FIFO reading/writting, code restructurization, few fixes |
2109 |
|
2110 |
if ((bank)&&(amode == ACCESS_DMA)) { |
|
2111 |
if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)) |
|
2112 |
Usage(argc, argv, "Invalid DMA channel (%s) is specified", bank); |
|
2113 |
else dma = itmp; |
|
2114 |
} else if (bank) { |
|
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
2115 |
switch (mode) { |
2116 |
case MODE_BENCHMARK: |
|
2117 |
case MODE_READ: |
|
2118 |
case MODE_WRITE: |
|
7.1.5
by Suren A. Chilingaryan
Support for FPGA registers |
2119 |
if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) |
7.1.2
by Suren A. Chilingaryan
Better handling of register banks |
2120 |
Usage(argc, argv, "Invalid data bank (%s) is specified", bank); |
2121 |
else bar = itmp; |
|
2122 |
break; |
|
2123 |
default: |
|
2124 |
if (pcilib_find_bank(handle, bank) == PCILIB_REGISTER_BANK_INVALID) |
|
2125 |
Usage(argc, argv, "Invalid data bank (%s) is specified", bank); |
|
2126 |
}
|
|
2127 |
}
|
|
87
by Suren A. Chilingaryan
Support writting output to file |
2128 |
|
2129 |
if (output) { |
|
2130 |
ofile = fopen(output, "a+"); |
|
2131 |
if (!ofile) { |
|
2132 |
Error("Failed to open file \"%s\"", output); |
|
2133 |
}
|
|
2134 |
}
|
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2135 |
|
2136 |
switch (mode) { |
|
2137 |
case MODE_INFO: |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
2138 |
Info(handle, model_info); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2139 |
break; |
2140 |
case MODE_LIST: |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
2141 |
List(handle, model_info, bank, details); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2142 |
break; |
2143 |
case MODE_BENCHMARK: |
|
68
by Suren A. Chilingaryan
Support iterations argument and fix interpretation of size argument for benchmarking |
2144 |
Benchmark(handle, amode, dma, bar, start, size_set?size:0, access, iterations); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2145 |
break; |
2146 |
case MODE_READ: |
|
109
by Suren A. Chilingaryan
Improvements of DMA engine |
2147 |
if (amode == ACCESS_DMA) { |
2148 |
ReadData(handle, amode, flags, dma, bar, start, size_set?size:0, access, endianess, timeout_set?timeout:(size_t)-1, ofile); |
|
2149 |
} else if (addr) { |
|
2150 |
ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2151 |
} else { |
2152 |
Error("Address to read is not specified"); |
|
2153 |
}
|
|
2154 |
break; |
|
2155 |
case MODE_READ_REGISTER: |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
2156 |
if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg); |
87
by Suren A. Chilingaryan
Support writting output to file |
2157 |
else ReadRegisterRange(handle, model_info, bank, start, size, ofile); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2158 |
break; |
2159 |
case MODE_WRITE: |
|
44
by root
DMA engine initialization and basic intrastructure for DMA read/write |
2160 |
WriteData(handle, amode, dma, bar, start, size, access, endianess, data); |
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2161 |
break; |
2162 |
case MODE_WRITE_REGISTER: |
|
54
by Suren A. Chilingaryan
Support dynamic registers, support register offsets and multiregisters (bitmasks), list NWL DMA registers |
2163 |
if (reg) WriteRegister(handle, model_info, bank, reg, data); |
2164 |
else WriteRegisterRange(handle, model_info, bank, start, size, data); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2165 |
break; |
15
by Suren A. Chilingaryan
Infrastructure for event API |
2166 |
case MODE_RESET: |
2167 |
pcilib_reset(handle); |
|
2168 |
break; |
|
2169 |
case MODE_GRAB: |
|
117
by Suren A. Chilingaryan
new event architecture, first trial |
2170 |
TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, partition, format, buffer, ofile); |
15
by Suren A. Chilingaryan
Infrastructure for event API |
2171 |
break; |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
2172 |
case MODE_LIST_DMA: |
2173 |
ListDMA(handle, fpga_device, model_info); |
|
2174 |
break; |
|
2175 |
case MODE_LIST_DMA_BUFFERS: |
|
2176 |
ListBuffers(handle, fpga_device, model_info, dma, dma_direction); |
|
2177 |
break; |
|
2178 |
case MODE_READ_DMA_BUFFER: |
|
2179 |
ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile); |
|
2180 |
break; |
|
62
by Suren A. Chilingaryan
Suppport DMA modes in console application (not functional yet) |
2181 |
case MODE_START_DMA: |
2182 |
StartStopDMA(handle, model_info, dma, dma_direction, 1); |
|
2183 |
break; |
|
2184 |
case MODE_STOP_DMA: |
|
2185 |
StartStopDMA(handle, model_info, dma, dma_direction, 0); |
|
2186 |
break; |
|
2187 |
case MODE_WAIT_IRQ: |
|
2188 |
WaitIRQ(handle, model_info, irq_source, timeout); |
|
2189 |
break; |
|
80
by Suren A. Chilingaryan
List kernel buffers |
2190 |
case MODE_LIST_KMEM: |
2191 |
ListKMEM(handle, fpga_device); |
|
2192 |
break; |
|
100
by root
Support exporting data from kernel buffers |
2193 |
case MODE_READ_KMEM: |
103
by Suren A. Chilingaryan
Provide information about active DMA engines & buffers |
2194 |
ReadKMEM(handle, fpga_device, use_id, block, 0, ofile); |
100
by root
Support exporting data from kernel buffers |
2195 |
break; |
81
by Suren A. Chilingaryan
Support forceful clean-up of kernel memory |
2196 |
case MODE_FREE_KMEM: |
2197 |
FreeKMEM(handle, fpga_device, use, force); |
|
2198 |
break; |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2199 |
}
|
2200 |
||
87
by Suren A. Chilingaryan
Support writting output to file |
2201 |
if (ofile) fclose(ofile); |
2202 |
||
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2203 |
pcilib_close(handle); |
14
by Suren A. Chilingaryan
Support memset operation |
2204 |
|
2205 |
if (data != argv + optind) free(data); |
|
6
by Suren A. Chilingaryan
Initial support for registers, infrastructure only |
2206 |
}
|