summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorroot <root@iss-tomyspiel-l>2011-06-16 01:26:14 +0200
committerroot <root@iss-tomyspiel-l>2011-06-16 01:26:14 +0200
commitc95df4d43738e1597c348bc7f98ff2902574d720 (patch)
tree1ecf978533c5cf81cc2052db696d2a2422de323e
parenta6965d707c82317f31bb7ed8eabea05b7adb6775 (diff)
downloadipecamera-c95df4d43738e1597c348bc7f98ff2902574d720.tar.gz
ipecamera-c95df4d43738e1597c348bc7f98ff2902574d720.tar.bz2
ipecamera-c95df4d43738e1597c348bc7f98ff2902574d720.tar.xz
ipecamera-c95df4d43738e1597c348bc7f98ff2902574d720.zip
Move to new FPGA design
-rw-r--r--cli.c40
-rw-r--r--default.c5
-rw-r--r--driver/pciDriver.h3
-rw-r--r--ipecamera/image.c11
-rw-r--r--ipecamera/model.c8
-rw-r--r--ipecamera/model.h33
-rw-r--r--pci.c147
-rw-r--r--pcilib.h14
8 files changed, 179 insertions, 82 deletions
diff --git a/cli.c b/cli.c
index 860fd9e..73449ee 100644
--- a/cli.c
+++ b/cli.c
@@ -397,20 +397,31 @@ int ReadData(pcilib_t *handle, pcilib_bar_t bar, uintptr_t addr, size_t n, acces
}
int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const char *reg) {
- int err;
int i;
+ int err;
+ const char *format;
+
+ pcilib_register_bank_t bank_id;
+ pcilib_register_bank_addr_t bank_addr;
+ pcilib_register_description_t *registers = pcilib_model[model].registers;
pcilib_register_value_t value;
if (reg) {
- err = pcilib_read_register(handle, bank, reg, &value);
+ pcilib_register_t regid = pcilib_find_register(handle, bank, reg);
+ bank_id = pcilib_find_bank_by_addr(handle, registers[regid].bank);
+ format = pcilib_model[model].banks[bank_id].format;
+ if (!format) format = "%lu";
+
+ err = pcilib_read_register_by_id(handle, regid, &value);
+ // err = pcilib_read_register(handle, bank, reg, &value);
if (err) printf("Error reading register %s\n", reg);
- else printf("%s = %i\n", reg, value);
+ else {
+ printf("%s = ", reg);
+ printf(format, value);
+ printf("\n");
+ }
} else {
- pcilib_register_bank_t bank_id;
- pcilib_register_bank_addr_t bank_addr;
-
- pcilib_register_description_t *registers = pcilib_model[model].registers;
if (registers) {
if (bank) {
@@ -421,9 +432,20 @@ int ReadRegister(pcilib_t *handle, pcilib_model_t model, const char *bank, const
printf("Registers:\n");
for (i = 0; registers[i].bits; i++) {
if ((registers[i].mode & PCILIB_REGISTER_R)&&((!bank)||(registers[i].bank == bank_addr))) {
+ bank_id = pcilib_find_bank_by_addr(handle, registers[i].bank);
+ format = pcilib_model[model].banks[bank_id].format;
+ if (!format) format = "%lu";
+
err = pcilib_read_register_by_id(handle, i, &value);
- if (err) printf(" %s = error reading value [%i]", registers[i].name, registers[i].defvalue);
- else printf(" %s = %i [%i]", registers[i].name, value, registers[i].defvalue);
+ if (err) printf(" %s = error reading value", registers[i].name);
+ else {
+ printf(" %s = ", registers[i].name);
+ printf(format, value);
+ }
+
+ printf(" [");
+ printf(format, registers[i].defvalue);
+ printf("]");
}
printf("\n");
}
diff --git a/default.c b/default.c
index e01a623..f771599 100644
--- a/default.c
+++ b/default.c
@@ -17,8 +17,9 @@ int pcilib_default_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank,
pcilib_register_value_t val = 0;
int access = bank->access / 8;
- ptr = pcilib_resolve_register_address(ctx, bank->read_addr + addr * access);
+ ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr + addr * access);
default_datacpy(&val, ptr, access, bank);
+// printf("%lx %lx\n",val, BIT_MASK(bits));
*value = val&BIT_MASK(bits);
@@ -32,7 +33,7 @@ int pcilib_default_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank
char *ptr;
int access = bank->access / 8;
- ptr = pcilib_resolve_register_address(ctx, bank->write_addr + addr * access);
+ ptr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr + addr * access);
default_datacpy(ptr, &value, access, bank);
return 0;
diff --git a/driver/pciDriver.h b/driver/pciDriver.h
index 05326ab..22369e9 100644
--- a/driver/pciDriver.h
+++ b/driver/pciDriver.h
@@ -87,7 +87,8 @@
#define PCIE_ML605_DEVICE_ID 0x04a0
/* Identifies the PCI-E IPE Camera */
-#define PCIE_IPECAMERA_DEVICE_ID 0x6018
+#define PCIE_IPECAMERA_DEVICE_ID 0x6081
+//#define PCIE_IPECAMERA_DEVICE_ID 0x6018
/* Possible values for ioctl commands */
diff --git a/ipecamera/image.c b/ipecamera/image.c
index 9718e85..4d55069 100644
--- a/ipecamera/image.c
+++ b/ipecamera/image.c
@@ -136,12 +136,13 @@ pcilib_context_t *ipecamera_init(pcilib_t *pcilib) {
ctx->buffer_size = IPECAMERA_DEFAULT_BUFFER_SIZE;
ctx->dim.bpp = sizeof(ipecamera_pixel_t) * 8;
-
+/*
ctx->data = pcilib_resolve_data_space(pcilib, 0, &ctx->size);
if (!ctx->data) {
err = -1;
pcilib_error("Unable to resolve the data space");
}
+*/
FIND_REG(status_reg, "fpga", "status");
FIND_REG(control_reg, "fpga", "control");
@@ -240,8 +241,10 @@ int ipecamera_reset(pcilib_context_t *vctx) {
if (err) return err;
// This is temporary for verification purposes
- memset(ctx->data, 0, ctx->size);
+ if (ctx->data) memset(ctx->data, 0, ctx->size);
+ usleep(10000);
+
err = pcilib_read_register_by_id(pcilib, status, &value);
if (err) {
pcilib_error("Error reading status register");
@@ -249,7 +252,7 @@ int ipecamera_reset(pcilib_context_t *vctx) {
}
if (value != IPECAMERA_EXPECTED_STATUS) {
- pcilib_error("Unexpected value (%lx) of status register", value);
+ pcilib_error("Unexpected value (%lx) of status register, expected %lx", value, IPECAMERA_EXPECTED_STATUS);
return PCILIB_ERROR_VERIFY;
}
@@ -477,6 +480,8 @@ static int ipecamera_get_image(ipecamera_t *ctx) {
ipecamera_payload_t *linebuf = (ipecamera_payload_t*)malloc(max_size * sizeof(ipecamera_payload_t));
if (!linebuf) return PCILIB_ERROR_MEMORY;
+ if (!ctx->data) return PCILIB_ERROR_NOTSUPPORTED;
+
#ifdef IPECAMERA_WRITE_RAW
FILE *f = fopen("raw/image.raw", "w");
if (f) fclose(f);
diff --git a/ipecamera/model.c b/ipecamera/model.c
index c258a32..23715e3 100644
--- a/ipecamera/model.c
+++ b/ipecamera/model.c
@@ -31,8 +31,8 @@ int ipecamera_read(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pcil
assert(addr < 128);
- wr = pcilib_resolve_register_address(ctx, bank->write_addr);
- rd = pcilib_resolve_register_address(ctx, bank->read_addr);
+ wr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr);
+ rd = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr);
if ((!rd)||(!wr)) {
pcilib_error("Error resolving addresses of read & write registers");
return PCILIB_ERROR_INVALID_ADDRESS;
@@ -121,8 +121,8 @@ int ipecamera_write(pcilib_t *ctx, pcilib_register_bank_description_t *bank, pci
assert(addr < 128);
assert(value < 256);
- wr = pcilib_resolve_register_address(ctx, bank->write_addr);
- rd = pcilib_resolve_register_address(ctx, bank->read_addr);
+ wr = pcilib_resolve_register_address(ctx, bank->bar, bank->write_addr);
+ rd = pcilib_resolve_register_address(ctx, bank->bar, bank->read_addr);
if ((!rd)||(!wr)) {
pcilib_error("Error resolving addresses of read & write registers");
return PCILIB_ERROR_INVALID_ADDRESS;
diff --git a/ipecamera/model.h b/ipecamera/model.h
index c3d82e3..9898084 100644
--- a/ipecamera/model.h
+++ b/ipecamera/model.h
@@ -6,15 +6,16 @@
#include "pcilib.h"
#include "image.h"
-#define IPECAMERA_REGISTER_SPACE 0xfeaffc00
+//#define IPECAMERA_REGISTER_SPACE 0xfeaffc00
+#define IPECAMERA_REGISTER_SPACE 0x9000
#define IPECAMERA_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE + 0)
-#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_WRITE + 4)
+#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_WRITE + 16)
#ifdef _IPECAMERA_MODEL_C
pcilib_register_bank_description_t ipecamera_register_banks[] = {
- { PCILIB_REGISTER_BANK0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, PCILIB_BIG_ENDIAN, 8, PCILIB_LITTLE_ENDIAN, "cmosis", "CMOSIS CMV2000 Registers" },
- { PCILIB_REGISTER_BANK1, 64, PCILIB_DEFAULT_PROTOCOL, IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_BIG_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "fpga", "IPECamera Registers" },
- { 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL }
+ { PCILIB_REGISTER_BANK0, PCILIB_BAR0, 128, IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, PCILIB_LITTLE_ENDIAN, 8, PCILIB_LITTLE_ENDIAN, "%lu", "cmosis", "CMOSIS CMV2000 Registers" },
+ { PCILIB_REGISTER_BANK1, PCILIB_BAR0, 64, PCILIB_DEFAULT_PROTOCOL, IPECAMERA_REGISTER_SPACE, IPECAMERA_REGISTER_SPACE, PCILIB_LITTLE_ENDIAN, 32, PCILIB_LITTLE_ENDIAN, "0x%lx", "fpga", "IPECamera Registers" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, NULL, NULL }
};
pcilib_register_description_t ipecamera_registers[] = {
@@ -65,17 +66,17 @@ pcilib_register_description_t ipecamera_registers[] = {
{115, 0, 1, 1, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "special_115", ""},
/*{126, 0, 16, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK0, "temp", ""},*/
{0, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "spi_conf_input", ""},
-{1, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
-{2, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
-{3, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "firmware_version", ""},
-{4, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "control", ""},
-{5, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "status", ""},
-{6, 0, 16, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "cmosis_temperature", ""},
-{7, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "temperature_sample_timing", ""},
-{8, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "start_address", ""},
-{9, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "end_address", ""},
-{10, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_address", ""},
-{11, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_value", ""},
+{4, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "spi_conf_output", ""},
+{8, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "spi_clk_speed", ""},
+{12, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "firmware_version", ""},
+{16, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "control", ""},
+{20, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "status", ""},
+{24, 0, 16, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "cmosis_temperature", ""},
+{28, 0, 32, 0, PCILIB_REGISTER_RW, PCILIB_REGISTER_BANK1, "temperature_sample_timing", ""},
+{32, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "start_address", ""},
+{36, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "end_address", ""},
+{40, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_address", ""},
+{44, 0, 32, 0, PCILIB_REGISTER_R, PCILIB_REGISTER_BANK1, "last_write_value", ""},
{0, 0, 0, 0, 0, 0, NULL, NULL}
};
diff --git a/pci.c b/pci.c
index 0299cf2..6221ddf 100644
--- a/pci.c
+++ b/pci.c
@@ -33,13 +33,17 @@ struct pcilib_s {
uintptr_t page_mask;
pci_board_info board_info;
pcilib_model_t model;
+
+ char *bar_space[PCILIB_MAX_BANKS];
+ int reg_bar_mapped;
pcilib_bar_t reg_bar;
- char *reg_space;
+// char *reg_space;
+ int data_bar_mapped;
pcilib_bar_t data_bar;
- char *data_space;
- size_t data_size;
+// char *data_space;
+// size_t data_size;
void *event_ctx;
@@ -72,6 +76,8 @@ pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
pcilib_t *ctx = malloc(sizeof(pcilib_t));
if (ctx) {
+ memset(ctx, 0, sizeof(pcilib_t));
+
ctx->handle = open(device, O_RDWR);
if (ctx->handle < 0) {
pcilib_error("Error opening device (%s)", device);
@@ -81,7 +87,6 @@ pcilib_t *pcilib_open(const char *device, pcilib_model_t model) {
ctx->page_mask = (uintptr_t)-1;
ctx->model = model;
- ctx->reg_space = NULL;
if (!model) model = pcilib_get_model(ctx);
api = pcilib_model[model].event_api;
@@ -116,6 +121,8 @@ pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
unsigned short vendor_id;
unsigned short device_id;
+ //return PCILIB_MODEL_PCI;
+
const pci_board_info *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_MODEL_PCI;
@@ -128,17 +135,17 @@ pcilib_model_t pcilib_get_model(pcilib_t *ctx) {
return ctx->model;
}
-static int pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
- int ret,i;
+static pcilib_bar_t pcilib_detect_bar(pcilib_t *ctx, uintptr_t addr, size_t size) {
+ pcilib_bar_t i;
const pci_board_info *board_info = pcilib_get_board_info(ctx);
- if (!board_info) return -1;
+ if (!board_info) return PCILIB_BAR_INVALID;
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
if ((addr >= board_info->bar_start[i])&&((board_info->bar_start[i] + board_info->bar_length[i]) >= (addr + size))) return i;
}
- return -1;
+ return PCILIB_BAR_INVALID;
}
static int pcilib_detect_address(pcilib_t *ctx, pcilib_bar_t *bar, uintptr_t *addr, size_t size) {
@@ -175,6 +182,8 @@ void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
const pci_board_info *board_info = pcilib_get_board_info(ctx);
if (!board_info) return NULL;
+ if (ctx->bar_space[bar]) return ctx->bar_space[bar];
+
ret = ioctl( ctx->handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );
if (ret) {
pcilib_error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar);
@@ -205,6 +214,8 @@ void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar) {
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data) {
const pci_board_info *board_info = pcilib_get_board_info(ctx);
if (!board_info) return;
+
+ if (ctx->bar_space[bar]) return;
munmap(data, board_info->bar_length[bar]);
#ifdef PCILIB_FILE_IO
@@ -227,7 +238,6 @@ int pcilib_read(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, vo
((uint32_t*)((char*)data+addr))[i] = 0x100 * i + 1;
}
*/
-
pcilib_memcpy(buf, data + addr, size);
pcilib_unmap_bar(ctx, bar, data);
@@ -249,7 +259,7 @@ int pcilib_write(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr, size_t size, v
}
-static pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
+pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank) {
pcilib_register_bank_t i;
pcilib_model_t model = pcilib_get_model(ctx);
pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
@@ -260,7 +270,7 @@ static pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_reg
return -1;
}
-static pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) {
+pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname) {
pcilib_register_bank_t i;
pcilib_register_bank_description_t *banks = pcilib_model[ctx->model].banks;
@@ -334,31 +344,48 @@ pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event) {
static int pcilib_map_register_space(pcilib_t *ctx) {
- if (!ctx->reg_space) {
+ int err;
+ pcilib_register_bank_t i;
+
+ if (!ctx->reg_bar_mapped) {
pcilib_model_t model = pcilib_get_model(ctx);
pcilib_register_bank_description_t *banks = pcilib_model[model].banks;
-
- if ((banks)&&(banks[0].access)) {
+
+ for (i = 0; ((banks)&&(banks[i].access)); i++) {
+// uint32_t buf[2];
void *reg_space;
-
- uintptr_t addr = banks[0].read_addr;
- pcilib_bar_t bar = PCILIB_BAR_DETECT;
-
- pcilib_detect_address(ctx, &bar, &addr, 1);
- reg_space = pcilib_map_bar(ctx, bar);
+ pcilib_bar_t bar = banks[i].bar;
- uint32_t buf[2];
- pcilib_memcpy(&buf, reg_space, 8);
+ if (bar == PCILIB_BAR_DETECT) {
+ uintptr_t addr = banks[0].read_addr;
- if (reg_space) {
- ctx->reg_bar = bar;
- ctx->reg_space = reg_space;
-
- return 0;
+ err = pcilib_detect_address(ctx, &bar, &addr, 1);
+ if (err) return err;
+
+ if (!ctx->bar_space[bar]) {
+ reg_space = pcilib_map_bar(ctx, bar);
+// pcilib_memcpy(&buf, reg_space, 8);
+
+ if (reg_space) {
+ ctx->bar_space[bar] = reg_space;
+ } else {
+ return PCILIB_ERROR_FAILED;
+ }
+ }
+ } else if (!ctx->bar_space[bar]) {
+ reg_space = pcilib_map_bar(ctx, bar);
+ if (reg_space) {
+ ctx->bar_space[bar] = reg_space;
+ } else {
+ return PCILIB_ERROR_FAILED;
+ }
+// pcilib_memcpy(&buf, reg_space, 8);
+
}
+ if (!i) ctx->reg_bar = bar;
}
- return PCILIB_ERROR_NOTFOUND;
+ ctx->reg_bar_mapped = 1;
}
return 0;
@@ -366,9 +393,9 @@ static int pcilib_map_register_space(pcilib_t *ctx) {
static int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
int err;
- int i;
+ pcilib_bar_t i;
- if (!ctx->data_space) {
+ if (!ctx->data_bar_mapped) {
const pci_board_info *board_info = pcilib_get_board_info(ctx);
if (!board_info) return PCILIB_ERROR_FAILED;
@@ -381,7 +408,7 @@ static int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
int data_bar = -1;
for (i = 0; i < PCILIB_MAX_BANKS; i++) {
- if ((i == ctx->reg_bar)||(!board_info->bar_length[i])) continue;
+ if ((ctx->bar_space[i])||(!board_info->bar_length[i])) continue;
if (addr) {
if (board_info->bar_start[i] == addr) {
@@ -406,18 +433,23 @@ static int pcilib_map_data_space(pcilib_t *ctx, uintptr_t addr) {
}
ctx->data_bar = data_bar;
- ctx->data_space = pcilib_map_bar(ctx, data_bar);
- ctx->data_size = board_info->bar_length[data_bar];
- if (!ctx->data_space) {
- pcilib_error("Unable to map the data space");
- return PCILIB_ERROR_FAILED;
+ if (!ctx->bar_space[data_bar]) {
+ char *data_space = pcilib_map_bar(ctx, data_bar);
+ if (data_space) ctx->bar_space[data_bar] = data_space;
+ else {
+ pcilib_error("Unable to map the data space");
+ return PCILIB_ERROR_FAILED;
+ }
}
+
+ ctx->data_bar_mapped = 0;
}
return 0;
}
+/*
static void pcilib_unmap_register_space(pcilib_t *ctx) {
if (ctx->reg_space) {
pcilib_unmap_bar(ctx, ctx->reg_bar, ctx->reg_space);
@@ -431,12 +463,31 @@ static void pcilib_unmap_data_space(pcilib_t *ctx) {
ctx->data_space = NULL;
}
}
+*/
-char *pcilib_resolve_register_address(pcilib_t *ctx, uintptr_t addr) {
- size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar];
- if (offset < ctx->board_info.bar_length[ctx->reg_bar]) {
- return ctx->reg_space + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask);
+char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr) {
+ if (bar == PCILIB_BAR_DETECT) {
+ // First checking the default register bar
+ size_t offset = addr - ctx->board_info.bar_start[ctx->reg_bar];
+ if ((addr > ctx->board_info.bar_start[ctx->reg_bar])&&(offset < ctx->board_info.bar_length[ctx->reg_bar])) {
+ return ctx->bar_space[ctx->reg_bar] + offset + (ctx->board_info.bar_start[ctx->reg_bar] & ctx->page_mask);
+ }
+
+ // Otherwise trying to detect
+ bar = pcilib_detect_bar(ctx, addr, 1);
+ if (bar != PCILIB_BAR_INVALID) {
+ size_t offset = addr - ctx->board_info.bar_start[bar];
+ if ((offset < ctx->board_info.bar_length[bar])&&(ctx->bar_space[bar])) {
+ return ctx->bar_space[bar] + offset + (ctx->board_info.bar_start[bar] & ctx->page_mask);
+ }
+ }
+ } else {
+ if (addr < ctx->board_info.bar_length[bar]) {
+ return ctx->bar_space[bar] + addr + (ctx->board_info.bar_start[bar] & ctx->page_mask);
+ }
+
}
+
return NULL;
}
@@ -449,20 +500,28 @@ char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size) {
return NULL;
}
- if (size) *size = ctx->data_size;
+ if (size) *size = ctx->board_info.bar_length[ctx->data_bar];
- return ctx->data_space + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask);
+ return ctx->bar_space[ctx->data_bar] + (ctx->board_info.bar_start[ctx->data_bar] & ctx->page_mask);
}
void pcilib_close(pcilib_t *ctx) {
+ pcilib_bar_t i;
+
if (ctx) {
pcilib_model_t model = pcilib_get_model(ctx);
pcilib_event_api_description_t *api = pcilib_model[model].event_api;
if ((api)&&(api->free)) api->free(ctx->event_ctx);
- if (ctx->data_space) pcilib_unmap_data_space(ctx);
- if (ctx->reg_space) pcilib_unmap_register_space(ctx);
+
+ for (i = 0; i < PCILIB_MAX_BANKS; i++) {
+ if (ctx->bar_space[i]) {
+ char *ptr = ctx->bar_space[i];
+ ctx->bar_space[i] = NULL;
+ pcilib_unmap_bar(ctx, i, ptr);
+ }
+ }
close(ctx->handle);
free(ctx);
diff --git a/pcilib.h b/pcilib.h
index f427b59..1df65f6 100644
--- a/pcilib.h
+++ b/pcilib.h
@@ -58,6 +58,9 @@ typedef enum {
} pcilib_event_data_type_t;
#define PCILIB_BAR_DETECT ((pcilib_bar_t)-1)
+#define PCILIB_BAR_INVALID ((pcilib_bar_t)-1)
+#define PCILIB_BAR0 0
+#define PCILIB_BAR1 1
#define PCILIB_REGISTER_INVALID ((pcilib_register_t)-1)
#define PCILIB_ADDRESS_INVALID ((uintptr_t)-1)
#define PCILIB_REGISTER_BANK_INVALID ((pcilib_register_bank_t)-1)
@@ -75,17 +78,20 @@ typedef enum {
typedef struct {
pcilib_register_bank_addr_t addr;
+
+ pcilib_bar_t bar; // optional
size_t size;
pcilib_register_protocol_t protocol;
- uintptr_t read_addr;
- uintptr_t write_addr;
+ uintptr_t read_addr; // or offset if bar specified
+ uintptr_t write_addr; // or offset if bar specified
uint8_t raw_endianess;
uint8_t access;
uint8_t endianess;
+ const char *format;
const char *name;
const char *description;
} pcilib_register_bank_description_t;
@@ -166,9 +172,11 @@ void pcilib_close(pcilib_t *ctx);
void *pcilib_map_bar(pcilib_t *ctx, pcilib_bar_t bar);
void pcilib_unmap_bar(pcilib_t *ctx, pcilib_bar_t bar, void *data);
-char *pcilib_resolve_register_address(pcilib_t *ctx, uintptr_t addr);
+char *pcilib_resolve_register_address(pcilib_t *ctx, pcilib_bar_t bar, uintptr_t addr);
char *pcilib_resolve_data_space(pcilib_t *ctx, uintptr_t addr, size_t *size);
+pcilib_register_bank_t pcilib_find_bank_by_addr(pcilib_t *ctx, pcilib_register_bank_addr_t bank);
+pcilib_register_bank_t pcilib_find_bank_by_name(pcilib_t *ctx, const char *bankname);
pcilib_register_bank_t pcilib_find_bank(pcilib_t *ctx, const char *bank);
pcilib_register_t pcilib_find_register(pcilib_t *ctx, const char *bank, const char *reg);
pcilib_event_t pcilib_find_event(pcilib_t *ctx, const char *event);