diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2014-04-03 00:37:21 +0200 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2014-04-03 00:37:21 +0200 |
commit | a1925232b26bc0d9801d7c1dcd58301841877af1 (patch) | |
tree | 8da70a5e091d5400fd063c385ec473d17b708583 /apps/xilinx.c | |
parent | d8c13eb6ff5a1c9cc28617d83dbde454c7222be4 (diff) | |
parent | c57db04f528e671040256d322bb8f21a8d8e9ac1 (diff) | |
download | pcitool-a1925232b26bc0d9801d7c1dcd58301841877af1.tar.gz pcitool-a1925232b26bc0d9801d7c1dcd58301841877af1.tar.bz2 pcitool-a1925232b26bc0d9801d7c1dcd58301841877af1.tar.xz pcitool-a1925232b26bc0d9801d7c1dcd58301841877af1.zip |
Merge changes from xilinx_dma branch providing support of multipage kmem allocations and mapping memory regions reserved with memmap boot option
Diffstat (limited to 'apps/xilinx.c')
-rw-r--r-- | apps/xilinx.c | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/apps/xilinx.c b/apps/xilinx.c index 1ec31d7..757c388 100644 --- a/apps/xilinx.c +++ b/apps/xilinx.c @@ -2,6 +2,7 @@ #define _POSIX_C_SOURCE 199309L #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <stdarg.h> #include <time.h> @@ -15,23 +16,27 @@ #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 STATIC_REGION 0x80000000 // to reserve 512 MB at the specified address, add "memmap=512M$2G" to kernel parameters +#define BUFFERS 1 +#define ITERATIONS 100 +#define TLP_SIZE 64 +#define HUGE_PAGE 4096 // number of pages per huge page #define PAGE_SIZE 4096 // other values are not supported in the kernel #define TIMEOUT 100000 /* IRQs are slow for some reason. REALTIME mode is slower. Adding delays does not really help, otherall we have only 3 checks in average. Check ready seems to be not needed and adds quite much extra time */ -//#define USE_IRQ +#define USE_IRQ //#define CHECK_READY //#define REALTIME //#define ADD_DELAYS +#define CHECK_RESULT //#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); } +#define WR(addr, value) { *(uint32_t*)(bar + addr + offset) = value; } +#define RD(addr, value) { value = *(uint32_t*)(bar + addr + offset); } static void fail(const char *msg, ...) { va_list va; @@ -63,7 +68,7 @@ void hpsleep(size_t ns) { int main() { int err; - int i, j; + long i, j; pcilib_t *pci; pcilib_kmem_handle_t *kbuf; uint32_t status; @@ -72,12 +77,15 @@ int main() { void* volatile bar; uintptr_t bus_addr[BUFFERS]; + pcilib_bar_t bar_tmp = BAR; + uintptr_t offset = 0; + pcilib_kmem_flags_t clean_flags = PCILIB_KMEM_FLAG_HARDWARE|PCILIB_KMEM_FLAG_PERSISTENT|PCILIB_KMEM_FLAG_EXCLUSIVE; #ifdef ADD_DELAYS long rpt = 0, rpt2 = 0; size_t best_time; - best_time = 1000000000L * PAGE_SIZE / (4L * 1024 * 1024 * 1024); + best_time = 1000000000L * HUGE_PAGE * PAGE_SIZE / (4L * 1024 * 1024 * 1024); #endif /* ADD_DELAYS */ #ifdef REALTIME @@ -99,22 +107,46 @@ int main() { fail("map bar"); } + pcilib_detect_address(pci, &bar_tmp, &offset, 1); + + // Reset + WR(0x00, 1) + usleep(1000); + WR(0x00, 0) + 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); +#ifdef STATIC_REGION + kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_REGION_C2S, BUFFERS, HUGE_PAGE * PAGE_SIZE, STATIC_REGION, USE, 0); +#else /* STATIC_REGION */ + kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, HUGE_PAGE * PAGE_SIZE, 4096, USE, 0); +#endif /* STATIC_REGION */ - kbuf = pcilib_alloc_kernel_memory(pci, PCILIB_KMEM_TYPE_DMA_C2S_PAGE, BUFFERS, PAGE_SIZE, 4096, USE, 0); + if (!kbuf) { + printf("KMem allocation failed\n"); + exit(0); + } + + +#ifdef CHECK_RESULT + volatile uint32_t *ptr0 = pcilib_kmem_get_block_ua(pci, kbuf, 0); + memset((void*)ptr0, 0, (HUGE_PAGE * PAGE_SIZE)); - WR(0x00, 1) - usleep(1000); - WR(0x00, 0) + for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) { + if (ptr0[i] != 0) break; + } + if (i < (HUGE_PAGE * PAGE_SIZE / 4)) { + printf("Initialization error in position %lu, value = %x\n", i * 4, ptr0[i]); + } +#endif /* CHECK_RESULT */ + WR(0x04, 0) - - WR(0x0C, 0x20) - WR(0x10, (PAGE_SIZE / 0x80)) + WR(0x0C, TLP_SIZE) + WR(0x10, (HUGE_PAGE * (PAGE_SIZE / (4 * TLP_SIZE)))) WR(0x14, 0x13131313) for (j = 0; j < BUFFERS; j++ ) { @@ -163,17 +195,31 @@ int main() { } gettimeofday(&end, NULL); +#ifdef CHECK_RESULT + pcilib_kmem_sync_block(pci, kbuf, PCILIB_KMEM_SYNC_FROMDEVICE, 0); + + for (i = 0; i < (HUGE_PAGE * PAGE_SIZE / 4); i++) { +// printf("%lx ", ptr0[i]); + if (ptr0[i] != 0x13131313) break; + } + if (i < (HUGE_PAGE * PAGE_SIZE / 4)) { + printf("Error in position %lu, value = %x\n", i * 4, ptr0[i]); + } +#endif /* CHECK_RESULT */ + 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 = (long long int)ITERATIONS * BUFFERS * PAGE_SIZE; + size = (long long int)ITERATIONS * BUFFERS * HUGE_PAGE * 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); # ifdef ADD_DELAYS printf("Repeats: %lf, %lf\n",1. * rpt / (ITERATIONS * BUFFERS), 1. * rpt2 / (ITERATIONS * BUFFERS)); #endif /* USE_IRQ */ + + } |