summaryrefslogtreecommitdiffstats
path: root/protocols
diff options
context:
space:
mode:
authorSuren A. Chilingaryan <csa@suren.me>2015-11-18 03:25:02 +0100
committerSuren A. Chilingaryan <csa@suren.me>2015-11-18 03:25:02 +0100
commitca7353be486a0364a3460b511291a40182f130ba (patch)
tree1505293794cbe29fdeb6341bbe699c52dd39f8aa /protocols
parentec667d49f84c45c261f050313d64f89ce88e4302 (diff)
downloadpcitool-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.c35
-rw-r--r--protocols/default.h3
-rw-r--r--protocols/property.h2
-rw-r--r--protocols/software.c15
-rw-r--r--protocols/software.h12
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 */