From bba9c619c79175b58359116b52a889e30a632d07 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Fri, 20 Nov 2015 18:26:29 +0100 Subject: 64-bit access to BAR memory --- CMakeLists.txt | 2 +- pcilib/bar.c | 13 +++++++------ pcilib/datacpy.c | 2 +- pcilib/fifo.c | 4 ++-- pcilib/memcpy.c | 16 ++++++++++++++++ pcilib/memcpy.h | 3 +-- pcilib/pcilib.h | 10 ++++++---- pcitool/cli.c | 22 +++++++++++----------- 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 -#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; } } -- cgit v1.2.3