diff options
author | Suren A. Chilingaryan <csa@suren.me> | 2015-11-18 03:25:02 +0100 |
---|---|---|
committer | Suren A. Chilingaryan <csa@suren.me> | 2015-11-18 03:25:02 +0100 |
commit | ca7353be486a0364a3460b511291a40182f130ba (patch) | |
tree | 1505293794cbe29fdeb6341bbe699c52dd39f8aa /protocols | |
parent | ec667d49f84c45c261f050313d64f89ce88e4302 (diff) | |
download | pcitool-ca7353be486a0364a3460b511291a40182f130ba.tar.gz pcitool-ca7353be486a0364a3460b511291a40182f130ba.tar.bz2 pcitool-ca7353be486a0364a3460b511291a40182f130ba.tar.xz pcitool-ca7353be486a0364a3460b511291a40182f130ba.zip |
Provide API calls for register and bank address resolution
Diffstat (limited to 'protocols')
-rw-r--r-- | protocols/default.c | 35 | ||||
-rw-r--r-- | protocols/default.h | 3 | ||||
-rw-r--r-- | protocols/property.h | 2 | ||||
-rw-r--r-- | protocols/software.c | 15 | ||||
-rw-r--r-- | protocols/software.h | 12 |
5 files changed, 62 insertions, 5 deletions
diff --git a/protocols/default.c b/protocols/default.c index 6f3dccf..f78c656 100644 --- a/protocols/default.c +++ b/protocols/default.c @@ -7,9 +7,40 @@ #include "error.h" #include "bar.h" #include "datacpy.h" +#include "pci.h" #define default_datacpy(dst, src, access, bank) pcilib_datacpy(dst, src, access, 1, bank->raw_endianess) +uintptr_t pcilib_default_resolve(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_address_resolution_flags_t flags, pcilib_register_addr_t reg_addr) { + uintptr_t addr; + const pcilib_register_bank_description_t *b = bank_ctx->bank; + + if (reg_addr == PCILIB_REGISTER_ADDRESS_INVALID) reg_addr = 0; + + switch (flags&PCILIB_ADDRESS_RESOLUTION_MASK_ACCESS_MODE) { + case 0: + if (b->read_addr != b->write_addr) + return PCILIB_ADDRESS_INVALID; + case PCILIB_ADDRESS_RESOLUTION_FLAG_READ_ONLY: + addr = b->read_addr + reg_addr; + break; + case PCILIB_ADDRESS_RESOLUTION_FLAG_WRITE_ONLY: + addr = b->write_addr + reg_addr; + default: + return PCILIB_ADDRESS_INVALID; + } + + switch (flags&PCILIB_ADDRESS_RESOLUTION_MASK_ADDRESS_TYPE) { + case 0: + return (uintptr_t)pcilib_resolve_bar_address(ctx, b->bar, addr); + case PCILIB_ADDRESS_RESOLUTION_FLAG_BUS_ADDRESS: + case PCILIB_ADDRESS_RESOLUTION_FLAG_PHYS_ADDRESS: + return ctx->board_info.bar_start[b->bar] + addr; + } + + return PCILIB_ADDRESS_INVALID; +} + int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_register_addr_t addr, pcilib_register_value_t *value) { char *ptr; pcilib_register_value_t val = 0; @@ -18,7 +49,7 @@ int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, int access = b->access / 8; - ptr = pcilib_resolve_register_address(ctx, b->bar, b->read_addr + addr); + ptr = pcilib_resolve_bar_address(ctx, b->bar, b->read_addr + addr); default_datacpy(&val, ptr, access, b); // *value = val&BIT_MASK(bits); @@ -35,7 +66,7 @@ int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx int access = b->access / 8; - ptr = pcilib_resolve_register_address(ctx, b->bar, b->write_addr + addr); + ptr = pcilib_resolve_bar_address(ctx, b->bar, b->write_addr + addr); default_datacpy(ptr, &value, access, b); return 0; diff --git a/protocols/default.h b/protocols/default.h index 829b65d..74dd91c 100644 --- a/protocols/default.h +++ b/protocols/default.h @@ -5,12 +5,13 @@ #include "version.h" #include "model.h" +uintptr_t pcilib_default_resolve(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_address_resolution_flags_t flags, pcilib_register_addr_t addr); int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t *value); int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_context_t *bank, pcilib_register_addr_t addr, pcilib_register_value_t value); #ifdef _PCILIB_EXPORT_C const pcilib_register_protocol_api_description_t pcilib_default_protocol_api = - { PCILIB_VERSION, NULL, NULL, pcilib_default_read, pcilib_default_write }; + { PCILIB_VERSION, NULL, NULL, pcilib_default_resolve, pcilib_default_read, pcilib_default_write }; #endif /* _PCILIB_EXPORT_C */ #endif /* _PCILIB_PROTOCOL_DEFAULT_H */ diff --git a/protocols/property.h b/protocols/property.h index 3d3eb63..7f9b0db 100644 --- a/protocols/property.h +++ b/protocols/property.h @@ -10,7 +10,7 @@ int pcilib_property_registers_write(pcilib_t *ctx, pcilib_register_bank_context_ #ifdef _PCILIB_EXPORT_C const pcilib_register_protocol_api_description_t pcilib_property_protocol_api = - { PCILIB_VERSION, NULL, NULL, pcilib_property_registers_read, pcilib_property_registers_write }; + { PCILIB_VERSION, NULL, NULL, NULL, pcilib_property_registers_read, pcilib_property_registers_write }; #endif /* _PCILIB_EXPORT_C */ #endif /* _PCILIB_PROTOCOL_PROPERTY_H */ diff --git a/protocols/software.c b/protocols/software.c index 3da8fde..5b217d4 100644 --- a/protocols/software.c +++ b/protocols/software.c @@ -105,6 +105,21 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc return (pcilib_register_bank_context_t*)bank_ctx; } +uintptr_t pcilib_software_registers_resolve(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_address_resolution_flags_t flags, pcilib_register_addr_t addr) { + if (addr == PCILIB_REGISTER_ADDRESS_INVALID) addr = 0; + + switch (flags&PCILIB_ADDRESS_RESOLUTION_MASK_ADDRESS_TYPE) { + case 0: + return (uintptr_t)((pcilib_software_register_bank_context_t*)bank_ctx)->addr + addr; + + case PCILIB_ADDRESS_RESOLUTION_FLAG_PHYS_ADDRESS: + return pcilib_kmem_get_block_pa(ctx, ((pcilib_software_register_bank_context_t*)bank_ctx)->kmem, 0) + addr; + } + + return PCILIB_ADDRESS_INVALID; +} + + 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){ const pcilib_register_bank_description_t *b = bank_ctx->bank; int access = b->access / 8; diff --git a/protocols/software.h b/protocols/software.h index 27ab86e..88f2986 100644 --- a/protocols/software.h +++ b/protocols/software.h @@ -28,6 +28,16 @@ pcilib_register_bank_context_t* pcilib_software_registers_open(pcilib_t *ctx, pc void pcilib_software_registers_close(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx); /** + * this function resolve the virtual address of the register for direct access + * @param[in] - ctx the pcilib_t structure runnning + * @param[in] - bank_ctx the bank context that was returned by the initialisation function + * @param[in] - flags + * @param[in] - addr the adress of the register we want to read + * @return virtual address or PCILIB_ADDRESS_INVALID on error + */ +uintptr_t pcilib_software_registers_resolve(pcilib_t *ctx, pcilib_register_bank_context_t *bank_ctx, pcilib_address_resolution_flags_t flags, pcilib_register_addr_t addr); + +/** * this function read the value of a said register in the kernel space. * @param[in] - ctx the pcilib_t structure runnning * @param[in] - bank_ctx the bank context that was returned by the initialisation function @@ -52,7 +62,7 @@ int pcilib_software_registers_write(pcilib_t *ctx,pcilib_register_bank_context_t * software protocol addition to the protocol api. */ const pcilib_register_protocol_api_description_t pcilib_software_protocol_api = - { PCILIB_VERSION, pcilib_software_registers_open, pcilib_software_registers_close,pcilib_software_registers_read, pcilib_software_registers_write }; /**< we add there the protocol to the list of possible protocols*/ + { PCILIB_VERSION, pcilib_software_registers_open, pcilib_software_registers_close, pcilib_software_registers_resolve, pcilib_software_registers_read, pcilib_software_registers_write }; #endif /* _PCILIB_EXPORT_C */ #endif /* _PCILIB_PROTOCOL_SOFTWARE_H */ |