/alps/pcitool

To get this branch, use:
bzr branch http://suren.me/webbzr/alps/pcitool
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#define _BSD_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/time.h>

#include "pcilib.h"
#include "irq.h"
#include "kmem.h"

#define DEVICE "/dev/fpga0"
#define BAR PCILIB_BAR0
#define USE PCILIB_KMEM_USE(PCILIB_KMEM_USE_USER, 1)
#define BUFFERS 16
#define ITERATIONS 16384
#define PAGE_SIZE 4096
#define TIMEOUT 100000

//#define WR(addr, value) { val = value; pcilib_write(pci, BAR, addr, sizeof(val), &val); }
//#define RD(addr, value) { pcilib_read(pci, BAR, addr, sizeof(val), &val); value = val; }
#define WR(addr, value) { *(uint32_t*)(bar + addr) = value; }
#define RD(addr, value) { value = *(uint32_t*)(bar + addr); }

static void fail(const char *msg, ...) {
    va_list va;
    
    va_start(va, msg);
    vprintf(msg, va);
    va_end(va);
    printf("\n");

    exit(-1);
}

int main() {
    int err;
    int i, j;
    pcilib_t *pci;
    pcilib_kmem_handle_t *kbuf;
    uint32_t status;
    struct timeval start, end;
    size_t size, run_time;
    void* volatile bar;

    pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE;


    pci = pcilib_open(DEVICE, PCILIB_MODEL_DETECT);
    if (!pci) fail("pcilib_open");

    bar = pcilib_map_bar(pci, BAR);
    if (!bar) {
	pcilib_close(pci);
	fail("map bar");
    }

    pcilib_enable_irq(pci, PCILIB_IRQ_TYPE_ALL, 0);
    pcilib_clear_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT);

    pcilib_clean_kernel_memory(pci, USE, clean_flags);


    kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, PAGE_SIZE, 4096, USE, 0);

    
    WR(0x00, 1)
    usleep(1000);
    WR(0x00, 0)
    WR(0x04, 0)
    
    WR(0x0C, 0x20)
    WR(0x10, 0x20)
    WR(0x14, 0x13131313)


    gettimeofday(&start, NULL);
    for (i = 0; i < ITERATIONS; i++) {
	for (j = 0; j < BUFFERS; j++ ) {
	    uintptr_t ba = pcilib_kmem_get_block_ba(pci, kbuf, j);
	    WR(0x08, ba)
	    
	    WR(0x04, 0x01)

	    err = pcilib_wait_irq(pci, PCILIB_IRQ_SOURCE_DEFAULT, TIMEOUT, NULL);
	    if (err) printf("Timeout waiting for IRQ, err: %i\n", err);
	    
	    RD(0x04, status);
	    if ((status&0xFFFF) != 0x101) printf("Invalid status %x\n", status);
//	    WR(0x04, 0x00);

	    WR(0x00, 1)
	    do {
		RD(0x04, status);
	    } while (status != 0);
//	    usleep(1);
	    WR(0x00, 0)
	}
    }
    gettimeofday(&end, NULL);

    pcilib_free_kernel_memory(pci, kbuf,  0);
    pcilib_disable_irq(pci, 0);
    pcilib_unmap_bar(pci, BAR, bar);
    pcilib_close(pci);

    run_time = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
    size = ITERATIONS * BUFFERS * PAGE_SIZE;

    printf("%.3lf GB/s: transfered %zu bytes in %zu us using %u buffers\n", 1000000. * size / run_time / 1024 / 1024 / 1024, size, run_time, BUFFERS);
}