/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
236 by Suren A. Chilingaryan
Big redign of model structures
1
#define _POSIX_C_SOURCE 200809L
2
#define _BSD_SOURCE
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
3
#include <stdio.h>
4
#include <stdlib.h>
5
#include <string.h>
6
#include <unistd.h>
7
#include <stdarg.h>
8
#include <time.h>
9
#include <sched.h>
10
#include <sys/time.h>
11
#include <sys/types.h>
12
#include <arpa/inet.h>
13
#include <sched.h>
14
#include <errno.h>
15
16
#include "pcilib.h"
17
#include "irq.h"
18
#include "kmem.h"
236 by Suren A. Chilingaryan
Big redign of model structures
19
#include "pci.h"
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
20
21
//#include <sys/ipc.h>
22
//#include <sys/shm.h>
23
24
25
#define DEVICE "/dev/fpga0"
26
27
#define BAR PCILIB_BAR0
28
#define USE_RING PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
29
#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 2)
30
//#define STATIC_REGION 0x80000000 //  to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters
31
32
#define BUFFERS         128
33
#define ITERATIONS      1000
34
#define DESC_THRESHOLD  BUFFERS/8   // Lorenzo: after how many desc the FPGA must update the "written descriptor counter" in PC mem
35
                                    // if set to 0, the update only happens when INT is received
36
37
#define HUGE_PAGE       1           // number of pages per huge page
236 by Suren A. Chilingaryan
Big redign of model structures
38
#define TLP_SIZE        64          // TLP SIZE = 64 for 256B payload, 32 for 128B payload
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
39
#define PAGE_SIZE       4096        // other values are not supported in the kernel
40
236 by Suren A. Chilingaryan
Big redign of model structures
41
#define USE_64                    // Lorenzo: use 64bit addressing
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
42
43
//#define DUAL_CORE                 // Lorenzo: DUAL Core
44
45
//#define SHARED_MEMORY               // Lorenzo: Test for fast GUI
46
47
#define CHECK_READY                 // Lorenzo: Check if PCI-Express is ready by reading 0x0
48
#define CHECK_RESULTS               // Lorenzo: Check if data received is ok (only for counter!)
49
//#define PRINT_RESULTS               // Lorenzo: Save the received data in "data.out"
50
//#define EXIT_ON_EMPTY               // Lorenzo: Exit if an "empty_detected" signal is received
51
52
//#define HEB                       // Lorenzo: Testing HEB
53
//#define SWITCH_GENERATOR          // Lorenzo: Testing HEB -> Turn data gen on/off
54
55
//#define TEST_DDR                    // Lorenzo: Testing DDR
56
57
#define TIMEOUT         1000000
58
59
60
61
/* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help,
62
   otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite 
63
   much extra time */
64
65
//#define USE_IRQ
66
//#define REALTIME
67
//#define ADD_DELAYS
68
69
70
#define FPGA_CLOCK 250 // Lorenzo: in MHz !
71
72
73
74
//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); }
75
//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; }
76
#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; }
77
#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); }
78
79
// **************************************************************************************
80
// Progress BAR
81
// Process has done x out of n rounds,
82
// and we want a bar of width w and resolution r.
83
   static inline void loadBar(int x, int n, int r, int w)
84
   {
85
    // Only update r times.
86
    if ( x % (n/r +1) != 0 ) return;
87
88
    // Calculuate the ratio of complete-to-incomplete.
89
    float ratio = x/(float)n;
90
    int   c     = ratio * w;
91
92
    // Show the percentage complete.
93
    printf("%3d%% [", (int)(ratio*100) );
94
95
    // Show the load bar.
96
        for (x=0; x<c; x++)
97
           printf("=");
98
99
       for (x=c; x<w; x++)
100
           printf(" ");
101
102
    // ANSI Control codes to go back to the
103
    // previous line and clear it.
104
       printf("]\n\033[F\033[J");
105
   }
106
// **************************************************************************************
107
108
109
   static void fail(const char *msg, ...) {
110
    va_list va;
111
112
    va_start(va, msg);
113
    vprintf(msg, va);
114
    va_end(va);
115
    printf("\n");
116
117
    exit(-1);
118
}
119
120
void hpsleep(size_t ns) {
121
    struct timespec wait, tv;
122
123
    clock_gettime(CLOCK_REALTIME, &wait);
124
125
    wait.tv_nsec += ns;
126
    if (wait.tv_nsec > 999999999) {
127
        wait.tv_sec += 1;
128
        wait.tv_nsec = 1000000000 - wait.tv_nsec;
129
    }
130
131
    do {
132
        clock_gettime(CLOCK_REALTIME, &tv);
133
    } while ((wait.tv_sec > tv.tv_sec)||((wait.tv_sec == tv.tv_sec)&&(wait.tv_nsec > tv.tv_nsec)));
134
}
135
136
137
// **************************************************************************************
138
int main() {
139
140
141
142
    int err;
236 by Suren A. Chilingaryan
Big redign of model structures
143
    int i, j, k;
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
144
    int mem_diff;
145
    pcilib_t *pci;
146
    pcilib_kmem_handle_t *kdesc;
147
    pcilib_kmem_handle_t *kbuf;
148
    struct timeval start, end;
236 by Suren A. Chilingaryan
Big redign of model structures
149
    size_t run_time;
150
    size_t size_mb;
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
151
    void* volatile bar;
152
    uintptr_t bus_addr[BUFFERS];
153
    uintptr_t kdesc_bus;
154
    volatile uint32_t *desc;
155
    typedef volatile uint32_t *Tbuf;
156
    Tbuf ptr[BUFFERS];
236 by Suren A. Chilingaryan
Big redign of model structures
157
158
#ifdef SWITCH_GENERATOR
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
159
    int switch_generator = 0;
236 by Suren A. Chilingaryan
Big redign of model structures
160
#endif /* SWITCH_GENERATOR */
161
 
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
162
    float performance, perf_counter; 
163
    pcilib_bar_t bar_tmp = BAR; 
164
    uintptr_t offset = 0;
165
166
    unsigned int temp;
236 by Suren A. Chilingaryan
Big redign of model structures
167
    unsigned iterations_completed, buffers_filled;
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
168
169
170
//    int shmid;
171
    
172
173
    printf("\n\n**** **** **** KIT-DMA TEST **** **** ****\n\n");
174
175
    size_mb = ITERATIONS * BUFFERS * HUGE_PAGE * 4 / 1024;
176
    printf("Total size of memory buffer: \t %.3lf GBytes\n", (float)size_mb/1024 );
236 by Suren A. Chilingaryan
Big redign of model structures
177
    printf("Using %u Buffers with %u iterations\n\n", BUFFERS, ITERATIONS );
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
178
179
#ifdef ADD_DELAYS
180
    long rpt = 0, rpt2 = 0;
181
    size_t best_time;
182
    best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024);
183
#endif /* ADD_DELAYS */
184
185
186
    pcilib_kmem_flags_t flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE/*|PCILIB_KMEM_FLAG_REUSE*/; // Lorenzo: if REUSE = 1, the re-allocation fails!
187
    pcilib_kmem_flags_t free_flags = PCILIB_KMEM_FLAG_HARDWARE/*|PCILIB_KMEM_FLAG_EXCLUSIVE|PCILIB_KMEM_FLAG_REUSE*/;
188
    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;
189
190
    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
191
    if (!pci) fail("pcilib_open");
192
193
    bar = pcilib_map_bar(pci, BAR);
194
    if (!bar) {
195
        pcilib_close(pci);
196
        fail("map bar");
197
    }
198
199
    pcilib_detect_address(pci, &bar_tmp, &offset, 1);
200
201
    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0);
202
    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT);
203
204
    pcilib_clean_kernel_memory(pci, USE, clean_flags);
205
    pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
206
207
    kdesc = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_CONSISTENT, 1, 128, 4096, USE_RING, flags);
208
    kdesc_bus = pcilib_kmem_get_block_ba(pci, kdesc, 0);
209
    desc = (uint32_t*)pcilib_kmem_get_block_ua(pci, kdesc, 0);
210
    memset((void*)desc, 0, 5*sizeof(uint32_t));
211
212
#ifdef REALTIME
213
    pid_t pid;
214
    struct sched_param sched = {0};
215
216
    pid = getpid();
217
    sched.sched_priority = sched_get_priority_min(SCHED_FIFO);
218
    if (sched_setscheduler(pid, SCHED_FIFO, &sched))
219
        printf("Warning: not able to get real-time priority\n");
220
#endif /* REALTIME */
221
222
    // ******************************************************************
223
    // ****      MEM: check 4k boundary                             ***** 
224
    // ******************************************************************
225
226
    do  {
227
        printf("* Allocating KMem, ");
228
#ifdef STATIC_REGION
229
        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, flags);
230
#else
231
        kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, flags);
232
#endif
233
234
        if (!kbuf) {
235
            printf("KMem allocation failed\n");
236
            exit(0);
237
        }
238
239
        // Pointers for Virtualized Mem
240
        for (j = 0; j < BUFFERS; j++) {
241
            ptr[j] = (volatile uint32_t*)pcilib_kmem_get_block_ua(pci, kbuf, j);
236 by Suren A. Chilingaryan
Big redign of model structures
242
            memset((void*)ptr[j], 0, HUGE_PAGE * PAGE_SIZE);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
243
        }
244
245
        err = 0;
246
247
        // Check if HW addresses satisfy 4k boundary condition, if not -> free (!!) and reallocate memory
248
        printf("4k boundary test: ");
249
        for (j = 0; j < BUFFERS; j++) {
250
            temp = (((unsigned int)pcilib_kmem_get_block_ba(pci, kbuf, j)) % 4096);
251
            //printf("%u", temp);
252
            if (temp  != 0) {
253
                err = 1;
254
            }
255
        }
256
        if (err == 1) {
257
            pcilib_clean_kernel_memory(pci, USE, clean_flags);
258
            pcilib_clean_kernel_memory(pci, USE_RING, clean_flags);
259
            pcilib_free_kernel_memory(pci, kbuf,  free_flags);
260
            printf("failed \xE2\x9C\x98\n");
261
        }
262
        else printf("passed \xE2\x9C\x93\n");
263
264
    } while (err == 1);
265
266
267
    // ******************************************************************
268
    // ****      Allocate RAM buffer Memory                         ***** 
269
    // ******************************************************************
270
    
271
    FILE * Output;
272
    FILE * error_log;
273
274
#ifdef CHECK_RESULTS
275
    uint32_t *temp_data[ITERATIONS][BUFFERS];
276
277
    for (j=0; j < ITERATIONS; j++) {
278
        for (i=0; i < BUFFERS; i++) {
279
            temp_data[j][i] = (uint32_t *)malloc(HUGE_PAGE*PAGE_SIZE);
280
            if (temp_data[j][i] == 0) {
281
                printf("******* Error: could not allocate memory! ********\n");
282
                exit(0);
283
            }
284
            memset((void*)(temp_data[j][i]), 0, HUGE_PAGE * PAGE_SIZE);
285
        }
286
    }
287
#endif
288
289
#ifdef SHARED_MEMORY
290
    // give your shared memory an id, anything will do
291
    key_t key = 123456;
292
    char *shared_memory;
293
294
    // Setup shared memory, 11 is the size
295
/*    if ((shmid = shmget(key, HUGE_PAGE*PAGE_SIZE, IPC_CREAT | 0666)) < 0)
296
    {
297
      printf("Error getting shared memory id");
298
      exit(1);
299
    }
300
301
    // Attached shared memory
302
    if ((shared_memory = shmat(shmid, NULL, 0)) == (char *) -1)
303
    {
304
      printf("Error attaching shared memory id");
305
      exit(1);
306
    }
307
    printf("* Shared memory created... Id:\t %d\n", key);
308
    //////////////// SHARED MEMORY TEST */
309
#endif
310
311
    Output = fopen ("data.out", "w");
312
    fclose(Output);
313
314
    error_log = fopen ("error_log.txt", "w");
315
    fclose(error_log);
316
   
317
   // *************************************
318
    Output = fopen("data.txt", "w");
319
    fclose(Output);
320
321
    // ******************************************************************
322
    // ****      PCIe TEST                                          ***** 
323
    // ******************************************************************
324
325
    // Reset DMA
326
    printf("* DMA: Reset...\n");
327
    WR(0x00, 0x1);
328
    usleep(100000);
329
    WR(0x00, 0x0);
330
    usleep(100000);
331
 
332
#ifdef CHECK_READY       
333
    printf("* PCIe: Testing...");
334
    RD(0x0, err);
236 by Suren A. Chilingaryan
Big redign of model structures
335
    if (err == 335746816 || err == 335681280) {
336
        printf("\xE2\x9C\x93 \n");
337
    } else {
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
338
        printf("\xE2\x9C\x98\n PCIe not ready!\n");
339
        exit(0);
340
    }
341
#endif
342
    
343
344
    // ******************************************************************
345
    // ****      DMA CONFIGURATION                                  ***** 
346
    // ******************************************************************
347
348
    
349
    printf("* DMA: Start Data Generator...\n");
350
    WR(0x04, 0x10) // Start data generator
351
352
    printf("* DMA: Send Data Fill Pattern 55aa55aa\n");
353
    WR(0x14, 0xbeef);
354
355
    printf("* DMA: Send Data Amount\n");
356
#ifdef DUAL_CORE
357
    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))/2);
358
#else  
359
    WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE))));
360
#endif   
361
362
    printf("* DMA: Running mode: ");
363
#ifdef USE_64   
364
    if (TLP_SIZE == 64) 
365
    {
366
        WR(0x0C, 0x80040);
367
        printf ("64bit - 256B Payload\n");
368
    }
369
    else if (TLP_SIZE == 32) 
370
    {
371
        WR(0x0C, 0x80020);
372
        printf ("64bit - 128B Payload\n");
373
    }
374
#else  
375
    if (TLP_SIZE == 64) 
376
    {
377
        WR(0x0C, 0x0040);
378
        printf ("32bit - 256B Payload\n");
379
    }
380
    else if (TLP_SIZE == 32) 
381
    {
382
        WR(0x0C, 0x0020);
383
        printf ("32bit - 128B Payload\n");
384
    }
385
#endif
386
    
387
    printf("* DMA: Reset Desc Memory...\n");
388
    WR(0x5C, 0x00); // RST Desc Memory
389
390
    //printf("Writing SW Read Descriptor\n");
391
    WR(0x58, BUFFERS-1);
392
    //WR(0x58, 0x01);
393
394
    //printf("Writing the Descriptor Threshold\n");
395
    WR(0x60, DESC_THRESHOLD);
396
397
    //printf("Writing HW write Descriptor Address: %lx\n", kdesc_bus);
398
    WR(0x54, kdesc_bus);
399
    usleep(100000);
400
401
    printf("* DMA: Writing Descriptors\n");
402
    for (j = 0; j < BUFFERS; j++ ) {
403
        bus_addr[j] = pcilib_kmem_get_block_ba(pci, kbuf, j);
404
        // LEAVE THIS DELAY???!?!?!?!
405
        usleep(1000);
236 by Suren A. Chilingaryan
Big redign of model structures
406
        printf("Writing descriptor num. %d: \t %08lx \r", j, bus_addr[j]);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
407
        WR(0x50, bus_addr[j]);
408
    }
409
410
    // ******************************************************************
411
    // ****      HEB CONFIGURATION                                  ***** 
412
    // ******************************************************************
413
#ifdef HEB
414
415
416
    printf("* DDR REGISTERS: AXI_BUF_SIZE \n");
417
    WR(0x9130, 0x1000);
418
419
    usleep(100000);
420
421
    printf("* HEB: Control \n");
422
    WR(0x9040, 0x00000001);
423
424
    usleep(100000);
425
426
    printf("* HEB: Control \n");
427
    WR(0x9040, 0x00000004);
428
429
    usleep(100000);
430
431
    printf("* HEB: Control \n");
432
    WR(0x9040, 0x00000000);
433
434
    usleep(100000);
435
436
    printf("* HEB: Writing Total Orbit Num\n");
437
    WR(0x9020, 0x2000);
438
439
    printf("* HEB: Orbit Skip Num h9028\n");
440
    WR(0x9028, 0x4);
441
442
    //printf("* HEB: LVDS_DELAY h9080\n");
443
    //WR(0x9080, 0x10101010);
444
445
    //printf("* HEB: Delay ADCs \n");
446
    //WR(0x9088, 0x001);
447
    //WR(0x9090, 0x001);
448
    //WR(0x9094, 0x001);
449
    //WR(0x9098, 0x001);
450
451
    //printf("* HEB: Delay TH \n");
452
    //WR(0x90a0, 0x005);
453
454
    //printf("* HEB: Delay_FPGA_reg \n");
455
    //WR(0x90a8, 0x006);
456
457
    //printf("* HEB: Control \n");
458
    //WR(0x9040, 0x40000000);
459
460
    //usleep(1000000);
461
 
462
    printf("* HEB: Control \n");
463
    WR(0x9040, 0x40000bf0);
464
465
    usleep(100000);
466
467
    printf("* HEB: Control \n");
468
    WR(0x9040, 0x400003f0);
469
470
    usleep(100000);
471
472
    printf("* HEB: Control \n");
473
    WR(0x9040, 0x480007F0);
474
475
    usleep(100000);
476
477
    printf("* HEB: Control \n");
478
    WR(0x9040, 0x48000FF0);
479
480
481
#endif
482
483
    // ******************************************************************
484
    // ****      TEST DDR conf                                      ***** 
485
    // ******************************************************************
486
#ifdef TEST_DDR
487
488
489
    printf("* DDR: AXI_BUF_SIZE_ADDR: 4k\n");
490
    WR(0x9010, 0x04000);
491
492
    printf("* DDR: Control \n");
493
    WR(0x9000, 0x000000F);
494
495
    usleep(100000);
496
    WR(0x9000, 0x00000008);
497
    usleep(100000);
498
    WR(0x9000, 0x08000008);
499
500
    usleep(50000);
501
502
    printf("* DDR: Control \n");
503
    WR(0x9000, 0x08000208);
504
505
506
#endif
507
508
    // ******************************************************************
509
    // ****     START DMA                                           *****
510
    // ******************************************************************
511
512
    //printf ("\n ---- Press ENTER to start DMA ---- \n");
513
    //getchar();
514
515
    printf("* DMA: Start \n");
516
    WR(0x04, 0x1f);
517
    gettimeofday(&start, NULL);
518
519
    // ******************************************************************
520
    // ****     Handshaking DMA                                     *****
521
    // ******************************************************************
522
523
    uint32_t curptr = 0, hwptr;
524
    uint32_t curbuf = 0;
525
    int empty = 0;
526
    i = 0;
527
528
529
    while (i < ITERATIONS) {
530
        j = 0;
531
        // printf("\ndesc0: %lx", htonl(desc[0])); 
532
        // printf("\ndesc1: %lx", htonl(desc[1])); 
533
        // printf("\ndesc2: %lx", htonl(desc[2])); 
534
        // printf("\ndesc3: %lx", htonl(desc[3])); 
535
        // printf("\ndesc4: %lx", htonl(desc[4]));
536
        // printf("\ndesc5: %lx", htonl(desc[5]));
537
        //printf("Iteration: %li of %li \r", i+1, ITERATIONS); 
538
        //loadBar(i+1, ITERATIONS, ITERATIONS, 30);
539
        // printf("\nhwptr: %zu", hwptr);  
540
        // printf("\ncurptr: %zu", curptr); 
541
542
        do {
543
#ifdef USE_64   
236 by Suren A. Chilingaryan
Big redign of model structures
544
                hwptr = desc[3];
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
545
#else // 32-bit
236 by Suren A. Chilingaryan
Big redign of model structures
546
                hwptr = desc[4];
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
547
#endif
548
        j++;    
549
        //printf("\rcurptr: %lx \t \t hwptr: %lx", curptr, hwptr);
550
        } while (hwptr == curptr);
551
552
        do {    
553
            pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, curbuf);
554
#ifdef CHECK_RESULTS   
236 by Suren A. Chilingaryan
Big redign of model structures
555
            memcpy(temp_data[i][curbuf], (void*)ptr[curbuf], 4096);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
556
#endif
557
#ifdef SHARED_MEMORY
236 by Suren A. Chilingaryan
Big redign of model structures
558
            memcpy(shared_memory, (void*)ptr[curbuf], 4096); 
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
559
#endif            
560
            //printf("\ncurbuf: %08x", curbuf); 
561
            //printf("\nbus_addr[curbuf]\n: %08x",bus_addr[curbuf]);
562
            // for (k = 0; k < 63; k++){
563
            // if (k%16 == 0) printf("\n# %d # :", k);
564
            // printf(" %08x", ptr[curbuf][k]);
565
            // }
566
            //pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_TODEVICE, curbuf);
567
            curbuf++;
568
            if (curbuf == BUFFERS) {
569
                i++;
570
                curbuf = 0;
571
#ifdef SWITCH_GENERATOR                 
572
                if (switch_generator == 1) {
573
                    switch_generator = 0;
574
                    WR(0x9040, 0x100007F0);
575
                } else {
576
                    WR(0x9040, 0x180007F0);
577
                    switch_generator = 1;
578
                }
579
#endif
580
                if (i >= ITERATIONS) break;
581
                //if (i >= (ITERATIONS - 4) ) WR(0x04, 0x0f); 
582
            }
583
        } while (bus_addr[curbuf] != hwptr);
584
585
#ifdef EXIT_ON_EMPTY
586
#ifdef USE_64                 
587
        if (desc[1] != 0) 
588
#else // 32bit  
589
        if (desc[2] != 0)  
590
#endif                                 
591
        {
592
            if (bus_addr[curbuf] == hwptr) {
593
                empty = 1;
594
                break;
595
            }
596
        }
597
#endif  
598
599
        WR(0x58, curbuf + 1); 
600
        //printf("WR %d\n", curbuf + 1); 
601
        //printf("%u (%lu)\n", curbuf, j);
602
        curptr = hwptr;
603
604
    }
605
    
606
607
608
    // ******************************************************************
609
    // **** Read performance and stop DMA                         *******
610
    // ******************************************************************
611
612
    gettimeofday(&end, NULL);
613
    WR(0x04, 0x00);
614
    WR(0x01, 0x00);
615
    RD(0x28, perf_counter);
616
617
618
619
    iterations_completed   = i;
620
    buffers_filled      = curbuf;
236 by Suren A. Chilingaryan
Big redign of model structures
621
    if (empty) printf("* DMA: Empty FIFO! Last iteration: %u of %u\n", i+1, ITERATIONS);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
622
    printf ("* DMA: Stop\n\n");
623
624
#ifdef CHECK_RESULTS
625
    printf ("First value:\t %08x\n", temp_data[0][0][0]);
626
    printf ("Last value:\t %08x\n\n", temp_data[ITERATIONS-1][BUFFERS-1][(PAGE_SIZE/4)-4]);
627
#endif
628
    
629
    // ******************************************************************
630
    // **** Performance                                           *******
631
    // ******************************************************************
632
    printf("Iterations done: %d\n", iterations_completed);
633
    printf("Buffers filled on last iteration: %d\n", buffers_filled);
634
635
636
    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
637
    size_mb = (long long int) (( BUFFERS * (iterations_completed)  + buffers_filled) * HUGE_PAGE * 4 / 1024);
236 by Suren A. Chilingaryan
Big redign of model structures
638
    printf("Performance: transfered %zu Mbytes in %zu us using %u buffers\n", (size_mb), run_time, BUFFERS);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
639
    //printf("Buffers: \t %d \n", BUFFERS);
640
    //printf("Buf_Size: \t %d \n", PAGE_SIZE);
641
    //printf("Perf_counter: \t %f \n", perf_counter);
642
    performance = ((size_mb * FPGA_CLOCK * 1000000)/(perf_counter*256));
643
    printf("DMA perf counter:\t%d\n", (int)perf_counter); 
644
    printf("DMA side:\t\t%.3lf MB/s\n", performance);  
645
    printf("PC side:\t\t%.3lf MB/s\n\n", 1000000. * size_mb / run_time );
646
647
    // ******************************************************************
648
    // **** Read Data                                             *******
649
    // ******************************************************************
650
651
236 by Suren A. Chilingaryan
Big redign of model structures
652
#ifdef PRINT_RESULTS
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
653
    printf("Writing Data to HDD... \n");
654
    for (i=0; i < iterations_completed; i++) {
655
        for (j=0; j < BUFFERS; j++)
656
        {
657
            Output = fopen("data.out", "a");
658
            fwrite(temp_data[i][j], 4096, 1, Output);
659
            fclose(Output);
660
        }   
661
        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
662
    }
663
    // Save last partially filled iteration
664
    for (j=0; j < buffers_filled; j++)
665
    {
666
        Output = fopen("data.out", "a");
667
        fwrite(temp_data[iterations_completed][j], 4096, 1, Output);
668
        fclose(Output);
669
    }   
670
    printf("Data saved in data.out. \n");
236 by Suren A. Chilingaryan
Big redign of model structures
671
#endif
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
672
236 by Suren A. Chilingaryan
Big redign of model structures
673
#ifdef CHECK_RESULTS
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
674
    err = 0;
675
    error_log = fopen ("error_log.txt", "a");
676
    printf("\nChecking data ...\n");
677
    for (i=0; i < iterations_completed; i++) {
678
        for (j = 0; j < BUFFERS; j++) {
679
            for (k = 0; k < 1024 ; k++) 
680
            {
681
                mem_diff = ((uint32_t)temp_data[i][j][k] - (uint32_t)temp_data[i][j][k+1]);
682
                //if ((mem_diff == 1) || (mem_diff == (-7)) || (k == 1023) ) 
683
                if ((mem_diff == -1) || (k == 1023) ) 
684
                    {;}
685
                else {
236 by Suren A. Chilingaryan
Big redign of model structures
686
                    fprintf(error_log, "Error in: \t IT %u \t BUF : %u \t OFFSET: %u \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j][k], temp_data[i][j][k+1], mem_diff);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
687
                    err++;
688
                }
689
            }
690
            if (j != BUFFERS-1) {
691
            // Check first and Last
692
                mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
693
                if (mem_diff == (1)) 
694
                    {;}
695
                else {
236 by Suren A. Chilingaryan
Big redign of model structures
696
                    fprintf(error_log, "Error_2 in: \t IT %u \t BUF : %u \t OFFSET: %u \t | %08x --> %08x - DIFF: %d \n", i, j, k, temp_data[i][j+1][0], temp_data[i][j][1023], mem_diff);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
697
                    err++;
698
                }
699
            }
700
701
        }
702
        loadBar(i+1, ITERATIONS, ITERATIONS, 30);
703
    }
704
    for (j = 0; j < buffers_filled; j++) {
236 by Suren A. Chilingaryan
Big redign of model structures
705
        for (k = 0; k < 1024 ; k++) {
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
706
            mem_diff = ((uint32_t)temp_data[iterations_completed][j][k] - (uint32_t)temp_data[iterations_completed][j][k+1]);
236 by Suren A. Chilingaryan
Big redign of model structures
707
            if ((mem_diff == -1) || (k == 1023) ) {
708
        	;
709
    	    } else {
710
                fprintf(error_log, "Error in: \t IT %u \t BUF : %u \t OFFSET: %u \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j][k], temp_data[iterations_completed][j][k+1], mem_diff);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
711
                err++;
712
            }
713
        }
236 by Suren A. Chilingaryan
Big redign of model structures
714
        if (j < (buffers_filled-1)) {
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
715
        // Check first and Last
716
            mem_diff = (uint32_t)(temp_data[i][j+1][0] - temp_data[i][j][1023]);
236 by Suren A. Chilingaryan
Big redign of model structures
717
            if (mem_diff == (1)) {
718
                ;
719
            } else {
720
                fprintf(error_log, "Error_2 in: \t IT %u \t BUF : %u \t OFFSET: %u \t | %08x --> %08x - DIFF: %d \n", iterations_completed, j, k, temp_data[iterations_completed][j+1][0], temp_data[iterations_completed][j][1023], mem_diff);
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
721
                err++;
722
            }
723
        }
724
    }
725
    if (err != 0) printf("\rChecking data: \xE2\x9C\x98 %d errors found  \n See \"error_log.txt\" for details \n\n", err);
726
    else printf("\rChecking data: \xE2\x9C\x93 no errors found  \n\n");
727
    fclose(error_log);
236 by Suren A. Chilingaryan
Big redign of model structures
728
#endif
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
729
730
731
    // *********** Free Memory
732
#ifdef CHECK_RESULTS
733
    for (i=0; i < ITERATIONS; i++) {
734
        for (j=0; j < BUFFERS; j++)
735
        {
736
            free(temp_data[i][j]);
737
        }
738
    }
236 by Suren A. Chilingaryan
Big redign of model structures
739
#endif /* CHECK_RESULTS */
227 by Suren A. Chilingaryan
Initial implementation of IPEDMA, dummy driver for KAPTURE, start of API changes
740
741
    pcilib_free_kernel_memory(pci, kbuf,  free_flags);
742
    pcilib_free_kernel_memory(pci, kdesc,  free_flags);
743
    pcilib_disable_irq(pci, 0);
744
    pcilib_unmap_bar(pci, BAR, bar);
745
    pcilib_close(pci);
746
747
//    shmdt(shmid);
748
//    shmctl(shmid, IPC_RMID, NULL);
749
750
}