summaryrefslogtreecommitdiffstats
path: root/protocols/default.c
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/default.c
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/default.c')
-rw-r--r--protocols/default.c35
1 files changed, 33 insertions, 2 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;