/alps/pcitool

To get this branch, use:
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
}