1 /*
2 *
3 * Top Level Hardware Operating Functions for Ztex Multi-FPGA board.
4 *
5 * This software is Copyright (c) 2016,2018-2019 Denis Burykin
6 * [denis_burykin yahoo com], [denis-burykin2014 yandex ru]
7 * and it is hereby released to the general public under the following terms:
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted.
10 *
11 */
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <libusb-1.0/libusb.h>
16
17 #include "../config.h"
18 #include "../misc.h"
19
20 #include "ztex.h"
21 #include "inouttraffic.h"
22 #include "ztex_scan.h"
23 #include "pkt_comm/pkt_comm.h"
24 #include "pkt_comm/init_data.h"
25 #include "device.h"
26
27
28 #define CONFIG_MAX_LEN 256
29
30 // boards are in "no comparison" mode
31 int device_nocompar_mode = 0;
32
hex_digit2bin(char digit)33 static int hex_digit2bin(char digit)
34 {
35 if (digit >= '0' && digit <= '9')
36 return digit - '0';
37 if (digit >= 'a' && digit <= 'f')
38 return digit - 'a' + 10;
39 if (digit >= 'A' && digit <= 'F')
40 return digit - 'A' + 10;
41 return -1;
42 }
43
44 // Convert hexadecimal ascii string e.g. \x0c\x00 into binary string
45 // TODO: consider moving into src/config.c
hex_string2bin(const char * src,int * len)46 static char *hex_string2bin(const char *src, int *len)
47 {
48 static char dst[CONFIG_MAX_LEN];
49
50 if (!src) {
51 fprintf(stderr, "NULL pointer in device.c:hex_string2bin()\n");
52 error();
53 }
54 *len = 0;
55
56 int i;
57 for (i = 0; ; i = i + 4) {
58 if (!src[i])
59 break;
60 if (src[i] != '\\' || !src[i+1] || src[i+1] != 'x'
61 || !src[i+2] || !src[i+3]) {
62 fprintf(stderr, "Invalid hex string in john.conf: %s\n", src);
63 error();
64 }
65
66 int upper = hex_digit2bin(src[i+2]);
67 int lower = hex_digit2bin(src[i+3]);
68 if (upper == -1 || lower == -1) {
69 fprintf(stderr, "Invalid hex digit in john.conf: %s\n", src);
70 error();
71 }
72
73 dst[(*len)++] = upper << 4 | lower;
74 if (*len == CONFIG_MAX_LEN) {
75 fprintf(stderr, "Hex string in john.conf of exceeds %d hex "
76 "chars: %s\n", CONFIG_MAX_LEN, src);
77 error();
78 }
79 }
80
81 if (!*len) {
82 fprintf(stderr, "Empty hex string in john.conf\n");
83 error();
84 }
85 return dst;
86 }
87
88
device_init_fpgas(struct device * device,struct device_bitstream * bitstream)89 static int device_init_fpgas(struct device *device,
90 struct device_bitstream *bitstream)
91 {
92 // Read config for given bitstream, device
93 char *CFG_SECTION = "ZTEX:";
94 char conf_name_board_freq[256], conf_name_freq[256];
95 int default_freq[NUM_PROGCLK_MAX], board_freq[NUM_PROGCLK_MAX],
96 fpga_freq[NUM_PROGCLK_MAX];
97
98 // Frequency
99 if (bitstream->num_progclk) {
100 // Default frequency (for every device for given bitstream)
101 cfg_get_int_array(CFG_SECTION, bitstream->label, "Frequency",
102 default_freq, NUM_PROGCLK_MAX);
103
104 // Frequency specific to given board
105 sprintf(conf_name_board_freq, "Frequency_%s",
106 device->ztex_device->snString);
107 cfg_get_int_array(CFG_SECTION, bitstream->label,
108 conf_name_board_freq, board_freq, NUM_PROGCLK_MAX);
109
110 if (board_freq[0] == -1 && default_freq[0] != -1)
111 memcpy(board_freq, default_freq, sizeof(board_freq));
112 }
113
114 // TODO: rewrite
115 // (if more subtypes of a configuration packet appear).
116 //
117 // Runtime configuration packet.
118 // Only subtype 1 is currently supported.
119 // Length is specific to bitstream.
120 // If configuration packet is of incorrect length then
121 // the FPGA would raise an error (app_status=0x08)
122 char conf_name_board_config1[256], conf_name_config1[256];
123 char default_config1[CONFIG_MAX_LEN], board_config1[CONFIG_MAX_LEN];
124 int len_default, len_board, len;
125
126 const char *ptr;
127 ptr = cfg_get_param(CFG_SECTION, bitstream->label, "Config1");
128 if (ptr) {
129 char *hex_str = hex_string2bin(ptr, &len_default);
130 strncpy(default_config1, hex_str, len_default);
131 } else
132 len_default = 0;
133
134 sprintf(conf_name_board_config1, "Config1_%s",
135 device->ztex_device->snString);
136 ptr = cfg_get_param(CFG_SECTION, bitstream->label,
137 conf_name_board_config1);
138 if (ptr) {
139 char *hex_str = hex_string2bin(ptr, &len_board);
140 strncpy(board_config1, hex_str, len_board);
141 } else {
142 len_board = len_default;
143 strncpy(board_config1, default_config1, len_default);
144 }
145
146 int fpga_num;
147 for (fpga_num = 0; fpga_num < device->num_of_fpgas; fpga_num++) {
148 struct fpga *fpga = &device->fpga[fpga_num];
149
150 int result = fpga_select(fpga);
151 if (result < 0) {
152 device_invalidate(device);
153 return result;
154 }
155
156 // Attn: on GSR, clocks remain at programmed frequency
157 // Set FPGAs to given frequency before GSR
158 if (bitstream->num_progclk) {
159
160 // Check for frequency for given fpga in the config
161 sprintf(conf_name_freq, "%s_%d", conf_name_board_freq, fpga_num + 1);
162 cfg_get_int_array(CFG_SECTION, bitstream->label, conf_name_freq,
163 fpga_freq, NUM_PROGCLK_MAX);
164
165 int clk_num;
166 for (clk_num = 0; clk_num < bitstream->num_progclk; clk_num++) {
167 int freq =
168 fpga_freq[clk_num] != -1 ? fpga_freq[clk_num] :
169 board_freq[clk_num] != -1 ? board_freq[clk_num] :
170 bitstream->freq[clk_num];
171
172 int result = fpga_progclk(fpga, clk_num, freq);
173 if (result < 0)
174 return result;
175 }
176
177 for ( ; clk_num < NUM_PROGCLK_MAX; clk_num++)
178 fpga->freq[clk_num] = 0;
179 }
180
181
182 // Reset FPGA application with Global Set Reset (GSR)
183 // Affected is FPGA previously selected with fpga_select()
184 result = fpga_reset(device->handle);
185 if (result < 0) {
186 fprintf(stderr, "SN %s #%d: device_fpga_reset: %d (%s)\n",
187 device->ztex_device->snString,
188 fpga_num + 1, result, libusb_error_name(result));
189 device_invalidate(device);
190 return result;
191 }
192
193
194 fpga->comm = pkt_comm_new(&bitstream->pkt_comm_params);
195
196 // Initialization packet (must be the 1st packet after GSR)
197 if (bitstream->init_len > 1 || bitstream->init_len < 0) {
198 fprintf(stderr, "Bad or unsupported bitstream->"
199 "init_len=%d\n", bitstream->init_len);
200 error();
201 }
202 else if (bitstream->init_len == 1) {
203 struct pkt *pkt_init
204 = pkt_init_data_1b_new(bitstream->init_data[0]);
205 pkt_queue_push(fpga->comm->output_queue, pkt_init);
206 }
207
208 // Runtime configuration packet
209 struct pkt *pkt_config1 = NULL;
210
211 sprintf(conf_name_config1, "%s_%d", conf_name_board_config1,
212 fpga_num + 1);
213 ptr = cfg_get_param(CFG_SECTION, bitstream->label,
214 conf_name_config1);
215 if (ptr) {
216 char *hex_str = hex_string2bin(ptr, &len);
217 pkt_config1 = pkt_config_new(1, hex_str, len);
218 } else if (len_board)
219 pkt_config1 = pkt_config_new(1, board_config1, len_board);
220
221 if (pkt_config1)
222 pkt_queue_push(fpga->comm->output_queue, pkt_config1);
223
224
225 } // for fpga
226 return 0;
227 }
228
229
device_list_init_fpgas(struct device_list * device_list,struct device_bitstream * bitstream)230 static int device_list_init_fpgas(struct device_list *device_list,
231 struct device_bitstream *bitstream)
232 {
233 int ok_count = 0;
234 struct device *device;
235 for (device = device_list->device; device; device = device->next) {
236 if (!device_valid(device))
237 continue;
238
239 int result = device_init_fpgas(device, bitstream);
240 if (result < 0) {
241 fprintf(stderr, "SN %s error %d initializing FPGAs.\n",
242 device->ztex_device->snString, result);
243 device_invalidate(device);
244 }
245 else
246 ok_count ++;
247 }
248 return ok_count;
249 }
250
251
252 ///////////////////////////////////////////////////////////////////
253 //
254 // Hardware Handling
255 //
256 // device_list_init() takes list of devices with uploaded firmware
257 // 1. upload bitstreams
258 // 2. initialize FPGAs
259 //
260 ///////////////////////////////////////////////////////////////////
261
device_list_init(struct device_list * device_list,struct device_bitstream * bitstream)262 void device_list_init(struct device_list *device_list,
263 struct device_bitstream *bitstream)
264 {
265 // bitstream->type is hardcoded into bitstream (vcr.v/BITSTREAM_TYPE)
266 if (!bitstream || !bitstream->type || !bitstream->path) {
267 fprintf(stderr, "device_list_init(): invalid bitstream information\n");
268 error();
269 }
270
271 int result = device_list_check_bitstreams(device_list, bitstream->type, bitstream->path);
272 if (result < 0) {
273 // fatal error
274 error();
275 }
276 if (result > 0) {
277 //usleep(3000);
278 result = device_list_check_bitstreams(device_list, bitstream->type, NULL);
279 if (result < 0) {
280 error();
281 }
282 }
283
284 device_list_init_fpgas(device_list, bitstream);
285
286 if (device_nocompar_mode)
287 device_list_set_app_mode(device_list, 0x40);
288 }
289
290
291 ///////////////////////////////////////////////////////////////////
292 //
293 // Top Level Hardware Initialization Function.
294 //
295 // device_timely_scan() takes the list of devices currently in use
296 //
297 // 1. Performs ztex_timely_scan()
298 // 2. Initialize devices
299 // 3. Returns list of newly found and initialized devices.
300 //
301 ///////////////////////////////////////////////////////////////////
302
device_timely_scan(struct device_list * device_list,struct device_bitstream * bitstream)303 struct device_list *device_timely_scan(struct device_list *device_list, struct device_bitstream *bitstream)
304 {
305 struct ztex_dev_list *ztex_dev_list_1 = ztex_dev_list_new();
306 ztex_timely_scan(ztex_dev_list_1, device_list->ztex_dev_list);
307
308 struct device_list *device_list_1 = device_list_new(ztex_dev_list_1);
309 device_list_init(device_list_1, bitstream);
310
311 return device_list_1;
312 }
313
device_init_scan(struct device_bitstream * bitstream)314 struct device_list *device_init_scan(struct device_bitstream *bitstream)
315 {
316 struct ztex_dev_list *ztex_dev_list = ztex_dev_list_new();
317 ztex_init_scan(ztex_dev_list);
318
319 struct device_list *device_list = device_list_new(ztex_dev_list);
320 device_list_init(device_list, bitstream);
321
322 return device_list;
323 }
324
325
device_list_print(struct device_list * device_list)326 void device_list_print(struct device_list *device_list)
327 {
328 struct device *dev;
329 for (dev = device_list->device; dev; dev = dev->next) {
330 if (!device_valid(dev))
331 continue;
332
333 int num, j;
334 int has_progclk = 0;
335
336 printf("ZTEX %s bus:%d dev:%d",
337 dev->ztex_device->snString, dev->ztex_device->busnum,
338 dev->ztex_device->devnum);
339 for (num = 0; num < dev->num_of_fpgas; num++) {
340 for (j = 0; j < NUM_PROGCLK_MAX; j++) {
341 if (!dev->fpga[num].freq[j])
342 break;
343 if (!has_progclk) {
344 printf(" Frequency:");
345 has_progclk = 1;
346 }
347 if (j > 0)
348 printf(",");
349 printf("%d", dev->fpga[num].freq[j]);
350 }
351 if (has_progclk)
352 printf(" ");
353 }
354 printf("\n");
355 }
356 }
357
358
359 ///////////////////////////////////////////////////////////////////
360 //
361 // Perform read/write operations on the device
362 // using high-speed packet communication interface (pkt_comm).
363 //
364 // Return values:
365 // <0 - error (expecting caller to invalidate / reset the device)
366 // 0 - no data was actually send or received (because of either host or remote reasons)
367 // >0 - success, some data was sent or received
368 //
369 ///////////////////////////////////////////////////////////////////
370
device_pkt_rw(struct device * device)371 int device_pkt_rw(struct device *device)
372 {
373 int data_transferred = 0;
374 int result;
375 int num;
376 for (num = 0; num < device->num_of_fpgas; num++) {
377 struct fpga *fpga = &device->fpga[num];
378
379 // Get input buffer
380 unsigned char *input_buf = pkt_comm_input_get_buf(fpga->comm);
381 if (fpga->comm->error)
382 return -1;
383 // Input buffer is full - skip r/w operation
384 if (!input_buf) {
385 if (DEBUG) printf("fpga_pkt_rw(): input buffer is full\n");
386 continue;
387 }
388
389 // fpga_select(), fpga_get_io_state(), fpga_setup_output() in 1 USB request
390 result = fpga_select_setup_io(fpga);
391 if (result < 0) {
392 fprintf(stderr, "SN %s FPGA #%d fpga_select_setup_io() error: %d\n",
393 device->ztex_device->snString, num + 1, result);
394 return result;
395 }
396
397 // TODO: human readable error description
398 if (fpga->wr.io_state.pkt_comm_status) {
399 fprintf(stderr, "SN %s FPGA #%d error: pkt_comm_status=0x%02x,"
400 " debug=0x%04x\n", device->ztex_device->snString, num + 1,
401 fpga->wr.io_state.pkt_comm_status,
402 fpga->wr.io_state.debug3 << 8 | fpga->wr.io_state.debug2);
403 return -1;
404 }
405
406 if (fpga->wr.io_state.app_status) {
407 fprintf(stderr, "SN %s FPGA #%d error: app_status=0x%02x,"
408 " debug=0x%04x\n", device->ztex_device->snString, num + 1,
409 fpga->wr.io_state.app_status,
410 fpga->wr.io_state.debug3 << 8 | fpga->wr.io_state.debug2);
411 return -1;
412 }
413
414 if (fpga->wr.io_state.io_state & ~IO_STATE_INPUT_PROG_FULL) {
415 fprintf(stderr, "SN %s FPGA #%d error: io_state=0x%02x\n",
416 device->ztex_device->snString, num + 1,
417 fpga->wr.io_state.io_state);
418 return -1;
419 }
420
421 int input_full = fpga->wr.io_state.io_state & IO_STATE_INPUT_PROG_FULL;
422 if (input_full) {
423
424 // FPGA input is full - no write
425 if (DEBUG) printf("#%d write: Input full\n", num + 1);
426
427 } else {
428
429 // Get output buffer
430 int output_data_len = 0;
431 unsigned char *output_data = pkt_comm_get_output_data(fpga->comm,
432 &output_data_len);
433
434 if (!output_data) {
435
436 // No data for output - no write
437 if (DEBUG) printf("fpga_pkt_write(): no data for output\n");
438
439 } else {
440
441 if (DEBUG >= 2) {
442 int i;
443 for (i=0; i < output_data_len; i++) {
444 if (i && !(i%32)) printf("\n");
445 printf("%02x ", output_data[i]);
446 }
447 printf("\n");
448 }
449
450 // Performing write
451 int transferred = 0;
452 result = libusb_bulk_transfer(fpga->device->handle, 0x06,
453 output_data, output_data_len, &transferred, USB_RW_TIMEOUT);
454 if (DEBUG) printf("#%d write: result=%d tx=%d/%d\n",
455 fpga->num + 1, result, transferred, output_data_len);
456 if (result < 0) {
457 return result;
458 }
459 if (transferred != output_data_len) {
460 return ERR_WR_PARTIAL;
461 }
462
463 // Let pkt_comm register data transmit (clear buffers etc)
464 pkt_comm_output_completed(fpga->comm, output_data_len, 0);
465 data_transferred = 1;
466 }
467 } // output issues end
468
469
470 // No data to read from FPGA - continue with next one
471 int read_limit = fpga->rd.read_limit;
472 if (!read_limit)
473 continue;
474
475 // Performing read
476 int current_read_limit = read_limit;
477 for ( ; ; ) {
478 int transferred = 0;
479 result = libusb_bulk_transfer(fpga->device->handle, 0x82, input_buf,
480 current_read_limit, &transferred, USB_RW_TIMEOUT);
481 if (DEBUG) printf("#%d read: result=%d, rx=%d/%d\n",
482 fpga->num + 1, result, transferred, current_read_limit);
483 if (result < 0) {
484 return result;
485 }
486 else if (transferred == 0) {
487 return ERR_RD_ZEROREAD;
488 }
489 else if (transferred != current_read_limit) { // partial read
490 if (DEBUG) printf("#%d PARTIAL READ: %d of %d\n",
491 fpga->num + 1, transferred, current_read_limit);
492 current_read_limit -= transferred;
493 fpga->rd.partial_read_count++;
494 continue;
495 }
496 else
497 break;
498 } // for (;;)
499
500 // Read completed.
501 if (DEBUG >= 2) {
502 int i;
503 for (i=0; i < read_limit; i++) {
504 if (i && !(i%32)) printf("\n");
505 printf("%02x ", input_buf[i]);
506 }
507 printf("\n");
508 }
509
510 // Let pkt_comm handle data (process packets, place into input queue)
511 result = pkt_comm_input_completed(fpga->comm, read_limit, 0);
512 if (result < 0)
513 return result;
514 data_transferred = 1;
515 }
516
517 return data_transferred;
518 }
519
520
device_strerror(int error_code)521 char *device_strerror(int error_code)
522 {
523 static char buf[256];
524 sprintf(buf, "%d unknown error", error_code);
525 return buf;
526 }
527
528
529 /////////////////////////////////////////////////////////////////////////////////////
530
531 //unsigned long long wr_byte_count = 0, rd_byte_count = 0;
532
533 // - The function is obsolete
534 // - There's a glitch: when input buffer / queue is full,
535 // it still attempts to read resulting in FPGA error OUTPUT_LIMIT_NOT_DONE
536 // (FPGA started output operation and did not complete).
537 // Suggest usage of device_pkt_rw(struct device *device)
538 //
device_fpgas_pkt_rw(struct device * device)539 int device_fpgas_pkt_rw(struct device *device)
540 {
541 int result;
542 int num;
543 for (num = 0; num < device->num_of_fpgas; num++) {
544
545 struct fpga *fpga = &device->fpga[num];
546 //if (!fpga->valid) // currently if r/w error on some FPGA, the entire device invalidated
547 // continue;
548
549 //fpga_select(fpga); // unlike select_fpga() from Ztex SDK, it waits for i/o timeout
550 result = fpga_select_setup_io(fpga); // combines fpga_select(), fpga_get_io_state() and fpga_setup_output() in 1 USB request
551 if (result < 0) {
552 fprintf(stderr, "SN %s FPGA #%d fpga_select_setup_io() error: %d\n",
553 device->ztex_device->snString, num + 1, result);
554 return result;
555 }
556
557 if (fpga->wr.io_state.pkt_comm_status) {
558 fprintf(stderr, "SN %s FPGA #%d error: pkt_comm_status=0x%02x\n",
559 device->ztex_device->snString, num + 1, fpga->wr.io_state.pkt_comm_status);
560 return -1;
561 }
562
563 if (fpga->wr.io_state.app_status) {
564 fprintf(stderr, "SN %s FPGA #%d error: app_status=0x%02x\n",
565 device->ztex_device->snString, num + 1, fpga->wr.io_state.app_status);
566 return -1;
567 }
568
569 result = fpga_pkt_write(fpga);
570 if (result < 0) {
571 fprintf(stderr, "SN %s FPGA #%d write error: %d (%s)\n",
572 device->ztex_device->snString, num + 1, result, libusb_error_name(result));
573 return result; // on such a result, device will be invalidated
574 }
575 //if (result > 0) {
576 //wr_byte_count += result;
577 //if ( wr_byte_count/1024/1024 != (wr_byte_count - result)/1024/1024 ) {
578 //printf(".");
579 //fflush(stdout);
580 // }
581 //}
582
583 // read
584 result = fpga_pkt_read(fpga);
585 if (result < 0) {
586 fprintf(stderr, "SN %s FPGA #%d read error: %d (%s)\n",
587 device->ztex_device->snString, num + 1, result, libusb_error_name(result));
588 return result; // on such a result, device will be invalidated
589 }
590 //if (result > 0)
591 // rd_byte_count += result;
592
593 } // for ( ;num_of_fpgas ;)
594 return 1;
595 }
596
597
598