diff options
| -rw-r--r-- | .bzrignore | 1 | ||||
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | apps/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | apps/xilinx.c | 111 | ||||
| -rw-r--r-- | kmem.h | 4 | ||||
| -rwxr-xr-x | tests/xilinx_dma.sh | 12 | 
6 files changed, 133 insertions, 4 deletions
| @@ -18,3 +18,4 @@ cmake_install.cmake  Makefile  *.so.*  install_manifest.txt +./xilinx diff --git a/CMakeLists.txt b/CMakeLists.txt index cb3be58..a756d43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,7 @@ add_definitions("-fPIC --std=c99 -Wall -O2")  add_subdirectory(dma)  add_subdirectory(ipecamera)  add_subdirectory(pcitool) +add_subdirectory(apps)  include_directories(      ${FASTWRITER_INCLUDE_DIRS} diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt new file mode 100644 index 0000000..14794b1 --- /dev/null +++ b/apps/CMakeLists.txt @@ -0,0 +1,8 @@ +include_directories( +    ${CMAKE_SOURCE_DIR} +) + +link_directories(${UFODECODE_LIBRARY_DIRS}) + +add_executable(xilinx xilinx.c) +target_link_libraries(xilinx pcilib) diff --git a/apps/xilinx.c b/apps/xilinx.c new file mode 100644 index 0000000..1312663 --- /dev/null +++ b/apps/xilinx.c @@ -0,0 +1,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); +} @@ -2,6 +2,9 @@  #define _PCILIB_KMEM_H  #include "pcilib.h" + +typedef struct pcilib_kmem_list_s pcilib_kmem_list_t; +  #include "tools.h"  typedef enum { @@ -53,7 +56,6 @@ typedef struct {  typedef void pcilib_kmem_handle_t; -typedef struct pcilib_kmem_list_s pcilib_kmem_list_t;  struct pcilib_kmem_list_s {      pcilib_kmem_list_t *next, *prev; diff --git a/tests/xilinx_dma.sh b/tests/xilinx_dma.sh index 2a26865..6aada8b 100755 --- a/tests/xilinx_dma.sh +++ b/tests/xilinx_dma.sh @@ -59,7 +59,7 @@ function parse_config {      echo "Link: PCIe gen$link_speed x$link_width"      if [ $link_speed -ne $dev_link_speed -o $link_width -ne $dev_link_width ]; then -	echo " * But device capable of gen$link_speed x$link_width" +	echo " * But device capable of gen$dev_link_speed x$dev_link_width"      fi      info=0x`read_cfg 40` @@ -99,7 +99,12 @@ for i in `seq 1 $ITERATIONS`; do  #Trigger      pci -b $BAR -w 0x04 0x01      pci --wait-irq -    pci -b $BAR -w 0x04 0x00 +#    pci -b $BAR -w 0x04 0x00 + +    status=`pci -b $BAR -r 0x04 | awk '{print $2; }' | cut -c 5-8` +    if [ $status != "0101" ]; then +	echo "Read failed, invalid status: $status" +    fi      dmaperf=$((dmaperf + 0x`pci -b $BAR -r 0x28 | awk '{print $2}'`))      reset @@ -110,6 +115,7 @@ pci --free-kernel-memory $USE  pci --disable-irq  echo -echo "FPGA performance: $((4096 * BUFFERS * ITERATIONS * $speed / $dmaperf)) MB/s" +# Don't ask me about this formula +echo "Performance reported by FPGA: $((4096 * BUFFERS * ITERATIONS * $speed / $dmaperf / 8)) MB/s"  #pci -b $BAR  -r 0 -s 32 | 
