summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2014-04-03 00:37:21 +0200
committerSuren A. Chilingaryan <csa@suren.me>2014-04-03 00:37:21 +0200
commita1925232b26bc0d9801d7c1dcd58301841877af1 (patch)
tree8da70a5e091d5400fd063c385ec473d17b708583 /apps
parentd8c13eb6ff5a1c9cc28617d83dbde454c7222be4 (diff)
parentc57db04f528e671040256d322bb8f21a8d8e9ac1 (diff)
downloadpcitool-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')
-rw-r--r--apps/xilinx.c76
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 */
+
+
}