diff options
Diffstat (limited to 'pcilib')
-rw-r--r-- | pcilib/CMakeLists.txt | 6 | ||||
-rw-r--r-- | pcilib/bar.c | 197 | ||||
-rw-r--r-- | pcilib/bar.h | 7 | ||||
-rw-r--r-- | pcilib/fifo.c | 55 | ||||
-rw-r--r-- | pcilib/fifo.h | 4 | ||||
-rw-r--r-- | pcilib/pci.c | 216 | ||||
-rw-r--r-- | pcilib/pci.h | 1 |
7 files changed, 273 insertions, 213 deletions
diff --git a/pcilib/CMakeLists.txt b/pcilib/CMakeLists.txt index eb86762..bb0abfd 100644 --- a/pcilib/CMakeLists.txt +++ b/pcilib/CMakeLists.txt @@ -3,8 +3,8 @@ include_directories( ${CMAKE_SOURCE_DIR}/pcilib ) -set(HEADERS pcilib.h pci.h export.h model.h bank.h register.h kmem.h irq.h dma.h event.h plugin.h tools.h error.h debug.h version.h config.h) -add_library(pcilib SHARED pci.c export.c model.c bank.c register.c kmem.c irq.c dma.c event.c plugin.c tools.c error.c debug.c) +set(HEADERS pcilib.h pci.h export.h bar.h fifo.h model.h bank.h register.h kmem.h irq.h dma.h event.h plugin.h tools.h error.h debug.h version.h config.h) +add_library(pcilib SHARED pci.c export.c bar.c fifo.c model.c bank.c register.c kmem.c irq.c dma.c event.c plugin.c tools.c error.c debug.c) target_link_libraries(pcilib dma protocols ${CMAKE_THREAD_LIBS_INIT} ${UFODECODE_LIBRARIES} ${CMAKE_DL_LIBS}) add_dependencies(pcilib dma protocols) @@ -16,6 +16,6 @@ install(FILES pcilib.h DESTINATION include ) -install(FILES bank.h register.h dma.h event.h model.h error.h debug.h tools.h export.h version.h +install(FILES bar.h kmem.h bank.h register.h dma.h event.h model.h error.h debug.h tools.h export.h version.h DESTINATION include/pcilib ) diff --git a/pcilib/bar.c b/pcilib/bar.c new file mode 100644 index 0000000..a2670c0 --- /dev/null +++ b/pcilib/bar.c @@ -0,0 +1,197 @@ +#define _BSD_SOURCE +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <arpa/inet.h> +#include <errno.h> +#include <assert.h> + +#include "pcilib.h" +#include "pci.h" +#include "tools.h" +#include "error.h" +#include "model.h" +#include "plugin.h" + +pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) { + int n = 0; + pcilib_bar_t i; + + const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); + if (!board_info) return PCILIB_BAR_INVALID; + + for (i = 0; i < PCILIB_MAX_BARS; i++) { + if (board_info->bar_length[i] > 0) { + if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i; + + if (n) n = -1; + else n = i + 1; + } + } + + if (n > 0) return n - 1; + + return PCILIB_BAR_INVALID; +} + +int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) { + const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); + if (!board_info) return PCILIB_ERROR_NOTFOUND; + + if (*bar == PCILIB_BAR_DETECT) { + *bar = pcilib_detect_bar(ctx, *addr, size); + if (*bar == PCILIB_BAR_INVALID) { + pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bar", *addr, size); + return PCILIB_ERROR_NOTFOUND; + } + if (*addr < board_info->bar_start[*bar]) + *addr += board_info->bar_start[*bar]; + } else { + if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) { + if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) { + *addr += board_info->bar_start[*bar]; + } else { + pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bar (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]); + return PCILIB_ERROR_NOTFOUND; + } + } + } + + *addr -= board_info->bar_start[*bar]; + *addr += board_info->bar_start[*bar] & ctx->page_mask; + + return 0; +} + +void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) { + void *res; + int ret; + + const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); + if (!board_info) return NULL; + + if (ctx->bar_space[bar]) return ctx->bar_space[bar]; + + ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI ); + if (ret) { + pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar); + return NULL; + } + + ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar ); + if (ret) { + pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar); + return NULL; + } + +#ifdef PCILIB_FILE_IO + file_io_handle = open("/root/data", O_RDWR); + res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 ); +#else + res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); +#endif + if ((!res)||(res == MAP_FAILED)) { + pcilib_error("Failed to mmap data bank %i", bar); + return NULL; + } + + + return res; +} + +void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) { + const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); + if (!board_info) return; + + if (ctx->bar_space[bar]) return; + + munmap(data, board_info->bar_length[bar]); +#ifdef PCILIB_FILE_IO + close(ctx->file_io_handle); +#endif +} + +int pcilib_map_register_space(pcilib_t *ctx) { + int err; + pcilib_register_bank_t i; + + if (!ctx->reg_bar_mapped) { + const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); + const pcilib_register_bank_description_t *banks = model_info->banks; + + for (i = 0; ((banks)&&(banks[i].access)); i++) { +// uint32_t buf[2]; + void *reg_space; + pcilib_bar_t bar = banks[i].bar; + + if (bar == PCILIB_BAR_DETECT) { + uintptr_t addr = banks[0].read_addr; + + err = pcilib_detect_address(ctx, &bar, &addr, 1); + if (err) return err; + + if (!ctx->bar_space[bar]) { + reg_space = pcilib_map_bar(ctx, bar); +// pcilib_memcpy(&buf, reg_space, 8); + + if (reg_space) { + ctx->bar_space[bar] = reg_space; + } else { + return PCILIB_ERROR_FAILED; + } + } + } else if (!ctx->bar_space[bar]) { + reg_space = pcilib_map_bar(ctx, bar); + if (reg_space) { + ctx->bar_space[bar] = reg_space; + } else { + return PCILIB_ERROR_FAILED; + } +// pcilib_memcpy(&buf, reg_space, 8); + + } + + if (!i) ctx->reg_bar = bar; + } + + + ctx->reg_bar_mapped = 1; + } + + return 0; +} + +int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) { + void *data; + + pcilib_detect_address(ctx, &bar, &addr, size); + data = pcilib_map_bar(ctx, bar); + + pcilib_memcpy(buf, data + addr, size); + + 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) { + void *data; + + pcilib_detect_address(ctx, &bar, &addr, size); + data = pcilib_map_bar(ctx, bar); + + pcilib_memcpy(data + addr, buf, size); + + pcilib_unmap_bar(ctx, bar, data); + + return 0; +} + diff --git a/pcilib/bar.h b/pcilib/bar.h new file mode 100644 index 0000000..9680fc1 --- /dev/null +++ b/pcilib/bar.h @@ -0,0 +1,7 @@ +#ifndef _PCILIB_BAR_H +#define _PCILIB_BAR_H + +pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size); +int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size); + +#endif /* _PCILIB_BAR_H */ diff --git a/pcilib/fifo.c b/pcilib/fifo.c new file mode 100644 index 0000000..593400f --- /dev/null +++ b/pcilib/fifo.c @@ -0,0 +1,55 @@ +#define _BSD_SOURCE +#define _POSIX_C_SOURCE 200809L + +#include <stdio.h> +#include <string.h> +#include <strings.h> +#include <stdlib.h> +#include <stdint.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <arpa/inet.h> +#include <errno.h> +#include <assert.h> + +#include "pcilib.h" +#include "pci.h" +#include "tools.h" +#include "error.h" +#include "model.h" +#include "plugin.h" +#include "bar.h" + +int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { + int i; + void *data; + + pcilib_detect_address(ctx, &bar, &addr, fifo_size); + data = pcilib_map_bar(ctx, bar); + + for (i = 0; i < n; i++) { + pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size); + } + + pcilib_unmap_bar(ctx, bar, data); + + return 0; +} + +int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { + int i; + void *data; + + pcilib_detect_address(ctx, &bar, &addr, fifo_size); + data = pcilib_map_bar(ctx, bar); + + for (i = 0; i < n; i++) { + pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size); + } + + pcilib_unmap_bar(ctx, bar, data); + + return 0; +} diff --git a/pcilib/fifo.h b/pcilib/fifo.h new file mode 100644 index 0000000..1bd5434 --- /dev/null +++ b/pcilib/fifo.h @@ -0,0 +1,4 @@ +#ifndef _PCILIB_FIFO_H +#define _PCILIB_FIFO_H + +#endif /* _PCILIB_FIFO_H */ diff --git a/pcilib/pci.c b/pcilib/pci.c index 62b3c64..a9cefda 100644 --- a/pcilib/pci.c +++ b/pcilib/pci.c @@ -21,6 +21,7 @@ #include "error.h" #include "model.h" #include "plugin.h" +#include "bar.h" static int pcilib_detect_model(pcilib_t *ctx, const char *model) { int i, j; @@ -86,8 +87,12 @@ static int pcilib_detect_model(pcilib_t *ctx, const char *model) { // how we reconcile the banks from event model and dma description? The banks specified in the DMA description should override corresponding banks of events... - if ((model)&&(!model_info)/*&&(no xml)*/) - return PCILIB_ERROR_NOTFOUND; + if (!model_info) { + if ((model)&&(strcasecmp(model, "pci"))/*&&(no xml)*/) + return PCILIB_ERROR_NOTFOUND; + + ctx->model = strdup("pci"); + } return 0; } @@ -192,155 +197,6 @@ pcilib_context_t *pcilib_get_implementation_context(pcilib_t *ctx) { return ctx->event_ctx; } - -static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) { - int n = 0; - pcilib_bar_t i; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_BAR_INVALID; - - for (i = 0; i < PCILIB_MAX_BARS; i++) { - if (board_info->bar_length[i] > 0) { - if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i; - - if (n) n = -1; - else n = i + 1; - } - } - - if (n > 0) return n - 1; - - return PCILIB_BAR_INVALID; -} - -int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return PCILIB_ERROR_NOTFOUND; - - if (*bar == PCILIB_BAR_DETECT) { - *bar = pcilib_detect_bar(ctx, *addr, size); - if (*bar == PCILIB_BAR_INVALID) { - pcilib_error("The requested data block at address 0x%x with size %zu does not belongs to any available memory bank", *addr, size); - return PCILIB_ERROR_NOTFOUND; - } - if (*addr < board_info->bar_start[*bar]) - *addr += board_info->bar_start[*bar]; - } else { - if ((*addr < board_info->bar_start[*bar])||((board_info->bar_start[*bar] + board_info->bar_length[*bar]) < (((uintptr_t)*addr) + size))) { - if ((board_info->bar_length[*bar]) >= (((uintptr_t)*addr) + size)) { - *addr += board_info->bar_start[*bar]; - } else { - pcilib_error("The requested data block at address 0x%x with size %zu does not belong the specified memory bank (Bar %i: starting at 0x%x with size 0x%x)", *addr, size, *bar, board_info->bar_start[*bar], board_info->bar_length[*bar]); - return PCILIB_ERROR_NOTFOUND; - } - } - } - - *addr -= board_info->bar_start[*bar]; - *addr += board_info->bar_start[*bar] & ctx->page_mask; - - return 0; -} - -void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) { - void *res; - int ret; - - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return NULL; - - if (ctx->bar_space[bar]) return ctx->bar_space[bar]; - - ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar); - return NULL; - } - - ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_AREA, PCIDRIVER_BAR0 + bar ); - if (ret) { - pcilib_error("PCIDRIVER_IOC_MMAP_AREA ioctl have failed for bank %i", bar); - return NULL; - } - -#ifdef PCILIB_FILE_IO - file_io_handle = open("/root/data", O_RDWR); - res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->file_io_handle, 0 ); -#else - res = mmap( 0, board_info->bar_length[bar], PROT_WRITE | PROT_READ, MAP_SHARED, ctx->handle, 0 ); -#endif - if ((!res)||(res == MAP_FAILED)) { - pcilib_error("Failed to mmap data bank %i", bar); - return NULL; - } - - - return res; -} - -void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) { - const pcilib_board_info_t *board_info = pcilib_get_board_info(ctx); - if (!board_info) return; - - if (ctx->bar_space[bar]) return; - - munmap(data, board_info->bar_length[bar]); -#ifdef PCILIB_FILE_IO - close(ctx->file_io_handle); -#endif -} - -int pcilib_map_register_space(pcilib_t *ctx) { - int err; - pcilib_register_bank_t i; - - if (!ctx->reg_bar_mapped) { - const pcilib_model_description_t *model_info = pcilib_get_model_description(ctx); - const pcilib_register_bank_description_t *banks = model_info->banks; - - for (i = 0; ((banks)&&(banks[i].access)); i++) { -// uint32_t buf[2]; - void *reg_space; - pcilib_bar_t bar = banks[i].bar; - - if (bar == PCILIB_BAR_DETECT) { - uintptr_t addr = banks[0].read_addr; - - err = pcilib_detect_address(ctx, &bar, &addr, 1); - if (err) return err; - - if (!ctx->bar_space[bar]) { - reg_space = pcilib_map_bar(ctx, bar); -// pcilib_memcpy(&buf, reg_space, 8); - - if (reg_space) { - ctx->bar_space[bar] = reg_space; - } else { - return PCILIB_ERROR_FAILED; - } - } - } else if (!ctx->bar_space[bar]) { - reg_space = pcilib_map_bar(ctx, bar); - if (reg_space) { - ctx->bar_space[bar] = reg_space; - } else { - return PCILIB_ERROR_FAILED; - } -// pcilib_memcpy(&buf, reg_space, 8); - - } - - if (!i) ctx->reg_bar = bar; - } - - - ctx->reg_bar_mapped = 1; - } - - return 0; -} - int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) { int err; pcilib_bar_t i; @@ -505,61 +361,3 @@ void pcilib_close(pcilib_t *ctx) { } } -int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, void *buf) { - void *data; - - pcilib_detect_address(ctx, &bar, &addr, size); - data = pcilib_map_bar(ctx, bar); - - pcilib_memcpy(buf, data + addr, size); - - 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) { - void *data; - - pcilib_detect_address(ctx, &bar, &addr, size); - data = pcilib_map_bar(ctx, bar); - - pcilib_memcpy(data + addr, buf, size); - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} - - -int pcilib_read_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { - int i; - void *data; - - pcilib_detect_address(ctx, &bar, &addr, fifo_size); - data = pcilib_map_bar(ctx, bar); - - for (i = 0; i < n; i++) { - pcilib_memcpy(buf + i * fifo_size, data + addr, fifo_size); - } - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} - -int pcilib_write_fifo(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, uint8_t fifo_size, size_t n, void *buf) { - int i; - void *data; - - pcilib_detect_address(ctx, &bar, &addr, fifo_size); - data = pcilib_map_bar(ctx, bar); - - for (i = 0; i < n; i++) { - pcilib_memcpy(data + addr, buf + i * fifo_size, fifo_size); - } - - pcilib_unmap_bar(ctx, bar, data); - - return 0; -} diff --git a/pcilib/pci.h b/pcilib/pci.h index 0775663..a914e84 100644 --- a/pcilib/pci.h +++ b/pcilib/pci.h @@ -70,6 +70,5 @@ const pcilib_board_info_t *pcilib_get_board_info(pcilib_t *ctx); int pcilib_map_register_space(pcilib_t *ctx); int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr); -int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size); #endif /* _PCITOOL_PCI_H */ |