summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-11-20 18:26:29 +0100
committerSuren A. Chilingaryan <csa@suren.me>2015-11-20 18:26:29 +0100
commitbba9c619c79175b58359116b52a889e30a632d07 (patch)
tree6da3898d50880e96f2afa5d5139bd16263fccf42
parentfe5bca8604e8c381d3fe2cce3073dd6602d016d1 (diff)
downloadpcitool-bba9c619c79175b58359116b52a889e30a632d07.tar.gz
pcitool-bba9c619c79175b58359116b52a889e30a632d07.tar.bz2
pcitool-bba9c619c79175b58359116b52a889e30a632d07.tar.xz
pcitool-bba9c619c79175b58359116b52a889e30a632d07.zip
64-bit access to BAR memory
-rw-r--r--CMakeLists.txt2
-rw-r--r--pcilib/bar.c13
-rw-r--r--pcilib/datacpy.c2
-rw-r--r--pcilib/fifo.c4
-rw-r--r--pcilib/memcpy.c16
-rw-r--r--pcilib/memcpy.h3
-rw-r--r--pcilib/pcilib.h10
-rw-r--r--pcitool/cli.c22
8 files changed, 45 insertions, 27 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1db3de0..63bdeb3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
project(pcitool)
-set(PCILIB_VERSION "0.2.4")
+set(PCILIB_VERSION "0.2.5")
set(PCILIB_ABI_VERSION "2")
cmake_minimum_required(VERSION 2.6)
diff --git a/pcilib/bar.c b/pcilib/bar.c
index 6d6cd6d..85c0e12 100644
--- a/pcilib/bar.c
+++ b/pcilib/bar.c
@@ -119,6 +119,7 @@ void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
return NULL;
}
+ ctx->bar_space[bar] = res;
return res;
}
@@ -323,26 +324,26 @@ const pcilib_bar_info_t *pcilib_get_bar_info(pcilib_t *ctx, pcilib_bar_t bar) {
return NULL;
}
-int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
+int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t access, size_t n, void *buf) {
void *data;
- pcilib_detect_address(ctx, &bar, &addr, size);
+ pcilib_detect_address(ctx, &bar, &addr, access * n);
data = pcilib_map_bar(ctx, bar);
- pcilib_memcpy(buf, data + addr, size);
+ pcilib_memcpy(buf, data + addr, access, n);
pcilib_unmap_bar(ctx, bar, data);
return 0;
}
-int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) {
+int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t access, size_t n, void *buf) {
void *data;
- pcilib_detect_address(ctx, &bar, &addr, size);
+ pcilib_detect_address(ctx, &bar, &addr, access * n);
data = pcilib_map_bar(ctx, bar);
- pcilib_memcpy(data + addr, buf, size);
+ pcilib_memcpy(data + addr, buf, access, n);
pcilib_unmap_bar(ctx, bar, data);
diff --git a/pcilib/datacpy.c b/pcilib/datacpy.c
index 15dfbe9..27bff11 100644
--- a/pcilib/datacpy.c
+++ b/pcilib/datacpy.c
@@ -81,7 +81,7 @@ void *pcilib_datacpy(void * dst, void const * src, uint8_t size, size_t n, pcili
size_t pos = 0;
pcilib_datacpy_routine_t routine;
- assert((size)&&(size < 64));
+ assert((size)&&(size <= 8));
while (size >>= 1) ++pos;
routine = pcilib_datacpy_routines[pos];
diff --git a/pcilib/fifo.c b/pcilib/fifo.c
index 7ed87b8..2ae4303 100644
--- a/pcilib/fifo.c
+++ b/pcilib/fifo.c
@@ -31,7 +31,7 @@ int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fi
data = pcilib_map_bar(ctx, bar);
for (i = 0; i < n; i++) {
- pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size);
+ pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size, 1);
}
pcilib_unmap_bar(ctx, bar, data);
@@ -47,7 +47,7 @@ int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t f
data = pcilib_map_bar(ctx, bar);
for (i = 0; i < n; i++) {
- pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size);
+ pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size, 1);
}
pcilib_unmap_bar(ctx, bar, data);
diff --git a/pcilib/memcpy.c b/pcilib/memcpy.c
index 149d1fd..dd55037 100644
--- a/pcilib/memcpy.c
+++ b/pcilib/memcpy.c
@@ -64,3 +64,19 @@ void *pcilib_memcpy64(void * dst, void const * src, size_t len) {
return (dst);
}
+typedef void* (*pcilib_memcpy_routine_t)(void * dst, void const *src, size_t bytes);
+static pcilib_memcpy_routine_t pcilib_memcpy_routines[4] = {
+ pcilib_memcpy8, NULL, pcilib_memcpy32, pcilib_memcpy64
+};
+
+void *pcilib_memcpy(void * dst, void const * src, uint8_t access, size_t n) {
+ size_t pos = 0, size = n * access;
+ pcilib_memcpy_routine_t routine;
+
+ assert((access)&&(access <= 8));
+
+ while (access >>= 1) ++pos;
+ routine = pcilib_memcpy_routines[pos];
+
+ return routine(dst, src, size);
+}
diff --git a/pcilib/memcpy.h b/pcilib/memcpy.h
index 3ac2115..dbfae36 100644
--- a/pcilib/memcpy.h
+++ b/pcilib/memcpy.h
@@ -5,8 +5,6 @@
#include <stdint.h>
-#define pcilib_memcpy pcilib_memcpy32
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -14,6 +12,7 @@ extern "C" {
void *pcilib_memcpy8(void * dst, void const * src, size_t len);
void *pcilib_memcpy32(void * dst, void const * src, size_t len);
void *pcilib_memcpy64(void * dst, void const * src, size_t len);
+void *pcilib_memcpy(void * dst, void const * src, uint8_t access, size_t n);
#ifdef __cplusplus
}
diff --git a/pcilib/pcilib.h b/pcilib/pcilib.h
index cfe3e96..3e7cf2b 100644
--- a/pcilib/pcilib.h
+++ b/pcilib/pcilib.h
@@ -327,22 +327,24 @@ char *pcilib_resolve_bar_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr
* @param[in,out] ctx - pcilib context
* @param[in] bar - the BAR to read, use PCILIB_BAR_DETECT to detect bar by the specified physical address
* @param[in] addr - absolute physical address to read or the offset in the specified bar
- * @param[in] size - number of bytes to read
+ * @param[in] access - word size (access width in bytes)
+ * @param[in] n - number of words to read
* @param[out] buf - the read data will be placed in this buffer
* @return - error code or 0 on success
*/
-int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
+int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t access, size_t n, void *buf);
/**
* Performs PIO write to the PCI BAR. The BAR will be automatically mapped and unmapped if necessary.
* @param[in,out] ctx - pcilib context
* @param[in] bar - the BAR to write, use PCILIB_BAR_DETECT to detect bar by the specified physical address
* @param[in] addr - absolute physical address to write or the offset in the specified bar
- * @param[in] size - number of bytes to write
+ * @param[in] access - word size (access width in bytes)
+ * @param[in] n - number of words to write
* @param[out] buf - the pointer to the data to be written
* @return - error code or 0 on success
*/
-int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf);
+int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t access, size_t n, void *buf);
/**
* Performs PIO read from the PCI BAR. The specified address is treated as FIFO and will be read
diff --git a/pcitool/cli.c b/pcitool/cli.c
index 0a070d7..c175c31 100644
--- a/pcitool/cli.c
+++ b/pcitool/cli.c
@@ -1115,12 +1115,12 @@ int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
gettimeofday(&start,NULL);
if (mode == ACCESS_BAR) {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_memcpy(buf, data, size);
+ pcilib_memcpy(buf, data, access, size / access);
}
} else {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
for (j = 0; j < (size/access); j++) {
- pcilib_memcpy(buf + j * access, fifo, access);
+ pcilib_memcpy(buf + j * access, fifo, access, 1);
}
}
}
@@ -1134,12 +1134,12 @@ int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
gettimeofday(&start,NULL);
if (mode == ACCESS_BAR) {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_memcpy(data, buf, size);
+ pcilib_memcpy(data, buf, access, size / access);
}
} else {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
for (j = 0; j < (size/access); j++) {
- pcilib_memcpy(fifo, buf + j * access, access);
+ pcilib_memcpy(fifo, buf + j * access, access, 1);
}
}
}
@@ -1155,7 +1155,7 @@ int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
gettimeofday(&start,NULL);
if (mode == ACCESS_BAR) {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_read(handle, bar, 0, size, buf);
+ pcilib_read(handle, bar, 0, access, size / access, buf);
}
} else {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
@@ -1172,7 +1172,7 @@ int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
gettimeofday(&start,NULL);
if (mode == ACCESS_BAR) {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_write(handle, bar, 0, size, buf);
+ pcilib_write(handle, bar, 0, access, size / access, buf);
}
} else {
for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
@@ -1188,8 +1188,8 @@ int Benchmark(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
if (mode == ACCESS_BAR) {
gettimeofday(&start,NULL);
for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
- pcilib_write(handle, bar, 0, size, buf);
- pcilib_read(handle, bar, 0, size, check);
+ pcilib_write(handle, bar, 0, access, size / access, buf);
+ pcilib_read(handle, bar, 0, access, size / access, check);
if (memcmp(buf, check, size)) ++errors;
}
gettimeofday(&end,NULL);
@@ -1344,7 +1344,7 @@ int ReadData(pcilib_t *handle, ACCESS_MODE mode, FLAGS flags, pcilib_dma_engine_
close(fd);
break;
default:
- pcilib_read(handle, bar, addr, size, buf);
+ pcilib_read(handle, bar, addr, access, size / access, buf);
}
if (endianess) pcilib_swap(buf, buf, abs(access), n);
@@ -1601,9 +1601,9 @@ int WriteData(pcilib_t *handle, ACCESS_MODE mode, pcilib_dma_engine_addr_t dma,
pcilib_write_fifo(handle, bar, addr, access, n, buf);
break;
default:
- pcilib_write(handle, bar, addr, size, buf);
+ pcilib_write(handle, bar, addr, access, size / access, buf);
if (verify) {
- pcilib_read(handle, bar, addr, size, check);
+ pcilib_read(handle, bar, addr, access, size / access, check);
read_back = 1;
}
}