1
#define _POSIX_C_SOURCE 200112L
13
#include <sys/ioctl.h>
17
#include <arpa/inet.h>
18
#include <sys/types.h>
26
#include <fastwriter.h>
28
#include "pcitool/sysinfo.h"
29
#include "pcitool/formaters.h"
38
//#define BIGBUFSIZE (512*1024*1024)
39
#define BIGBUFSIZE (1024*1024)
42
#define DEFAULT_FPGA_DEVICE "/dev/fpga0"
45
#define SEPARATOR_WIDTH 2
46
#define BLOCK_SEPARATOR_WIDTH 2
48
#define BENCHMARK_ITERATIONS 128
49
#define STATUS_MESSAGE_INTERVAL 5 /* seconds */
52
#define isnumber pcilib_isnumber
53
#define isxnumber pcilib_isxnumber
54
#define isnumber_n pcilib_isnumber_n
55
#define isxnumber_n pcilib_isxnumber_n
57
typedef uint8_t access_t;
78
MODE_LIST_DMA_BUFFERS,
145
OPT_LIST_DMA_BUFFERS,
168
static struct option long_options[] = {
169
{"device", required_argument, 0, OPT_DEVICE },
170
{"model", required_argument, 0, OPT_MODEL },
171
{"bar", required_argument, 0, OPT_BAR },
172
{"access", required_argument, 0, OPT_ACCESS },
173
{"endianess", required_argument, 0, OPT_ENDIANESS },
174
{"size", required_argument, 0, OPT_SIZE },
175
{"output", required_argument, 0, OPT_OUTPUT },
176
{"timeout", required_argument, 0, OPT_TIMEOUT },
177
{"iterations", required_argument, 0, OPT_ITERATIONS },
178
{"info", no_argument, 0, OPT_INFO },
179
{"list", no_argument, 0, OPT_LIST },
180
{"reset", no_argument, 0, OPT_RESET },
181
{"benchmark", optional_argument, 0, OPT_BENCHMARK },
182
{"read", optional_argument, 0, OPT_READ },
183
{"write", optional_argument, 0, OPT_WRITE },
184
{"grab", optional_argument, 0, OPT_GRAB },
185
{"trigger", optional_argument, 0, OPT_TRIGGER },
186
{"data", required_argument, 0, OPT_DATA_TYPE },
187
{"event", required_argument, 0, OPT_EVENT },
188
{"run-time", required_argument, 0, OPT_RUN_TIME },
189
{"trigger-rate", required_argument, 0, OPT_TRIGGER_RATE },
190
{"trigger-time", required_argument, 0, OPT_TRIGGER_TIME },
191
{"format", required_argument, 0, OPT_FORMAT },
192
{"buffer", optional_argument, 0, OPT_BUFFER },
193
{"threads", optional_argument, 0, OPT_THREADS },
194
{"start-dma", required_argument, 0, OPT_START_DMA },
195
{"stop-dma", optional_argument, 0, OPT_STOP_DMA },
196
{"list-dma-engines", no_argument, 0, OPT_LIST_DMA },
197
{"list-dma-buffers", required_argument, 0, OPT_LIST_DMA_BUFFERS },
198
{"read-dma-buffer", required_argument, 0, OPT_READ_DMA_BUFFER },
199
{"enable-irq", optional_argument, 0, OPT_ENABLE_IRQ },
200
{"disable-irq", optional_argument, 0, OPT_DISABLE_IRQ },
201
{"acknowledge-irq", optional_argument, 0, OPT_ACK_IRQ },
202
{"wait-irq", optional_argument, 0, OPT_WAIT_IRQ },
203
{"list-kernel-memory", optional_argument, 0, OPT_LIST_KMEM },
204
{"read-kernel-memory", required_argument, 0, OPT_READ_KMEM },
205
{"alloc-kernel-memory", required_argument, 0, OPT_ALLOC_KMEM },
206
{"free-kernel-memory", required_argument, 0, OPT_FREE_KMEM },
207
{"type", required_argument, 0, OPT_TYPE },
208
{"block-size", required_argument, 0, OPT_BLOCK_SIZE },
209
{"alignment", required_argument, 0, OPT_ALIGNMENT },
210
{"quiete", no_argument, 0, OPT_QUIETE },
211
{"verbose", optional_argument, 0, OPT_VERBOSE },
212
{"force", no_argument, 0, OPT_FORCE },
213
{"verify", no_argument, 0, OPT_VERIFY },
214
{"multipacket", no_argument, 0, OPT_MULTIPACKET },
215
{"wait", no_argument, 0, OPT_WAIT },
216
{"help", no_argument, 0, OPT_HELP },
221
void Usage(int argc, char *argv[], const char *format, ...) {
225
va_start(ap, format);
226
printf("Error %i: ", errno);
237
" %s <mode> [options] [hex data]\n"
239
" -i - Device Info\n"
240
" -l[l] - List (detailed) Data Banks & Registers\n"
241
" -r <addr|reg|dmaX> - Read Data/Register\n"
242
" -w <addr|reg|dmaX> - Write Data/Register\n"
243
" --benchmark <barX|dmaX> - Performance Evaluation\n"
244
" --reset - Reset board\n"
245
" --help - Help message\n"
248
" --trigger [event] - Trigger Events\n"
249
" -g [event] - Grab Events\n"
252
" --enable-irq [type] - Enable IRQs\n"
253
" --disable-irq [type] - Disable IRQs\n"
254
" --acknowledge-irq <source> - Clean IRQ queue\n"
255
" --wait-irq <source> - Wait for IRQ\n"
258
" --start-dma <num>[r|w] - Start specified DMA engine\n"
259
" --stop-dma [num[r|w]] - Stop specified engine or DMA subsystem\n"
260
" --list-dma-engines - List active DMA engines\n"
261
" --list-dma-buffers <dma> - List buffers for specified DMA engine\n"
262
" --read-dma-buffer <dma:buf> - Read the specified buffer\n"
265
" --list-kernel-memory [use] - List kernel buffers\n"
266
" --read-kernel-memory <blk> - Read the specified block of the kernel memory\n"
267
" block is specified as: use:block_number\n"
268
" --alloc-kernel-memory <use> - Allocate kernel buffers (DANGEROUS)\n"
269
" --free-kernel-memory <use> - Cleans lost kernel space buffers (DANGEROUS)\n"
270
" dma - Remove all buffers allocated by DMA subsystem\n"
271
" #number - Remove all buffers with the specified use id\n"
274
" -d <device> - FPGA device (/dev/fpga0)\n"
275
" -m <model> - Memory model (autodetected)\n"
277
" ipecamera - IPE Camera\n"
278
" -b <bank> - PCI bar, Register bank, or DMA channel\n"
281
" -s <size> - Number of words (default: 1)\n"
282
" -a [fifo|dma|config]<bits> - Access type and bits per word (default: 32)\n"
283
" -e <l|b> - Endianess Little/Big (default: host)\n"
284
" -o <file> - Append output to file (default: stdout)\n"
285
" -t <timeout|unlimited> - Timeout in microseconds\n"
286
" --check - Verify write operations\n"
289
" --event <evt> - Specifies event for trigger and grab modes\n"
290
" --data <type> - Data type to request for the events\n"
291
" --run-time <us> - Limit time to grab/trigger events\n"
292
" -t <timeout|unlimited> - Timeout to stop if no events triggered\n"
293
" --trigger-rate <tps> - Generate tps triggers per second\n"
294
" --trigger-time <us> - Specifies delay between triggers (us)\n"
295
" -s <num|unlimited> - Number of events to grab and trigger\n"
296
" --format [type] - Specifies how event data should be stored\n"
297
" raw - Just write all events sequentially\n"
298
" add_header - Prefix events with 512 bit header:\n"
299
" event(64), data(64), nope(64), size(64)\n"
300
" seqnum(64), offset(64), timestamp(128)\n"
301
//" ringfs - Write to RingFS\n"
302
" --buffer [size] - Request data buffering, size in MB\n"
303
" --threads [num] - Allow multithreaded processing\n"
306
" --multipacket - Read multiple packets\n"
307
" --wait - Wait until data arrives\n"
310
" --type <type> - Type of kernel memory to allocate\n"
311
" consistent - Consistent memory\n"
312
" s2c - DMA S2C (write) memory\n"
313
" c2s - DMA C2S (read) memory\n"
314
" --page-size <size> - Size of kernel buffer in bytes (default: page)\n"
315
" -s <size> - Number of buffers to allocate (default: 1)\n"
316
" --allignment <alignment> - Buffer alignment (default: page)\n"
319
" --verbose [level] - Announce details of ongoing operations\n"
320
" -q - Quiete mode (suppress warnings)\n"
323
" Data can be specified as sequence of hexdecimal number or\n"
324
" a single value prefixed with '*'. In this case it will be\n"
325
" replicated the specified amount of times\n"
332
static int StopFlag = 0;
334
static void signal_exit_handler(int signo) {
340
void Error(const char *format, ...) {
343
va_start(ap, format);
344
printf("Error %i: ", errno);
346
if (errno) printf("\n errno: %s", strerror(errno));
353
void Silence(const char *format, ...) {
356
void List(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, int details) {
358
pcilib_register_bank_description_t *banks;
359
pcilib_register_description_t *registers;
360
pcilib_event_description_t *events;
361
pcilib_event_data_type_description_t *types;
363
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
364
const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
366
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
367
if (board_info->bar_length[i] > 0) {
368
printf(" BAR %d - ", i);
370
switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) {
371
case IORESOURCE_IO: printf(" IO"); break;
372
case IORESOURCE_MEM: printf("MEM"); break;
373
case IORESOURCE_IRQ: printf("IRQ"); break;
374
case IORESOURCE_DMA: printf("DMA"); break;
377
if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64");
380
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] );
385
if ((dma_info)&&(dma_info->engines)) {
386
printf("DMA Engines: \n");
387
for (i = 0; dma_info->engines[i]; i++) {
388
pcilib_dma_engine_description_t *engine = dma_info->engines[i];
389
printf(" DMA %2d ", engine->addr);
390
switch (engine->direction) {
391
case PCILIB_DMA_FROM_DEVICE:
394
case PCILIB_DMA_TO_DEVICE:
397
case PCILIB_DMA_BIDIRECTIONAL:
402
switch (engine->type) {
403
case PCILIB_DMA_TYPE_BLOCK:
406
case PCILIB_DMA_TYPE_PACKET:
413
printf(", Address Width: %02lu bits\n", engine->addr_bits);
418
if ((bank)&&(bank != (char*)-1)) banks = NULL;
419
else banks = model_info->banks;
423
for (i = 0; banks[i].access; i++) {
424
printf(" 0x%02x %s", banks[i].addr, banks[i].name);
425
if ((banks[i].description)&&(banks[i].description[0])) {
426
printf(": %s", banks[i].description);
433
if (bank == (char*)-1) registers = NULL;
434
else registers = model_info->registers;
437
pcilib_register_bank_addr_t bank_addr = 0;
439
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
440
pcilib_register_bank_description_t *b = model_info->banks + bank_id;
443
if (b->description) printf("%s:\n", b->description);
444
else if (b->name) printf("Registers of bank %s:\n", b->name);
445
else printf("Registers of bank 0x%x:\n", b->addr);
447
printf("Registers: \n");
449
for (i = 0; registers[i].bits; i++) {
452
if ((bank)&&(registers[i].bank != bank_addr)) continue;
453
if (registers[i].type == PCILIB_REGISTER_BITS) {
454
if (!details) continue;
456
if (registers[i].bits > 1) {
457
printf(" [%2u:%2u] - %s\n", registers[i].offset, registers[i].offset + registers[i].bits, registers[i].name);
459
printf(" [ %2u] - %s\n", registers[i].offset, registers[i].name);
465
if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW";
466
else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R ";
467
else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W";
470
printf(" 0x%02x (%2i %s) %s", registers[i].addr, registers[i].bits, mode, registers[i].name);
471
if ((details > 0)&&(registers[i].description)&&(registers[i].description[0])) {
472
printf(": %s", registers[i].description);
480
if (bank == (char*)-1) events = NULL;
482
events = model_info->events;
483
types = model_info->data_types;
487
printf("Events: \n");
488
for (i = 0; events[i].name; i++) {
489
printf(" %s", events[i].name);
490
if ((events[i].description)&&(events[i].description[0])) {
491
printf(": %s", events[i].description);
495
for (j = 0; types[j].name; j++) {
496
if (types[j].evid & events[i].evid) {
497
printf("\n %s", types[j].name);
498
if ((types[j].description)&&(types[j].description[0])) {
499
printf(": %s", types[j].description);
509
void Info(pcilib_t *handle, pcilib_model_description_t *model_info) {
510
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
512
printf("Vendor: %x, Device: %x, Bus: %x, Slot: %x, Function: %x\n", board_info->vendor_id, board_info->device_id, board_info->bus, board_info->slot, board_info->func);
513
printf(" Interrupt - Pin: %i, Line: %i\n", board_info->interrupt_pin, board_info->interrupt_line);
514
List(handle, model_info, (char*)-1, 0);
518
#define BENCH_MAX_DMA_SIZE 4 * 1024 * 1024
519
#define BENCH_MAX_FIFO_SIZE 1024 * 1024
521
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) {
524
void *data, *buf, *check;
526
struct timeval start, end;
528
size_t size, min_size, max_size;
529
double mbs_in, mbs_out, mbs;
532
const pcilib_board_info_t *board_info = pcilib_get_board_info(handle);
534
if (mode == ACCESS_CONFIG)
535
Error("No benchmarking of configuration space acess is allowed");
537
if (mode == ACCESS_DMA) {
539
min_size = n * access;
540
max_size = n * access;
543
max_size = BENCH_MAX_DMA_SIZE;
546
for (size = min_size; size <= max_size; size *= 4) {
547
mbs_in = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_FROM_DEVICE);
548
mbs_out = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_TO_DEVICE);
549
mbs = pcilib_benchmark_dma(handle, dma, addr, size, iterations, PCILIB_DMA_BIDIRECTIONAL);
550
err = pcilib_wait_irq(handle, 0, 0, &irqs);
553
printf("%8zu KB - ", size / 1024);
556
if (mbs < 0) printf("failed ... ");
557
else printf("%8.2lf MB/s", mbs);
560
if (mbs_in < 0) printf("failed ... ");
561
else printf("%8.2lf MB/s", mbs_in);
564
if (mbs_out < 0) printf("failed ... ");
565
else printf("%8.2lf MB/s", mbs_out);
568
printf(", IRQs: %lu", irqs);
577
if (bar == PCILIB_BAR_INVALID) {
578
unsigned long maxlength = 0;
581
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
582
if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + access))) {
587
if (board_info->bar_length[i] > maxlength) {
588
maxlength = board_info->bar_length[i];
593
if (bar < 0) Error("Data banks are not available");
597
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]);
599
min_size = n * access;
600
max_size = n * access;
603
if (mode == ACCESS_BAR) max_size = board_info->bar_length[bar];
604
else max_size = BENCH_MAX_FIFO_SIZE;
607
err = posix_memalign( (void**)&buf, 256, max_size );
608
if (!err) err = posix_memalign( (void**)&check, 256, max_size );
609
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size);
611
data = pcilib_map_bar(handle, bar);
612
if (!data) Error("Can't map bar %i", bar);
614
if (mode == ACCESS_FIFO) {
615
fifo = data + (addr - board_info->bar_start[bar]) + (board_info->bar_start[bar] & pcilib_get_page_mask());
616
// pcilib_resolve_register_address(handle, bar, addr);
617
if (!fifo) Error("Can't resolve address (%lx) in bar (%u)", addr, bar);
620
if (mode == ACCESS_FIFO)
621
printf("Transfer time (Bank: %i, Fifo: %lx):\n", bar, addr);
623
printf("Transfer time (Bank: %i):\n", bar);
625
for (size = min_size ; size < max_size; size *= 8) {
626
gettimeofday(&start,NULL);
627
if (mode == ACCESS_BAR) {
628
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
629
pcilib_memcpy(buf, data, size);
632
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
633
for (j = 0; j < (size/access); j++) {
634
pcilib_memcpy(buf + j * access, fifo, access);
638
gettimeofday(&end,NULL);
640
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
641
printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
645
gettimeofday(&start,NULL);
646
if (mode == ACCESS_BAR) {
647
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
648
pcilib_memcpy(data, buf, size);
651
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
652
for (j = 0; j < (size/access); j++) {
653
pcilib_memcpy(fifo, buf + j * access, access);
657
gettimeofday(&end,NULL);
659
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
660
printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
663
pcilib_unmap_bar(handle, bar, data);
665
printf("\n\nOpen-Transfer-Close time: \n");
667
for (size = 4 ; size < max_size; size *= 8) {
668
gettimeofday(&start,NULL);
669
if (mode == ACCESS_BAR) {
670
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
671
pcilib_read(handle, bar, 0, size, buf);
674
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
675
pcilib_read_fifo(handle, bar, addr, access, size / access, buf);
678
gettimeofday(&end,NULL);
680
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
681
printf("%8zu bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
685
gettimeofday(&start,NULL);
686
if (mode == ACCESS_BAR) {
687
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
688
pcilib_write(handle, bar, 0, size, buf);
691
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
692
pcilib_write_fifo(handle, bar, addr, access, size / access, buf);
696
gettimeofday(&end,NULL);
698
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
699
printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
701
if (mode == ACCESS_BAR) {
702
gettimeofday(&start,NULL);
703
for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
704
pcilib_write(handle, bar, 0, size, buf);
705
pcilib_read(handle, bar, 0, size, check);
706
if (memcmp(buf, check, size)) ++errors;
708
gettimeofday(&end,NULL);
710
time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec);
711
printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024. * 1024.));
712
if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS);
725
#define pci2host16(endianess, value) endianess?
734
} DMACallbackContext;
736
static int DMACallback(void *arg, pcilib_dma_flags_t flags, size_t bufsize, void *buf) {
737
DMACallbackContext *ctx = (DMACallbackContext*)arg;
739
if ((ctx->pos + bufsize > ctx->size)||(!ctx->data)) {
741
ctx->data = realloc(ctx->data, ctx->size);
743
Error("Allocation of %i bytes of memory have failed", ctx->size);
748
memcpy(ctx->data + ctx->pos, buf, bufsize);
751
if (flags & PCILIB_DMA_FLAG_EOP) return 0;
757
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) {
761
size_t size = n * abs(access);
762
int block_width, blocks_per_line;
763
int numbers_per_block, numbers_per_line;
764
pcilib_dma_engine_t dmaid;
765
pcilib_dma_flags_t dma_flags = 0;
770
const pcilib_board_info_t *board_info;
772
numbers_per_block = BLOCK_SIZE / access;
774
block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH);
775
blocks_per_line = (LINE_WIDTH - 10) / (block_width + BLOCK_SEPARATOR_WIDTH);
776
if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
777
numbers_per_line = blocks_per_line * numbers_per_block;
781
if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
788
if (timeout == (size_t)-1) timeout = PCILIB_DMA_TIMEOUT;
790
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
791
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
793
if (flags&FLAG_MULTIPACKET) dma_flags |= PCILIB_DMA_FLAG_MULTIPACKET;
794
if (flags&FLAG_WAIT) dma_flags |= PCILIB_DMA_FLAG_WAIT;
797
err = pcilib_read_dma_custom(handle, dmaid, addr, size, dma_flags, timeout, buf, &bytes);
798
if (err) Error("Error (%i) is reported by DMA engine", err);
800
dma_flags |= PCILIB_DMA_FLAG_IGNORE_ERRORS;
802
size = 2048; bytes = 0;
805
buf = realloc(buf, size);
806
if (!buf) Error("Allocation of %zu bytes of memory has failed", size);
807
err = pcilib_read_dma_custom(handle, dmaid, addr, size - bytes, dma_flags, timeout, buf + bytes, &ret);
810
if ((!err)&&(flags&FLAG_MULTIPACKET)) {
811
err = PCILIB_ERROR_TOOBIG;
812
if ((flags&FLAG_WAIT)==0) timeout = 0;
814
} while (err == PCILIB_ERROR_TOOBIG);
817
if ((err)&&(err != PCILIB_ERROR_TIMEOUT)) {
818
Error("Error (%i) during DMA read", err);
821
pcilib_warning("No data is returned by DMA engine");
825
n = bytes / abs(access);
829
pcilib_read_fifo(handle, bar, addr, access, n, buf);
833
board_info = pcilib_get_board_info(handle);
834
sprintf(stmp, "/sys/bus/pci/devices/0000:%02x:%02x.%1x/config", board_info->bus, board_info->slot, board_info->func);
835
fd = open(stmp, O_RDONLY);
837
if ((!fd)||(fstat(fd, &st))) Error("Can't open %s", stmp);
839
if (st.st_size < addr)
840
Error("Access beyond the end of PCI configuration space");
842
if (st.st_size < (addr + size)) {
843
n = (st.st_size - addr) / abs(access);
844
size = n * abs(access);
845
if (!n) Error("Access beyond the end of PCI configuration space");
848
lseek(fd, addr, SEEK_SET);
849
ret = read(fd, buf, size);
850
if (ret == (size_t)-1) Error("Error reading %s", stmp);
854
n = ret / abs(access);
860
pcilib_read(handle, bar, addr, size, buf);
863
if (endianess) pcilib_swap(buf, buf, abs(access), n);
866
printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
867
fwrite(buf, abs(access), n, o);
869
for (i = 0; i < n; i++) {
871
if (i%numbers_per_line == 0) printf("\n");
873
printf("%*s", SEPARATOR_WIDTH, "");
874
if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
878
if (i%numbers_per_line == 0) printf("%8lx: ", addr + i * abs(access));
881
case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break;
882
case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break;
883
case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break;
884
case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break;
898
int ReadRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg) {
903
pcilib_register_bank_t bank_id;
904
pcilib_register_bank_addr_t bank_addr = 0;
906
pcilib_register_value_t value;
909
pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
910
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
911
format = model_info->banks[bank_id].format;
912
if (!format) format = "%lu";
914
err = pcilib_read_register_by_id(handle, regid, &value);
915
// err = pcilib_read_register(handle, bank, reg, &value);
916
if (err) printf("Error reading register %s\n", reg);
918
printf("%s = ", reg);
919
printf(format, value);
923
// Adding DMA registers
924
pcilib_get_dma_info(handle);
926
if (model_info->registers) {
928
bank_id = pcilib_find_bank(handle, bank);
929
bank_addr = model_info->banks[bank_id].addr;
932
printf("Registers:\n");
933
for (i = 0; model_info->registers[i].bits; i++) {
934
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)) {
935
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[i].bank);
936
format = model_info->banks[bank_id].format;
937
if (!format) format = "%lu";
939
err = pcilib_read_register_by_id(handle, i, &value);
940
if (err) printf(" %s = error reading value", model_info->registers[i].name);
942
printf(" %s = ", model_info->registers[i].name);
943
printf(format, value);
947
printf(format, model_info->registers[i].defvalue);
953
printf("No registers");
961
#define WRITE_REGVAL(buf, n, access, o) {\
962
uint##access##_t tbuf[n]; \
963
for (i = 0; i < n; i++) { \
964
tbuf[i] = (uint##access##_t)buf[i]; \
966
fwrite(tbuf, access/8, n, o); \
969
int ReadRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, FILE *o) {
973
pcilib_register_bank_description_t *banks = model_info->banks;
974
pcilib_register_bank_t bank_id = pcilib_find_bank(handle, bank);
976
if (bank_id == PCILIB_REGISTER_BANK_INVALID) {
977
if (bank) Error("Invalid register bank is specified (%s)", bank);
978
else Error("Register bank should be specified");
981
int access = banks[bank_id].access / 8;
982
// int size = n * abs(access);
983
int block_width, blocks_per_line;
984
int numbers_per_block, numbers_per_line;
986
numbers_per_block = BLOCK_SIZE / access;
988
block_width = numbers_per_block * ((access * 2) + SEPARATOR_WIDTH);
989
blocks_per_line = (LINE_WIDTH - 6) / (block_width + BLOCK_SEPARATOR_WIDTH);
990
if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line;
991
numbers_per_line = blocks_per_line * numbers_per_block;
994
pcilib_register_value_t buf[n];
995
err = pcilib_read_register_space(handle, bank, addr, n, buf);
996
if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1000
printf("Writting output (%zu bytes) to file (append to the end)...\n", n * abs(access));
1002
case 1: WRITE_REGVAL(buf, n, 8, o) break;
1003
case 2: WRITE_REGVAL(buf, n, 16, o) break;
1004
case 4: WRITE_REGVAL(buf, n, 32, o) break;
1005
case 8: WRITE_REGVAL(buf, n, 64, o) break;
1008
for (i = 0; i < n; i++) {
1010
if (i%numbers_per_line == 0) printf("\n");
1012
printf("%*s", SEPARATOR_WIDTH, "");
1013
if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
1017
if (i%numbers_per_line == 0) printf("%4lx: ", addr + 4 * i - addr_shift);
1018
printf("%0*lx", access * 2, (unsigned long)buf[i]);
1026
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, int verify) {
1029
int res = 0, i, err;
1030
int size = n * abs(access);
1032
pcilib_dma_engine_t dmaid;
1034
if (mode == ACCESS_CONFIG)
1035
Error("Writting to PCI configuration space is not supported");
1037
err = posix_memalign( (void**)&buf, 256, size );
1038
if (!err) err = posix_memalign( (void**)&check, 256, size );
1039
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
1041
for (i = 0; i < n; i++) {
1043
case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break;
1044
case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break;
1045
case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break;
1046
case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break;
1047
default: Error("Unexpected data size (%lu)", access);
1049
if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
1052
if (endianess) pcilib_swap(buf, buf, abs(access), n);
1056
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
1057
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (%lu) is specified", dma);
1058
err = pcilib_write_dma(handle, dmaid, addr, size, buf, &ret);
1059
if ((err)||(ret != size)) {
1060
if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout writting the data to DMA");
1061
else if (err) Error("DMA engine returned a error while writing the data");
1062
else if (!ret) Error("No data is written by DMA engine");
1063
else Error("Only %lu bytes of %lu is written by DMA engine", ret, size);
1067
pcilib_write_fifo(handle, bar, addr, access, n, buf);
1070
pcilib_write(handle, bar, addr, size, buf);
1072
pcilib_read(handle, bar, addr, size, check);
1077
if ((read_back)&&(memcmp(buf, check, size))) {
1078
printf("Write failed: the data written and read differ, the foolowing is read back:\n");
1079
if (endianess) pcilib_swap(check, check, abs(access), n);
1080
ReadData(handle, mode, 0, dma, bar, addr, n, access, endianess, (size_t)-1, NULL);
1090
int WriteRegisterRange(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, uintptr_t addr, long addr_shift, size_t n, char ** data) {
1091
pcilib_register_value_t *buf, *check;
1093
unsigned long value;
1094
int size = n * sizeof(pcilib_register_value_t);
1096
err = posix_memalign( (void**)&buf, 256, size );
1097
if (!err) err = posix_memalign( (void**)&check, 256, size );
1098
if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size);
1100
for (i = 0; i < n; i++) {
1101
res = sscanf(data[i], "%lx", &value);
1102
if ((res != 1)||(!isxnumber(data[i]))) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]);
1106
err = pcilib_write_register_space(handle, bank, addr, n, buf);
1107
if (err) Error("Error writting register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1109
err = pcilib_read_register_space(handle, bank, addr, n, check);
1110
if (err) Error("Error reading register space for bank \"%s\" at address %lx, size %lu", bank?bank:"default", addr, n);
1112
if (memcmp(buf, check, size)) {
1113
printf("Write failed: the data written and read differ, the foolowing is read back:\n");
1114
ReadRegisterRange(handle, model_info, bank, addr, addr_shift, n, NULL);
1125
int WriteRegister(pcilib_t *handle, pcilib_model_description_t *model_info, const char *bank, const char *reg, char ** data) {
1129
pcilib_register_value_t value;
1131
const char *format = NULL;
1133
pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
1134
if (regid == PCILIB_REGISTER_INVALID) Error("Can't find register (%s) from bank (%s)", reg, bank?bank:"autodetected");
1137
pcilib_register_bank_t bank_id;
1138
pcilib_register_bank_addr_t bank_addr;
1140
bank_id = pcilib_find_bank_by_addr(handle, model_info->registers[regid].bank);
1141
if (bank_id == PCILIB_REGISTER_BANK_INVALID) Error("Can't find bank of the register (%s)", reg);
1142
format = model_info->banks[bank_id].format;
1143
if (!format) format = "%lu";
1146
if (isnumber(*data)) {
1147
if (sscanf(*data, "%li", &val) != 1) {
1148
Error("Can't parse data value (%s) is not valid decimal number", *data);
1152
} else if (isxnumber(*data)) {
1153
if (sscanf(*data, "%lx", &val) != 1) {
1154
Error("Can't parse data value (%s) is not valid decimal number", *data);
1159
Error("Can't parse data value (%s) is not valid decimal number", *data);
1164
err = pcilib_write_register(handle, bank, reg, value);
1165
if (err) Error("Error writting register %s\n", reg);
1167
if ((model_info->registers[regid].mode&PCILIB_REGISTER_RW) == PCILIB_REGISTER_RW) {
1168
err = pcilib_read_register(handle, bank, reg, &value);
1169
if (err) Error("Error reading back register %s for verification\n", reg);
1172
Error("Failed to write register %s: %lu is written and %lu is read back", reg, val, value);
1174
printf("%s = ", reg);
1175
printf(format, value);
1179
printf("%s is written\n ", reg);
1187
pcilib_event_t event;
1188
pcilib_event_data_type_t data;
1190
fastwriter_t *writer;
1193
pcilib_timeout_t timeout;
1195
size_t trigger_time;
1196
size_t max_triggers;
1197
pcilib_event_flags_t flags;
1200
volatile int event_pending; /**< Used to detect that we have read previously triggered event */
1201
volatile int trigger_thread_started; /**< Indicates that trigger thread is ready and we can't procced to start event recording */
1202
volatile int started; /**< Indicates that recording is started */
1204
volatile int run_flag;
1205
volatile int writing_flag;
1207
struct timeval first_frame;
1208
struct timeval last_frame;
1211
size_t trigger_failed;
1212
size_t trigger_count;
1214
size_t incomplete_count;
1215
size_t broken_count;
1216
size_t missing_count;
1217
size_t storage_count;
1219
struct timeval start_time;
1220
struct timeval stop_time;
1223
int GrabCallback(pcilib_event_id_t event_id, pcilib_event_info_t *info, void *user) {
1228
GRABContext *ctx = (GRABContext*)user;
1229
pcilib_t *handle = ctx->handle;
1231
gettimeofday(&ctx->last_frame, NULL);
1233
if (!ctx->event_count) {
1234
memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
1237
ctx->event_pending = 0;
1241
ctx->missing_count += (info->seqnum - ctx->last_num) - 1;
1242
ctx->last_num = info->seqnum;
1244
if (info->flags&PCILIB_EVENT_INFO_FLAG_BROKEN) {
1245
ctx->incomplete_count++;
1246
return PCILIB_STREAMING_CONTINUE;
1249
switch (ctx->format) {
1250
case FORMAT_DEFAULT:
1251
data = pcilib_get_data(handle, event_id, PCILIB_EVENT_DATA, &size);
1254
data = pcilib_get_data(handle, event_id, PCILIB_EVENT_RAW_DATA, &size);
1258
ctx->broken_count++;
1259
return PCILIB_STREAMING_CONTINUE;
1262
if (ctx->format == FORMAT_HEADER) {
1264
header[0] = info->type;
1265
header[1] = ctx->data;
1268
header[4] = info->seqnum;
1269
header[5] = info->offset;
1270
memcpy(header + 6, &info->timestamp, 16);
1272
err = fastwriter_push(ctx->writer, 64, header);
1276
err = fastwriter_push(ctx->writer, size, data);
1279
fastwriter_cancel(ctx->writer);
1281
if (err != EWOULDBLOCK)
1282
Error("Storage error %i", err);
1284
ctx->storage_count++;
1285
pcilib_return_data(handle, event_id, ctx->data, data);
1286
return PCILIB_STREAMING_CONTINUE;
1289
err = pcilib_return_data(handle, event_id, ctx->data, data);
1291
ctx->missing_count++;
1292
fastwriter_cancel(ctx->writer);
1293
return PCILIB_STREAMING_CONTINUE;
1296
err = fastwriter_commit(ctx->writer);
1297
if (err) Error("Error commiting data to storage, Error: %i", err);
1299
return PCILIB_STREAMING_CONTINUE;
1302
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) {
1305
GRABContext *ctx = (GRABContext*)user;
1306
// pcilib_t *handle = ctx->handle;
1309
if ((info)&&(info->seqnum != ctx->last_num)) {
1310
gettimeofday(&ctx->last_frame, NULL);
1311
if (!ctx->event_count) {
1312
memcpy(&ctx->first_frame, &ctx->last_frame, sizeof(struct timeval));
1316
ctx->missing_count += (info->seqnum - ctx->last_num) - 1;
1317
ctx->last_num = info->seqnum;
1320
err = fastwriter_push_data(ctx->writer, size, data);
1322
if (err == EWOULDBLOCK) Error("Storage is not able to handle the data stream, buffer overrun");
1323
Error("Storage error %i", err);
1326
return PCILIB_STREAMING_CONTINUE;
1330
void *Trigger(void *user) {
1332
struct timeval start;
1334
GRABContext *ctx = (GRABContext*)user;
1335
size_t trigger_time = ctx->trigger_time;
1336
size_t max_triggers = ctx->max_triggers;
1338
ctx->trigger_thread_started = 1;
1339
ctx->event_pending = 1;
1341
while (!ctx->started) ;
1343
gettimeofday(&start, NULL);
1345
err = pcilib_trigger(ctx->handle, ctx->event, 0, NULL);
1346
if (err) ctx->trigger_failed++;
1347
if ((++ctx->trigger_count == max_triggers)&&(max_triggers)) break;
1350
pcilib_add_timeout(&start, trigger_time);
1351
if ((ctx->stop_time.tv_sec)&&(pcilib_timecmp(&start, &ctx->stop_time)>0)) break;
1352
pcilib_sleep_until_deadline(&start);
1354
while ((ctx->event_pending)&&(ctx->run_flag)) usleep(10);
1355
ctx->event_pending = 1;
1357
} while (ctx->run_flag);
1359
ctx->trigger_thread_started = 0;
1364
void GrabStats(GRABContext *ctx, struct timeval *end_time) {
1366
pcilib_timeout_t duration, fps_duration;
1368
double fps = 0, good_fps = 0;
1369
size_t total, good, pending = 0;
1371
verbose = ctx->verbose;
1375
printf("-------------------------------------------------------------------------------\n");
1378
gettimeofday(&cur, NULL);
1382
// if ((ctx->event_count + ctx->missing_count) == 0)
1385
duration = pcilib_timediff(&ctx->start_time, end_time);
1386
fps_duration = pcilib_timediff(&ctx->first_frame, &ctx->last_frame);
1388
if (ctx->trigger_count) {
1389
total = ctx->trigger_count;
1390
pending = ctx->trigger_count - ctx->event_count - ctx->missing_count - ctx->trigger_failed;
1392
total = ctx->event_count + ctx->missing_count;
1395
good = ctx->event_count - ctx->broken_count - ctx->incomplete_count - ctx->storage_count;
1397
if (ctx->event_count > 1) {
1398
fps = (ctx->event_count - 1) / (1.*fps_duration/1000000);
1402
good_fps = (good - 1) / (1.*fps_duration/1000000);
1406
PrintTime(duration);
1408
if (ctx->trigger_count) {
1409
printf(", Triggers: ");
1410
PrintNumber(ctx->trigger_count);
1413
printf(", Captured: ");
1414
PrintNumber(ctx->event_count);
1415
printf(" FPS %5.0lf", fps);
1417
if ((ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) == 0) {
1418
printf(", Stored: ");
1420
printf(" FPS %5.0lf", good_fps);
1426
if (ctx->trigger_count) {
1428
PrintNumber(ctx->trigger_count);
1429
printf(" Issued: ");
1430
PrintNumber(ctx->trigger_count - ctx->trigger_failed);
1432
PrintPercent(ctx->trigger_count - ctx->trigger_failed, ctx->trigger_count);
1433
printf("%%) Failed: ");
1434
PrintNumber(ctx->trigger_failed);
1436
PrintPercent(ctx->trigger_failed, ctx->trigger_count);
1437
printf( "%%); Pending: ");
1438
PrintNumber(pending);
1440
PrintPercent(pending, ctx->trigger_count);
1444
if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
1445
printf("Captured: ");
1450
printf(", Dropped: ");
1451
PrintNumber(ctx->storage_count);
1453
PrintNumber(ctx->incomplete_count);
1454
printf(", Empty: ");
1455
PrintNumber(ctx->broken_count);
1458
PrintNumber(ctx->missing_count);
1463
if (ctx->flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
1464
printf("Captured: ");
1465
PrintPercent(good, total);
1468
PrintPercent(good, total);
1469
printf("%% Dropped: ");
1470
PrintPercent(ctx->storage_count, total);
1472
PrintPercent(ctx->incomplete_count, total);
1473
printf("%% Empty: ");
1474
PrintPercent(ctx->broken_count, total);
1477
printf("%% Lost: ");
1478
PrintPercent(ctx->missing_count, total);
1484
void StorageStats(GRABContext *ctx) {
1486
fastwriter_stats_t st;
1488
pcilib_timeout_t duration;
1491
gettimeofday(&cur, NULL);
1492
duration = pcilib_timediff(&ctx->start_time, &cur);
1495
err = fastwriter_get_stats(ctx->writer, &st);
1499
PrintSize(st.written);
1501
PrintSize(st.commited);
1503
PrintSize(1000000.*st.written / duration);
1504
printf("/s, %6.2lf%% ", 100.*st.buffer_used / st.buffer_size);
1506
PrintSize(st.buffer_size);
1507
printf(" buffer (%6.2lf%% max)\n", 100.*st.buffer_max / st.buffer_size);
1510
void *Monitor(void *user) {
1511
struct timeval deadline;
1512
struct timeval nextinfo;
1514
GRABContext *ctx = (GRABContext*)user;
1515
int verbose = ctx->verbose;
1516
pcilib_timeout_t timeout = ctx->timeout;
1519
if (timeout == PCILIB_TIMEOUT_INFINITE) timeout = 0;
1521
// while (!ctx->started);
1524
memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
1525
pcilib_add_timeout(&deadline, timeout);
1529
pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
1532
while (ctx->run_flag) {
1534
pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
1539
if (pcilib_calc_time_to_deadline(&deadline) == 0) {
1540
memcpy(&deadline, (struct timeval*)&ctx->last_frame, sizeof(struct timeval));
1541
pcilib_add_timeout(&deadline, timeout);
1543
if (pcilib_calc_time_to_deadline(&deadline) == 0) {
1544
pcilib_stop(ctx->handle, PCILIB_EVENT_FLAG_STOP_ONLY);
1551
if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
1552
GrabStats(ctx, NULL);
1554
pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
1561
pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
1562
while (ctx->writing_flag) {
1563
if (pcilib_calc_time_to_deadline(&nextinfo) == 0) {
1564
if (verbose >= 0) StorageStats(ctx);
1565
pcilib_calc_deadline(&nextinfo, STATUS_MESSAGE_INTERVAL*1000000);
1574
int TriggerAndGrab(pcilib_t *handle, GRAB_MODE grab_mode, const char *evname, const char *data_type, size_t num, size_t run_time, size_t trigger_time, pcilib_timeout_t timeout, PARTITION partition, FORMAT format, size_t buffer_size, size_t threads, int verbose, const char *output) {
1577
// void *data = NULL;
1578
// size_t size, written;
1580
pcilib_event_t event;
1581
pcilib_event_t listen_events;
1582
pcilib_event_data_type_t data;
1584
pthread_t monitor_thread;
1585
pthread_t trigger_thread;
1586
pthread_attr_t attr;
1587
struct sched_param sched;
1589
struct timeval end_time;
1590
pcilib_event_flags_t flags;
1593
event = pcilib_find_event(handle, evname);
1594
if (event == PCILIB_EVENT_INVALID)
1595
Error("Can't find event (%s)", evname);
1597
listen_events = event;
1599
listen_events = PCILIB_EVENTS_ALL;
1600
event = PCILIB_EVENT0;
1604
data = pcilib_find_event_data_type(handle, event, data_type);
1605
if (data == PCILIB_EVENT_DATA_TYPE_INVALID)
1606
Error("Can't find data type (%s)", data_type);
1608
data = PCILIB_EVENT_DATA;
1611
memset(&ctx, 0, sizeof(GRABContext));
1613
ctx.handle = handle;
1616
ctx.run_time = run_time;
1617
ctx.timeout = timeout;
1618
ctx.format = format;
1620
if (grab_mode&GRAB_MODE_GRAB) ctx.verbose = verbose;
1621
else ctx.verbose = 0;
1623
if (grab_mode&GRAB_MODE_GRAB) {
1624
ctx.writer = fastwriter_init(output, 0);
1626
Error("Can't initialize fastwritter library");
1628
fastwriter_set_buffer_size(ctx.writer, buffer_size);
1630
err = fastwriter_open(ctx.writer, output, 0);
1632
Error("Error opening file (%s), Error: %i\n", output, err);
1634
ctx.writing_flag = 1;
1639
flags = PCILIB_EVENT_FLAGS_DEFAULT;
1641
if (data == PCILIB_EVENT_RAW_DATA) {
1642
if (format == FORMAT_RAW) {
1643
flags |= PCILIB_EVENT_FLAG_RAW_DATA_ONLY;
1646
flags |= PCILIB_EVENT_FLAG_PREPROCESS;
1651
// printf("Limits: %lu %lu %lu\n", num, run_time, timeout);
1652
pcilib_configure_autostop(handle, num, run_time);
1654
if (flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY) {
1655
pcilib_configure_rawdata_callback(handle, &raw_data, &ctx);
1658
if (flags&PCILIB_EVENT_FLAG_PREPROCESS) {
1659
pcilib_configure_preprocessing_threads(handle, threads);
1662
if (grab_mode&GRAB_MODE_TRIGGER) {
1664
if ((timeout)&&(trigger_time * 2 > timeout)) {
1665
timeout = 2 * trigger_time;
1666
ctx.timeout = timeout;
1669
// Otherwise, we will trigger next event after previous one is read
1670
if (((grab_mode&GRAB_MODE_GRAB) == 0)||(flags&PCILIB_EVENT_FLAG_RAW_DATA_ONLY)) trigger_time = PCILIB_TRIGGER_TIMEOUT;
1673
ctx.max_triggers = num;
1674
ctx.trigger_count = 0;
1675
ctx.trigger_time = trigger_time;
1677
// We don't really care if RT priority is imposible
1678
pthread_attr_init(&attr);
1679
if (!pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
1680
sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
1681
pthread_attr_setschedparam(&attr, &sched);
1684
// Start triggering thread and wait until it is schedulled
1685
if (pthread_create(&trigger_thread, &attr, Trigger, (void*)&ctx))
1686
Error("Error spawning trigger thread");
1688
while (!ctx.trigger_thread_started) usleep(10);
1691
gettimeofday(&ctx.start_time, NULL);
1693
if (grab_mode&GRAB_MODE_GRAB) {
1694
err = pcilib_start(handle, listen_events, flags);
1695
if (err) Error("Failed to start event engine, error %i", err);
1701
ctx.stop_time.tv_usec = ctx.start_time.tv_usec + run_time%1000000;
1702
if (ctx.stop_time.tv_usec > 999999) {
1703
ctx.stop_time.tv_usec -= 1000000;
1704
__sync_synchronize();
1705
ctx.stop_time.tv_sec = ctx.start_time.tv_sec + 1 + run_time / 1000000;
1707
__sync_synchronize();
1708
ctx.stop_time.tv_sec = ctx.start_time.tv_sec + run_time / 1000000;
1712
memcpy(&ctx.last_frame, &ctx.start_time, sizeof(struct timeval));
1713
if (pthread_create(&monitor_thread, NULL, Monitor, (void*)&ctx))
1714
Error("Error spawning monitoring thread");
1716
if (grab_mode&GRAB_MODE_GRAB) {
1717
err = pcilib_stream(handle, &GrabCallback, &ctx);
1718
if (err) Error("Error streaming events, error %i", err);
1723
if (grab_mode&GRAB_MODE_TRIGGER) {
1724
while (ctx.trigger_thread_started) usleep(10);
1727
if (grab_mode&GRAB_MODE_GRAB) {
1728
pcilib_stop(handle, PCILIB_EVENT_FLAGS_DEFAULT);
1731
gettimeofday(&end_time, NULL);
1733
if (grab_mode&GRAB_MODE_TRIGGER) {
1734
pthread_join(trigger_thread, NULL);
1738
if (grab_mode&GRAB_MODE_GRAB) {
1740
printf("Grabbing is finished, flushing results....\n");
1742
err = fastwriter_close(ctx.writer);
1743
if (err) Error("Storage problems, error %i", err);
1746
ctx.writing_flag = 0;
1748
pthread_join(monitor_thread, NULL);
1750
if ((grab_mode&GRAB_MODE_GRAB)&&(verbose>=0)) {
1751
GrabStats(&ctx, &end_time);
1755
fastwriter_destroy(ctx.writer);
1760
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) {
1762
pcilib_dma_engine_t dmaid;
1764
if (dma == PCILIB_DMA_ENGINE_ADDR_INVALID) {
1765
const pcilib_dma_info_t *dma_info = pcilib_get_dma_info(handle);
1767
if (start) Error("DMA engine should be specified");
1769
for (dmaid = 0; dma_info->engines[dmaid]; dmaid++) {
1770
err = pcilib_start_dma(handle, dmaid, 0);
1771
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);
1772
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
1773
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);
1779
if (dma_direction&PCILIB_DMA_FROM_DEVICE) {
1780
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, dma);
1781
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (C2S %lu) is specified", dma);
1784
err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
1785
if (err) Error("Error starting DMA engine (C2S %lu)", dma);
1787
err = pcilib_start_dma(handle, dmaid, 0);
1788
if (err) Error("Error starting DMA engine (C2S %lu)", dma);
1789
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
1790
if (err) Error("Error stopping DMA engine (C2S %lu)", dma);
1794
if (dma_direction&PCILIB_DMA_TO_DEVICE) {
1795
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, dma);
1796
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("Invalid DMA engine (S2C %lu) is specified", dma);
1799
err = pcilib_start_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
1800
if (err) Error("Error starting DMA engine (S2C %lu)", dma);
1802
err = pcilib_start_dma(handle, dmaid, 0);
1803
if (err) Error("Error starting DMA engine (S2C %lu)", dma);
1804
err = pcilib_stop_dma(handle, dmaid, PCILIB_DMA_FLAG_PERSISTENT);
1805
if (err) Error("Error stopping DMA engine (S2C %lu)", dma);
1814
pcilib_kmem_use_t use;
1828
pcilib_kmem_use_t ParseUse(const char *use) {
1832
if ((!isxnumber(use))||(sscanf(use, "%lx", &utmp) != 1)) Error("Invalid use (%s) is specified", use);
1834
if (strlen(use) < 5)
1835
return PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER,utmp);
1840
Error("Kernel memory use is not specified");
1844
size_t FindUse(size_t *n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
1845
size_t i, n = *n_uses;
1847
if (uses[n - 1].use == use) return n - 1;
1849
for (i = 1; i < (n - 1); i++) {
1850
if (uses[i].use == use) return i;
1853
if (n == MAX_USES) return 0;
1860
kmem_use_info_t *GetUse(size_t n_uses, kmem_use_info_t *uses, pcilib_kmem_use_t use) {
1862
for (i = 0; i < n_uses; i++) {
1863
if (uses[i].use == use) {
1864
if (uses[i].count) return uses + i;
1872
int ParseKMEM(pcilib_t *handle, const char *device, size_t *uses_number, kmem_use_info_t *uses) {
1874
struct dirent *entry;
1880
size_t useid, n_uses = 1; // Use 0 is for others
1882
memset(uses, 0, sizeof(uses));
1884
pos = strrchr(device, '/');
1888
snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
1890
dir = opendir(sysdir);
1891
if (!dir) Error("Can't open directory (%s)", sysdir);
1893
while ((entry = readdir(dir)) != NULL) {
1895
unsigned long use = 0;
1896
unsigned long size = 0;
1897
unsigned long refs = 0;
1898
unsigned long mode = 0;
1899
unsigned long hwref = 0;
1901
if (strncmp(entry->d_name, "kbuf", 4)) continue;
1902
if (!isnumber(entry->d_name+4)) continue;
1904
snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
1905
f = fopen(fname, "r");
1906
if (!f) Error("Can't access file (%s)", fname);
1909
fgets(info, 256, f);
1910
if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
1911
if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
1912
if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
1913
if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
1914
if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
1918
useid = FindUse(&n_uses, uses, use);
1919
uses[useid].count++;
1920
uses[useid].size += size;
1921
if (refs) uses[useid].referenced = 1;
1922
if (hwref) uses[useid].hw_lock = 1;
1923
if (mode&KMEM_MODE_REUSABLE) uses[useid].reusable = 1;
1924
if (mode&KMEM_MODE_PERSISTENT) uses[useid].persistent = 1;
1925
if (mode&KMEM_MODE_COUNT) uses[useid].open = 1;
1929
*uses_number = n_uses;
1934
int ListKMEM(pcilib_t *handle, const char *device) {
1938
size_t i, useid, n_uses;
1939
kmem_use_info_t uses[MAX_USES];
1941
err = ParseKMEM(handle, device, &n_uses, uses);
1942
if (err) Error("Failed to parse kernel memory information provided through sysfs");
1944
if ((n_uses == 1)&&(uses[0].count == 0)) {
1945
printf("No kernel memory is allocated\n");
1949
printf("Use Type Count Total Size REF Mode \n");
1950
printf("--------------------------------------------------------------------------------\n");
1951
for (useid = 0; useid < n_uses; useid++) {
1952
if (useid + 1 == n_uses) {
1953
if (!uses[0].count) continue;
1955
} else i = useid + 1;
1957
printf("%08x ", uses[i].use);
1958
if (!i) printf("All Others ");
1959
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"));
1960
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"));
1961
else if ((uses[i].use >> 16) == PCILIB_KMEM_USE_USER) printf("User %04x ", uses[i].use&0xFFFF);
1964
printf("% 6lu", uses[i].count);
1966
printf("% 10s", GetPrintSize(stmp, uses[i].size));
1968
if (uses[i].referenced&&uses[i].hw_lock) printf("HW+SW");
1969
else if (uses[i].referenced) printf(" SW");
1970
else if (uses[i].hw_lock) printf("HW ");
1973
if (uses[i].persistent) printf("Persistent");
1974
else if (uses[i].open) printf("Open ");
1975
else if (uses[i].reusable) printf("Reusable ");
1976
else printf("Closed ");
1979
printf("--------------------------------------------------------------------------------\n");
1980
printf("REF - Software/Hardware Reference, MODE - Reusable/Persistent/Open\n");
1986
int DetailKMEM(pcilib_t *handle, const char *device, const char *use, size_t block) {
1989
pcilib_kmem_handle_t *kbuf;
1990
pcilib_kmem_use_t useid = ParseUse(use);
1993
kmem_use_info_t uses[MAX_USES];
1994
kmem_use_info_t *use_info;
1996
if (block == (size_t)-1) {
1997
err = ParseKMEM(handle, device, &n_uses, uses);
1998
if (err) Error("Failed to parse kernel memory information provided through sysfs");
1999
use_info = GetUse(n_uses, uses, useid);
2000
if (!use_info) Error("No kernel buffers is allocated for the specified use (%lx)", useid);
2003
n = use_info->count;
2009
kbuf = pcilib_alloc_kernel_memory(handle, 0, n, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
2011
Error("Allocation of kernel buffer (use %lx, count %lu) is failed\n", useid, n);
2015
printf("Buffer Address Hardware Address Bus Address\n");
2016
printf("--------------------------------------------------------------------------------\n");
2017
for (; i < n; i++) {
2018
void *data = pcilib_kmem_get_block_ua(handle, kbuf, i);
2019
uintptr_t pa = pcilib_kmem_get_block_pa(handle, kbuf, i);
2020
uintptr_t ba = pcilib_kmem_get_block_ba(handle, kbuf, i);
2021
printf("%6lu %16p %16lx %16lx\n", i, data, pa, ba);
2025
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2031
int ReadKMEM(pcilib_t *handle, const char *device, pcilib_kmem_use_t useid, size_t block, size_t max_size, FILE *o) {
2035
pcilib_kmem_handle_t *kbuf;
2037
if (block == (size_t)-1) block = 0;
2039
kbuf = pcilib_alloc_kernel_memory(handle, 0, block + 1, 0, 0, useid, PCILIB_KMEM_FLAG_REUSE|PCILIB_KMEM_FLAG_TRY);
2041
Error("The specified kernel buffer is not allocated\n");
2045
err = pcilib_kmem_sync_block(handle, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, block);
2047
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2048
Error("The synchronization of kernel buffer has failed\n");
2052
data = pcilib_kmem_get_block_ua(handle, kbuf, block);
2054
size = pcilib_kmem_get_block_size(handle, kbuf, block);
2055
if ((max_size)&&(size > max_size)) size = max_size;
2057
fwrite(data, 1, size, o?o:stdout);
2059
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2060
Error("The specified block is not existing\n");
2064
pcilib_free_kernel_memory(handle, kbuf, KMEM_FLAG_REUSE);
2069
int AllocKMEM(pcilib_t *handle, const char *device, const char *use, const char *type, size_t size, size_t block_size, size_t alignment) {
2070
pcilib_kmem_type_t ktype = PCILIB_KMEM_TYPE_PAGE;
2071
pcilib_kmem_flags_t flags = KMEM_FLAG_REUSE;
2072
pcilib_kmem_handle_t *kbuf;
2073
pcilib_kmem_use_t useid = ParseUse(use);
2075
long page_size = sysconf(_SC_PAGESIZE);
2078
if (!strcmp(type, "consistent")) ktype = PCILIB_KMEM_TYPE_CONSISTENT;
2079
else if (!strcmp(type, "c2s")) ktype = PCILIB_KMEM_TYPE_DMA_C2S_PAGE;
2080
else if (!strcmp(type, "s2c")) ktype = PCILIB_KMEM_TYPE_DMA_S2C_PAGE;
2081
else Error("Invalid memory type (%s) is specified", type);
2084
if ((block_size)&&(ktype != PCILIB_KMEM_TYPE_CONSISTENT))
2085
Error("Selected memory type does not allow custom size");
2087
kbuf = pcilib_alloc_kernel_memory(handle, ktype, size, (block_size?block_size:page_size), (alignment?alignment:page_size), useid, flags|KMEM_FLAG_PERSISTENT);
2088
if (!kbuf) Error("Allocation of kernel memory has failed");
2090
pcilib_free_kernel_memory(handle, kbuf, flags);
2095
int FreeKMEM(pcilib_t *handle, const char *device, const char *use, int force) {
2099
pcilib_kmem_use_t useid;
2101
pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;
2102
if (force) flags |= PCILIB_KMEM_FLAG_FORCE; // this will ignore mmap locks as well.
2104
if (!strcasecmp(use, "dma")) {
2105
for (i = 0; i < PCILIB_MAX_DMA_ENGINES; i++) {
2106
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, i), flags);
2107
if (err) Error("Error cleaning DMA%i C2S Ring buffer", i);
2108
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_RING, 0x80|i), flags);
2109
if (err) Error("Error cleaning DMA%i S2C Ring buffer", i);
2110
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, i), flags);
2111
if (err) Error("Error cleaning DMA%i C2S Page buffers", i);
2112
err = pcilib_clean_kernel_memory(handle, PCILIB_KMEM_USE(PCILIB_KMEM_USE_DMA_PAGES, 0x80|i), flags);
2113
if (err) Error("Error cleaning DMA%i S2C Page buffers", i);
2119
useid = ParseUse(use);
2120
err = pcilib_clean_kernel_memory(handle, useid, flags);
2121
if (err) Error("Error cleaning kernel buffers for use (0x%lx)", useid);
2126
int ListDMA(pcilib_t *handle, const char *device, pcilib_model_description_t *model_info) {
2130
struct dirent *entry;
2137
pcilib_dma_engine_t dmaid;
2138
pcilib_dma_engine_status_t status;
2140
pos = strrchr(device, '/');
2144
snprintf(sysdir, 255, "/sys/class/fpga/%s", pos);
2146
dir = opendir(sysdir);
2147
if (!dir) Error("Can't open directory (%s)", sysdir);
2149
printf("DMA Engine Status Total Size Buffer Ring (1st used - 1st free)\n");
2150
printf("--------------------------------------------------------------------------------\n");
2151
while ((entry = readdir(dir)) != NULL) {
2153
unsigned long use = 0;
2154
// unsigned long size = 0;
2155
// unsigned long refs = 0;
2156
unsigned long mode = 0;
2157
// unsigned long hwref = 0;
2159
if (strncmp(entry->d_name, "kbuf", 4)) continue;
2160
if (!isnumber(entry->d_name+4)) continue;
2162
snprintf(fname, 255, "%s/%s", sysdir, entry->d_name);
2163
f = fopen(fname, "r");
2164
if (!f) Error("Can't access file (%s)", fname);
2167
fgets(info, 256, f);
2168
if (!strncmp(info, "use:", 4)) use = strtoul(info+4, NULL, 16);
2169
// if (!strncmp(info, "size:", 5)) size = strtoul(info+5, NULL, 10);
2170
// if (!strncmp(info, "refs:", 5)) refs = strtoul(info+5, NULL, 10);
2171
if (!strncmp(info, "mode:", 5)) mode = strtoul(info+5, NULL, 16);
2172
// if (!strncmp(info, "hw ref:", 7)) hwref = strtoul(info+7, NULL, 10);
2176
if ((mode&(KMEM_MODE_REUSABLE|KMEM_MODE_PERSISTENT|KMEM_MODE_COUNT)) == 0) continue; // closed
2177
if ((use >> 16) != PCILIB_KMEM_USE_DMA_RING) continue;
2180
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_TO_DEVICE, use&0x7F);
2182
dmaid = pcilib_find_dma_by_addr(handle, PCILIB_DMA_FROM_DEVICE, use&0x7F);
2185
if (dmaid == PCILIB_DMA_ENGINE_INVALID) continue;
2188
printf("DMA%lu %s ", use&0x7F, (use&0x80)?"S2C":"C2S");
2189
err = pcilib_start_dma(handle, dmaid, 0);
2191
printf("-- Wrong state, start is failed\n");
2195
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2197
printf("-- Wrong state, failed to obtain status\n");
2198
pcilib_stop_dma(handle, dmaid, 0);
2202
pcilib_stop_dma(handle, dmaid, 0);
2204
if (status.started) printf("S");
2207
if (status.ring_head == status.ring_tail) printf(" ");
2211
printf("% 10s", GetPrintSize(stmp, status.ring_size * status.buffer_size));
2214
printf("%zu - %zu (of %zu)", status.ring_tail, status.ring_head, status.ring_size);
2221
printf("--------------------------------------------------------------------------------\n");
2222
printf("S - Started, D - Data in buffers\n");
2227
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) {
2230
pcilib_dma_engine_t dmaid;
2231
pcilib_dma_engine_status_t status;
2232
pcilib_dma_buffer_status_t *buffer;
2235
dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
2236
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
2238
err = pcilib_start_dma(handle, dmaid, 0);
2239
if (err) Error("Error starting the specified DMA engine");
2241
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2242
if (err) Error("Failed to obtain status of the specified DMA engine");
2244
buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
2245
if (!buffer) Error("Failed to allocate memory for status buffer");
2247
err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
2248
if (err) Error("Failed to obtain extended status of the specified DMA engine");
2251
printf("Buffer Status Total Size \n");
2252
printf("--------------------------------------------------------------------------------\n");
2254
for (i = 0; i < status.ring_size; i++) {
2256
printf("%c%c %c%c ", buffer[i].used?'U':' ', buffer[i].error?'E':' ', buffer[i].first?'F':' ', buffer[i].last?'L':' ');
2257
printf("% 10s", GetPrintSize(stmp, buffer[i].size));
2261
printf("--------------------------------------------------------------------------------\n");
2262
printf("U - Used, E - Error, F - First block, L - Last Block\n");
2266
pcilib_stop_dma(handle, dmaid, 0);
2271
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) {
2273
pcilib_dma_engine_t dmaid;
2274
pcilib_dma_engine_status_t status;
2275
pcilib_dma_buffer_status_t *buffer;
2278
dmaid = pcilib_find_dma_by_addr(handle, dma_direction, dma);
2279
if (dmaid == PCILIB_DMA_ENGINE_INVALID) Error("The specified DMA engine is not found");
2281
err = pcilib_start_dma(handle, dmaid, 0);
2282
if (err) Error("Error starting the specified DMA engine");
2284
err = pcilib_get_dma_status(handle, dmaid, &status, 0, NULL);
2285
if (err) Error("Failed to obtain status of the specified DMA engine");
2287
buffer = (pcilib_dma_buffer_status_t*)malloc(status.ring_size*sizeof(pcilib_dma_buffer_status_t));
2288
if (!buffer) Error("Failed to allocate memory for status buffer");
2290
err = pcilib_get_dma_status(handle, dmaid, &status, status.ring_size, buffer);
2291
if (err) Error("Failed to obtain extended status of the specified DMA engine");
2293
if (block == (size_t)-1) {
2297
size = buffer[block].size;
2301
pcilib_stop_dma(handle, dmaid, 0);
2303
return ReadKMEM(handle, device, ((dma&0x7F)|((dma_direction == PCILIB_DMA_TO_DEVICE)?0x80:0x00))|(PCILIB_KMEM_USE_DMA_PAGES<<16), block, size, o);
2307
int EnableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
2310
err = pcilib_enable_irq(handle, irq_type, 0);
2312
if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
2313
Error("Error enabling IRQs");
2319
int DisableIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_type_t irq_type) {
2322
err = pcilib_disable_irq(handle, 0);
2324
if ((err != PCILIB_ERROR_NOTSUPPORTED)&&(err != PCILIB_ERROR_NOTAVAILABLE))
2325
Error("Error disabling IRQs");
2331
int AckIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source) {
2332
pcilib_clear_irq(handle, irq_source);
2336
int WaitIRQ(pcilib_t *handle, pcilib_model_description_t *model_info, pcilib_irq_hw_source_t irq_source, pcilib_timeout_t timeout) {
2340
err = pcilib_wait_irq(handle, irq_source, timeout, &count);
2342
if (err == PCILIB_ERROR_TIMEOUT) Error("Timeout waiting for IRQ");
2343
else Error("Error waiting for IRQ");
2350
int main(int argc, char **argv) {
2357
const char *num_offset;
2365
pcilib_model_t model = PCILIB_MODEL_DETECT;
2366
pcilib_model_description_t *model_info;
2367
MODE mode = MODE_INVALID;
2368
GRAB_MODE grab_mode = 0;
2369
size_t trigger_time = 0;
2370
size_t run_time = 0;
2373
FORMAT format = FORMAT_DEFAULT;
2374
PARTITION partition = PARTITION_UNKNOWN;
2376
const char *atype = NULL;
2377
const char *type = NULL;
2378
ACCESS_MODE amode = ACCESS_BAR;
2379
const char *fpga_device = DEFAULT_FPGA_DEVICE;
2380
pcilib_bar_t bar = PCILIB_BAR_DETECT;
2381
const char *addr = NULL;
2382
const char *reg = NULL;
2383
const char *bank = NULL;
2385
const char *event = NULL;
2386
const char *data_type = NULL;
2387
const char *dma_channel = NULL;
2388
const char *use = NULL;
2389
size_t block = (size_t)-1;
2390
pcilib_irq_type_t irq_type = PCILIB_IRQ_TYPE_ALL;
2391
pcilib_irq_hw_source_t irq_source = PCILIB_IRQ_SOURCE_DEFAULT;
2392
pcilib_dma_direction_t dma_direction = PCILIB_DMA_BIDIRECTIONAL;
2393
pcilib_kmem_use_t useid = 0;
2395
pcilib_dma_engine_addr_t dma = PCILIB_DMA_ENGINE_ADDR_INVALID;
2396
long addr_shift = 0;
2397
uintptr_t start = -1;
2398
size_t block_size = 0;
2400
access_t access = 4;
2404
size_t alignment = 0;
2405
const char *output = NULL;
2407
size_t iterations = BENCHMARK_ITERATIONS;
2412
int timeout_set = 0;
2413
// int run_time_set = 0;
2415
while ((c = getopt_long(argc, argv, "hqilr::w::g::d:m:t:b:a:s:e:o:", long_options, NULL)) != (unsigned char)-1) {
2419
Usage(argc, argv, NULL);
2422
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2427
if (mode == MODE_LIST) details++;
2428
else if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2433
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2438
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2440
mode = MODE_BENCHMARK;
2442
if (optarg) addr = optarg;
2443
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
2446
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2449
if (optarg) addr = optarg;
2450
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
2453
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2456
if (optarg) addr = optarg;
2457
else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++];
2460
if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_GRAB))) Usage(argc, argv, "Multiple operations are not supported");
2463
grab_mode |= GRAB_MODE_GRAB;
2466
if (optarg) stmp = optarg;
2467
else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
2470
if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
2475
if ((mode != MODE_INVALID)&&((mode != MODE_GRAB)||(grab_mode&GRAB_MODE_TRIGGER))) Usage(argc, argv, "Multiple operations are not supported");
2478
grab_mode |= GRAB_MODE_TRIGGER;
2481
if (optarg) stmp = optarg;
2482
else if ((optind < argc)&&(argv[optind][0] != '-')) stmp = argv[optind++];
2485
if ((event)&&(strcasecmp(stmp,event))) Usage(argc, argv, "Redefinition of considered event");
2490
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2492
mode = MODE_LIST_DMA;
2494
case OPT_LIST_DMA_BUFFERS:
2495
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2497
mode = MODE_LIST_DMA_BUFFERS;
2498
dma_channel = optarg;
2500
case OPT_READ_DMA_BUFFER:
2501
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2503
mode = MODE_READ_DMA_BUFFER;
2505
num_offset = strchr(optarg, ':');
2508
if (sscanf(num_offset + 1, "%zu", &block) != 1)
2509
Usage(argc, argv, "Invalid buffer is specified (%s)", num_offset + 1);
2511
*(char*)num_offset = 0;
2512
} else block = (size_t)-1;
2514
dma_channel = optarg;
2517
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2519
mode = MODE_START_DMA;
2520
if (optarg) dma_channel = optarg;
2521
else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
2524
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2526
mode = MODE_STOP_DMA;
2527
if (optarg) dma_channel = optarg;
2528
else if ((optind < argc)&&(argv[optind][0] != '-')) dma_channel = argv[optind++];
2530
case OPT_ENABLE_IRQ:
2531
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2533
mode = MODE_ENABLE_IRQ;
2534
if (optarg) num_offset = optarg;
2535
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2536
else num_offset = NULL;
2539
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
2540
Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
2545
case OPT_DISABLE_IRQ:
2546
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2548
mode = MODE_DISABLE_IRQ;
2549
if (optarg) num_offset = optarg;
2550
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2551
else num_offset = NULL;
2554
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
2555
Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
2561
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2563
mode = MODE_ACK_IRQ;
2564
if (optarg) num_offset = optarg;
2565
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2566
else num_offset = NULL;
2569
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
2570
Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
2576
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2578
mode = MODE_WAIT_IRQ;
2579
if (optarg) num_offset = optarg;
2580
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2581
else num_offset = NULL;
2584
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
2585
Usage(argc, argv, "Invalid IRQ source is specified (%s)", num_offset);
2591
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2592
mode = MODE_LIST_KMEM;
2594
if (optarg) use = optarg;
2595
else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
2599
num_offset = strchr(use, ':');
2602
if (sscanf(num_offset + 1, "%zu", &block) != 1)
2603
Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
2605
*(char*)num_offset = 0;
2610
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2611
mode = MODE_READ_KMEM;
2613
num_offset = strchr(optarg, ':');
2616
if (sscanf(num_offset + 1, "%zu", &block) != 1)
2617
Usage(argc, argv, "Invalid block number is specified (%s)", num_offset + 1);
2619
*(char*)num_offset = 0;
2623
useid = ParseUse(use);
2625
case OPT_ALLOC_KMEM:
2626
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2627
mode = MODE_ALLOC_KMEM;
2629
if (optarg) use = optarg;
2630
else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
2633
if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported");
2634
mode = MODE_FREE_KMEM;
2636
if (optarg) use = optarg;
2637
else if ((optind < argc)&&(argv[optind][0] != '-')) use = argv[optind++];
2640
fpga_device = optarg;
2643
if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI;
2644
else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA;
2645
else if (!strcasecmp(optarg, "kapture")) model = PCILIB_MODEL_KAPTURE;
2646
else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg);
2650
// if ((sscanf(optarg,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg);
2654
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &alignment) != 1)) {
2655
Usage(argc, argv, "Invalid alignment is specified (%s)", optarg);
2659
if (!strncasecmp(optarg, "fifo", 4)) {
2661
num_offset = optarg + 4;
2662
amode = ACCESS_FIFO;
2663
} else if (!strncasecmp(optarg, "dma", 3)) {
2665
num_offset = optarg + 3;
2667
} else if (!strncasecmp(optarg, "bar", 3)) {
2669
num_offset = optarg + 3;
2671
} else if (!strncasecmp(optarg, "config", 6)) {
2673
num_offset = optarg + 6;
2674
amode = ACCESS_CONFIG;
2675
} else if (!strncasecmp(optarg, "plain", 5)) {
2677
num_offset = optarg + 5;
2680
num_offset = optarg;
2684
if ((!isnumber(num_offset))||(sscanf(num_offset, "%li", &itmp) != 1))
2685
Usage(argc, argv, "Invalid access type (%s) is specified", optarg);
2688
case 8: access = 1; break;
2689
case 16: access = 2; break;
2690
case 32: access = 4; break;
2691
case 64: access = 8; break;
2692
default: Usage(argc, argv, "Invalid data width (%s) is specified", num_offset);
2697
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &size) != 1)) {
2698
if (strcasecmp(optarg, "unlimited"))
2699
Usage(argc, argv, "Invalid size is specified (%s)", optarg);
2701
size = 0;//(size_t)-1;
2706
case OPT_BLOCK_SIZE:
2707
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &block_size) != 1)) {
2708
Usage(argc, argv, "Invalid size is specified (%s)", optarg);
2712
if ((*optarg == 'b')||(*optarg == 'B')) {
2713
if (ntohs(1) == 1) endianess = 0;
2715
} else if ((*optarg == 'l')||(*optarg == 'L')) {
2716
if (ntohs(1) == 1) endianess = 1;
2718
} else Usage(argc, argv, "Invalid endianess is specified (%s)", optarg);
2722
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &timeout) != 1)) {
2723
if (strcasecmp(optarg, "unlimited"))
2724
Usage(argc, argv, "Invalid timeout is specified (%s)", optarg);
2726
timeout = PCILIB_TIMEOUT_INFINITE;
2733
case OPT_ITERATIONS:
2734
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &iterations) != 1))
2735
Usage(argc, argv, "Invalid number of iterations is specified (%s)", optarg);
2747
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &run_time) != 1)) {
2748
if (strcasecmp(optarg, "unlimited"))
2749
Usage(argc, argv, "Invalid run-time is specified (%s)", optarg);
2753
// run_time_set = 1;
2755
case OPT_TRIGGER_TIME:
2756
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &trigger_time) != 1))
2757
Usage(argc, argv, "Invalid trigger-time is specified (%s)", optarg);
2759
case OPT_TRIGGER_RATE:
2760
if ((!isnumber(optarg))||(sscanf(optarg, "%zu", &ztmp) != 1))
2761
Usage(argc, argv, "Invalid trigger-rate is specified (%s)", optarg);
2763
trigger_time = (1000000 / ztmp) + ((1000000 % ztmp)?1:0);
2766
if (optarg) num_offset = optarg;
2767
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2768
else num_offset = NULL;
2771
if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &buffer) != 1))
2772
Usage(argc, argv, "Invalid buffer size is specified (%s)", num_offset);
2773
buffer *= 1024 * 1024;
2775
buffer = get_free_memory();
2776
if (buffer < 256) Error("Not enough free memory (%lz MB) for buffering", buffer / 1024 / 1024);
2778
buffer -= 128 + buffer/16;
2782
if (optarg) num_offset = optarg;
2783
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2784
else num_offset = NULL;
2787
if ((!isnumber(num_offset))||(sscanf(num_offset, "%zu", &threads) != 1))
2788
Usage(argc, argv, "Invalid threads number is specified (%s)", num_offset);
2794
if (!strcasecmp(optarg, "raw")) format = FORMAT_RAW;
2795
else if (!strcasecmp(optarg, "add_header")) format = FORMAT_HEADER;
2796
// else if (!strcasecmp(optarg, "ringfs")) format = FORMAT_RINGFS;
2797
else if (strcasecmp(optarg, "default")) Error("Invalid format (%s) is specified", optarg);
2804
if (optarg) num_offset = optarg;
2805
else if ((optind < argc)&&(argv[optind][0] != '-')) num_offset = argv[optind++];
2806
else num_offset = NULL;
2809
if ((!isnumber(num_offset))||(sscanf(num_offset, "%i", &verbose) != 1))
2810
Usage(argc, argv, "Invalid verbosity level is specified (%s)", num_offset);
2821
case OPT_MULTIPACKET:
2822
flags |= FLAG_MULTIPACKET;
2828
Usage(argc, argv, "Unknown option (%s) with argument (%s)", optarg?argv[optind-2]:argv[optind-1], optarg?optarg:"(null)");
2832
if (mode == MODE_INVALID) {
2833
if (argc > 1) Usage(argc, argv, "Operation is not specified");
2834
else Usage(argc, argv, NULL);
2837
pcilib_set_error_handler(&Error, quiete?Silence:NULL);
2839
handle = pcilib_open(fpga_device, model);
2840
if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device);
2842
model = pcilib_get_model(handle);
2843
model_info = pcilib_get_model_description(handle);
2847
if (((argc - optind) == 1)&&(*argv[optind] == '*')) {
2848
int vallen = strlen(argv[optind]);
2850
data = (char**)malloc(size * (vallen + sizeof(char*)));
2851
if (!data) Error("Error allocating memory for data array");
2853
for (i = 0; i < size; i++) {
2854
data[i] = ((char*)data) + size * sizeof(char*) + i * vallen;
2855
strcpy(data[i], argv[optind] + 1);
2858
data = (char**)malloc(size * (9 + sizeof(char*)));
2859
if (!data) Error("Error allocating memory for data array");
2861
for (i = 0; i < size; i++) {
2862
data[i] = ((char*)data) + size * sizeof(char*) + i * 9;
2863
sprintf(data[i], "%x", i);
2866
} else if ((argc - optind) == size) data = argv + optind;
2867
else Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size);
2870
if (model == PCILIB_MODEL_PCI) {
2871
if ((amode != ACCESS_DMA)&&(amode != ACCESS_CONFIG))
2872
Usage(argc, argv, "The address is not specified");
2876
case MODE_START_DMA:
2878
case MODE_LIST_DMA_BUFFERS:
2879
case MODE_READ_DMA_BUFFER:
2880
if ((dma_channel)&&(*dma_channel)) {
2881
itmp = strlen(dma_channel) - 1;
2882
if (dma_channel[itmp] == 'r') dma_direction = PCILIB_DMA_FROM_DEVICE;
2883
else if (dma_channel[itmp] == 'w') dma_direction = PCILIB_DMA_TO_DEVICE;
2885
if (dma_direction != PCILIB_DMA_BIDIRECTIONAL) itmp--;
2887
if (strncmp(dma_channel, "dma", 3)) num_offset = dma_channel;
2889
num_offset = dma_channel + 3;
2894
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);
2897
if (!isnumber_n(num_offset, itmp))
2898
Usage(argc, argv, "Invalid DMA channel (%s) is specified", dma_channel);
2900
dma = atoi(num_offset);
2904
if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied");
2909
if ((!strncmp(addr, "dma", 3))&&((addr[3]==0)||isnumber(addr+3))) {
2910
if ((atype)&&(amode != ACCESS_DMA)) Usage(argc, argv, "Conflicting access modes, the DMA read is requested, but access type is (%s)", type);
2912
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);
2914
if (addr[3] == 0) Usage(argc, argv, "The DMA channel is not specified");
2916
dma = atoi(addr + 3);
2919
} else if ((!strncmp(addr, "bar", 3))&&((addr[3]==0)||isnumber(addr+3))) {
2920
if ((atype)&&(amode != ACCESS_BAR)) Usage(argc, argv, "Conflicting access modes, the plain PCI read is requested, but access type is (%s)", type);
2921
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);
2922
bar = atoi(addr + 3);
2925
} else if (!strcmp(addr, "config")) {
2926
if ((atype)&&(amode != ACCESS_CONFIG)) Usage(argc, argv, "Conflicting access modes, the read of PCI configurataion space is requested, but access type is (%s)", type);
2927
amode = ACCESS_CONFIG;
2929
} else if ((isxnumber(addr))&&(sscanf(addr, "%lx", &start) == 1)) {
2930
// check if the address in the register range
2931
pcilib_register_range_t *ranges = model_info->ranges;
2934
for (i = 0; ranges[i].start != ranges[i].end; i++)
2935
if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break;
2937
// register access in plain mode
2938
if (ranges[i].start != ranges[i].end) {
2939
pcilib_register_bank_t regbank = pcilib_find_bank_by_addr(handle, ranges[i].bank);
2940
if (regbank == PCILIB_REGISTER_BANK_INVALID) Error("Configuration error: register bank specified in the address range is not found");
2942
bank = model_info->banks[regbank].name;
2943
start += ranges[i].addr_shift;
2944
addr_shift = ranges[i].addr_shift;
2949
if (pcilib_find_register(handle, bank, addr) == PCILIB_REGISTER_INVALID) {
2950
Usage(argc, argv, "Invalid address (%s) is specified", addr);
2958
if (mode == MODE_GRAB) {
2961
if (!get_file_fs(output, 127, fsname)) {
2962
if (!strcmp(fsname, "ext4")) partition = PARTITION_EXT4;
2963
else if (!strcmp(fsname, "raw")) partition = PARTITION_RAW;
2966
output = "/dev/null";
2967
partition = PARTITION_NULL;
2971
if (run_time) timeout = PCILIB_TIMEOUT_INFINITE;
2972
else timeout = PCILIB_EVENT_TIMEOUT;
2976
if (run_time) size = 0;
2980
if (mode != MODE_GRAB) {
2981
if (size == (size_t)-1)
2982
Usage(argc, argv, "Unlimited size is not supported in selected operation mode");
2986
if ((bank)&&(amode == ACCESS_DMA)) {
2987
if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0))
2988
Usage(argc, argv, "Invalid DMA channel (%s) is specified", bank);
2992
case MODE_BENCHMARK:
2995
if ((!isnumber(bank))||(sscanf(bank,"%li", &itmp) != 1)||(itmp < 0)||(itmp >= PCILIB_MAX_BANKS))
2996
Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
3000
if (pcilib_find_bank(handle, bank) == PCILIB_REGISTER_BANK_INVALID)
3001
Usage(argc, argv, "Invalid data bank (%s) is specified", bank);
3005
signal(SIGINT, signal_exit_handler);
3007
if ((mode != MODE_GRAB)&&(output)) {
3008
ofile = fopen(output, "a+");
3010
Error("Failed to open file \"%s\"", output);
3016
Info(handle, model_info);
3019
List(handle, model_info, bank, details);
3021
case MODE_BENCHMARK:
3022
Benchmark(handle, amode, dma, bar, start, size_set?size:0, access, iterations);
3025
if (amode == ACCESS_DMA) {
3026
ReadData(handle, amode, flags, dma, bar, start, size_set?size:0, access, endianess, timeout_set?timeout:(size_t)-1, ofile);
3027
} else if (amode == ACCESS_CONFIG) {
3028
ReadData(handle, amode, flags, dma, bar, addr?start:0, (addr||size_set)?size:(256/abs(access)), access, endianess, (size_t)-1, ofile);
3030
ReadData(handle, amode, flags, dma, bar, start, size, access, endianess, (size_t)-1, ofile);
3032
Error("Address to read is not specified");
3035
case MODE_READ_REGISTER:
3036
if ((reg)||(!addr)) ReadRegister(handle, model_info, bank, reg);
3037
else ReadRegisterRange(handle, model_info, bank, start, addr_shift, size, ofile);
3040
WriteData(handle, amode, dma, bar, start, size, access, endianess, data, verify);
3042
case MODE_WRITE_REGISTER:
3043
if (reg) WriteRegister(handle, model_info, bank, reg, data);
3044
else WriteRegisterRange(handle, model_info, bank, start, addr_shift, size, data);
3047
pcilib_reset(handle);
3050
TriggerAndGrab(handle, grab_mode, event, data_type, size, run_time, trigger_time, timeout, partition, format, buffer, threads, verbose, output);
3053
ListDMA(handle, fpga_device, model_info);
3055
case MODE_LIST_DMA_BUFFERS:
3056
ListBuffers(handle, fpga_device, model_info, dma, dma_direction);
3058
case MODE_READ_DMA_BUFFER:
3059
ReadBuffer(handle, fpga_device, model_info, dma, dma_direction, block, ofile);
3061
case MODE_START_DMA:
3062
StartStopDMA(handle, model_info, dma, dma_direction, 1);
3065
StartStopDMA(handle, model_info, dma, dma_direction, 0);
3067
case MODE_ENABLE_IRQ:
3068
EnableIRQ(handle, model_info, irq_type);
3070
case MODE_DISABLE_IRQ:
3071
DisableIRQ(handle, model_info, irq_type);
3074
AckIRQ(handle, model_info, irq_source);
3077
WaitIRQ(handle, model_info, irq_source, timeout);
3079
case MODE_LIST_KMEM:
3080
if (use) DetailKMEM(handle, fpga_device, use, block);
3081
else ListKMEM(handle, fpga_device);
3083
case MODE_READ_KMEM:
3084
ReadKMEM(handle, fpga_device, useid, block, 0, ofile);
3086
case MODE_ALLOC_KMEM:
3087
AllocKMEM(handle, fpga_device, use, type, size, block_size, alignment);
3089
case MODE_FREE_KMEM:
3090
FreeKMEM(handle, fpga_device, use, force);
3096
if (ofile) fclose(ofile);
3098
pcilib_close(handle);
3100
if (data != argv + optind) free(data);