diff options
author | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2012-11-14 05:39:28 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@dside.dyndns.org> | 2012-11-14 05:39:28 +0100 |
commit | 7f6ee41a4963b05494900d8392f82f318c476770 (patch) | |
tree | 6fdc990fa93949310511f7f6e3026b21d0114c87 | |
parent | 8ae66e50aa659a45dc108433d63917b25cb08cbe (diff) | |
download | ipecamera-7f6ee41a4963b05494900d8392f82f318c476770.tar.gz ipecamera-7f6ee41a4963b05494900d8392f82f318c476770.tar.bz2 ipecamera-7f6ee41a4963b05494900d8392f82f318c476770.tar.xz ipecamera-7f6ee41a4963b05494900d8392f82f318c476770.zip |
Xilinx benchmark
-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 |