diff options
author | root <root@iss-tomyspiel-l> | 2011-06-16 01:26:14 +0200 |
---|---|---|
committer | root <root@iss-tomyspiel-l> | 2011-06-16 01:26:14 +0200 |
commit | c95df4d43738e1597c348bc7f98ff2902574d720 (patch) | |
tree | 1ecf978533c5cf81cc2052db696d2a2422de323e | |
parent | a6965d707c82317f31bb7ed8eabea05b7adb6775 (diff) | |
download | pcitool-c95df4d43738e1597c348bc7f98ff2902574d720.tar.gz pcitool-c95df4d43738e1597c348bc7f98ff2902574d720.tar.bz2 pcitool-c95df4d43738e1597c348bc7f98ff2902574d720.tar.xz pcitool-c95df4d43738e1597c348bc7f98ff2902574d720.zip |
Move to new FPGA design
-rw-r--r-- | cli.c | 40 | ||||
-rw-r--r-- | default.c | 5 | ||||
-rw-r--r-- | driver/pciDriver.h | 3 | ||||
-rw-r--r-- | ipecamera/image.c | 11 | ||||
-rw-r--r-- | ipecamera/model.c | 8 | ||||
-rw-r--r-- | ipecamera/model.h | 33 | ||||
-rw-r--r-- | pci.c | 147 | ||||
-rw-r--r-- | pcilib.h | 14 |
8 files changed, 179 insertions, 82 deletions
@@ -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"); } @@ -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} }; @@ -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); @@ -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); |