diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-11-17 18:23:48 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-11-17 18:23:48 +0100 |
commit | 52e32b2c9f0e5ac7cfb31fd2306e6536340955e1 (patch) | |
tree | 720e376325d14f6713df434e031c503ba8f33c1e /protocols/software.c | |
parent | 2455a677448e0e0c17d7193bf405b734b758811b (diff) | |
download | pcitool-52e32b2c9f0e5ac7cfb31fd2306e6536340955e1.tar.gz pcitool-52e32b2c9f0e5ac7cfb31fd2306e6536340955e1.tar.bz2 pcitool-52e32b2c9f0e5ac7cfb31fd2306e6536340955e1.tar.xz pcitool-52e32b2c9f0e5ac7cfb31fd2306e6536340955e1.zip |
Support for 64-bit registes
Diffstat (limited to 'protocols/software.c')
-rw-r--r-- | protocols/software.c | 43 |
1 files changed, 28 insertions, 15 deletions
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; } |