diff options
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/default.c | 1 | ||||
-rw-r--r-- | protocols/software.c | 43 |
2 files changed, 29 insertions, 15 deletions
diff --git a/protocols/default.c b/protocols/default.c index cbc53a8..6f3dccf 100644 --- a/protocols/default.c +++ b/protocols/default.c @@ -6,6 +6,7 @@ #include "model.h" #include "error.h" #include "bar.h" +#include "datacpy.h" #define default_datacpy(dst, src, access, bank) pcilib_datacpy(dst, src, access, 1, bank->raw_endianess) diff --git a/protocols/software.c b/protocols/software.c index 55ed647..3da8fde 100644 --- a/protocols/software.c +++ b/protocols/software.c @@ -4,11 +4,14 @@ #include <string.h> #include <sys/file.h> + +#include "tools.h" #include "model.h" #include "error.h" #include "kmem.h" #include "pcilib.h" #include "pci.h" +#include "datacpy.h" typedef struct pcilib_software_register_bank_context_s pcilib_software_register_bank_context_t; @@ -103,23 +106,33 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc } int pcilib_software_registers_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value){ - if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) { - pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr); - return PCILIB_ERROR_INVALID_ADDRESS; - } + const pcilib_register_bank_description_t *b = bank_ctx->bank; + int access = b->access / 8; + + pcilib_register_value_t val = 0; + + if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) { + pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr); + return PCILIB_ERROR_INVALID_ADDRESS; + } + + pcilib_datacpy(&val, ((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, access, 1, b->raw_endianess); + *value = val; - // we consider this atomic operation and, therefore, do no locking - *value = *(pcilib_register_value_t*)(((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr); - return 0; + return 0; } int pcilib_software_registers_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t value) { - if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) { - pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr); - return PCILIB_ERROR_INVALID_ADDRESS; - } - - // we consider this atomic operation and, therefore, do no locking - *(pcilib_register_value_t*)(((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr) = value; - return 0; + const pcilib_register_bank_description_t *b = bank_ctx->bank; + int access = b->access / 8; + + if ((addr + sizeof(pcilib_register_value_t)) > bank_ctx->bank->size) { + pcilib_error("Trying to access space outside of the define register bank (bank: %s, addr: 0x%lx)", bank_ctx->bank->name, addr); + return PCILIB_ERROR_INVALID_ADDRESS; + } + + // we consider this atomic operation and, therefore, do no locking + pcilib_datacpy(((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr, &value, access, 1, b->raw_endianess); + + return 0; } |