diff options
| -rw-r--r-- | .bzrignore | 4 | ||||
| -rw-r--r-- | Makefile | 10 | ||||
| -rw-r--r-- | cli.c | 579 | ||||
| -rw-r--r-- | common.mk | 4 | ||||
| -rw-r--r-- | driver/common.h | 30 | ||||
| -rw-r--r-- | driver/pciDriver.h | 32 | ||||
| -rw-r--r-- | ipecamera.c | 4 | ||||
| -rw-r--r-- | ipecamera.h | 70 | ||||
| -rw-r--r-- | pci.c | 514 | ||||
| -rw-r--r-- | pci.h | 81 | ||||
| -rw-r--r-- | tools.h | 5 | 
11 files changed, 838 insertions, 495 deletions
@@ -7,3 +7,7 @@ modules.order  Module.symvers  ./pci  .tmp_versions +cli.d +ipecamera.d +pci.d +tools.d @@ -10,14 +10,18 @@ all: $(BINARIES)  include common.mk -  ###############################################################  # Target definitions +OBJECTS = pci.o ipecamera.o tools.o + +libpcilib.so: $(OBJECTS) +	echo -e "LD \t$@" +	$(Q)$(CC) $(LDINC) $(LDFLAGS) $(CFLAGS) -shared -o $@ $(OBJECTS) -pci: pci.o tools.o +pci: cli.o libpcilib.so  	echo -e "LD \t$@" -	$(Q)$(CC) $(LDINC) $(LDFLAGS) $(CFLAGS) -o $@ $< tools.o +	$(Q)$(CC) $(LDINC) $(LDFLAGS) $(CFLAGS) -L. -lpcilib -o $@ $<  clean:  	@echo -e "CLEAN \t$(shell pwd)" @@ -0,0 +1,579 @@ +/******************************************************************* + * This is a test program for the IOctl interface of the  + * pciDriver. + *  + * $Revision: 1.3 $ + * $Date: 2006-11-17 18:49:01 $ + *  + *******************************************************************/ + +/******************************************************************* + * Change History: + *  + * $Log: not supported by cvs2svn $ + * Revision 1.2  2006/10/16 16:56:09  marcus + * Added nice comment at the start. + * + *******************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdarg.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <errno.h> +#include <alloca.h> + +#include <getopt.h> + +#include "pci.h" +#include "ipecamera.h" + + +/* defines */ +#define MAX_KBUF 14 +//#define BIGBUFSIZE (512*1024*1024) +#define BIGBUFSIZE (1024*1024) + + +#define DEFAULT_FPGA_DEVICE "/dev/fpga0" + +#define LINE_WIDTH 80 +#define SEPARATOR_WIDTH 2 +#define BLOCK_SEPARATOR_WIDTH 2 +#define BLOCK_SIZE 8 +#define BENCHMARK_ITERATIONS 128 + +//#define FILE_IO + +typedef enum { +    MODE_INVALID, +    MODE_INFO, +    MODE_LIST, +    MODE_BENCHMARK, +    MODE_READ, +    MODE_READ_REGISTER, +    MODE_WRITE, +    MODE_WRITE_REGISTER +} MODE; + +typedef enum { +    OPT_DEVICE = 'd', +    OPT_MODEL = 'm', +    OPT_BAR = 'b', +    OPT_ACCESS = 'a', +    OPT_SIZE = 's', +    OPT_INFO = 'i', +    OPT_BENCHMARK = 'p', +    OPT_LIST = 'l', +    OPT_READ = 'r', +    OPT_WRITE = 'w', +    OPT_HELP = 'h', +} OPTIONS; + +static struct option long_options[] = { +    {"device",			required_argument, 0, OPT_DEVICE }, +    {"model",			required_argument, 0, OPT_MODEL }, +    {"bar",			required_argument, 0, OPT_BAR }, +    {"access",			required_argument, 0, OPT_ACCESS }, +    {"size",			required_argument, 0, OPT_SIZE }, +    {"info",			no_argument, 0, OPT_INFO }, +    {"list",			no_argument, 0, OPT_LIST }, +    {"benchmark",		no_argument, 0, OPT_BENCHMARK }, +    {"read",			optional_argument, 0, OPT_READ }, +    {"write",			optional_argument, 0, OPT_WRITE }, +    {"help",			no_argument, 0, OPT_HELP }, +    { 0, 0, 0, 0 } +}; + + +void Usage(int argc, char *argv[], const char *format, ...) { +    if (format) { +	va_list ap; +     +	va_start(ap, format); +	printf("Error %i: ", errno); +	vprintf(format, ap); +	printf("\n"); +	va_end(ap); +     +        printf("\n"); +    } + + +    printf( +"Usage:\n" +" %s <mode> [options] [hex data]\n" +"  Modes:\n" +"	-i		- Device Info\n" +"	-l		- List Data Banks & Registers\n" +"	-p		- Performance Evaluation\n" +"	-r <addr|reg>	- Read Data/Register\n" +"	-w <addr|reg>	- Write Data/Register\n" +"	--help		- Help message\n" +"\n" +"  Addressing:\n" +"	-d <device>	- FPGA device (/dev/fpga0)\n" +"	-m <model>	- Memory model\n" +"	   pci		- Plain (default)\n" +"	   ipecamera	- IPE Camera\n" +"	-b <bank>	- Data bank (autodetected)\n" +"\n" +"  Options:\n" +"	-s <size>	- Number of words (default: 1)\n" +"	-a <bitness>	- Bits per word (default: 32)\n" +"\n\n", +argv[0]); + +    exit(0); +} + +void Error(const char *format, ...) { +    va_list ap; +     +    va_start(ap, format); +    printf("Error %i: ", errno); +    vprintf(format, ap); +    if (errno) printf("\n errno: %s", strerror(errno)); +    printf("\n\n"); +    va_end(ap); +     +    exit(-1); +} + + +void List(int handle, pcilib_model_t model) { +    int i; +    pcilib_register_t *registers; + +    const pci_board_info *board_info = pcilib_get_board_info(handle); + +    for (i = 0; i < PCILIB_MAX_BANKS; i++) { +	if (board_info->bar_length[i] > 0) { +	    printf(" BAR %d - ", i); + +	    switch ( board_info->bar_flags[i]&IORESOURCE_TYPE_BITS) { +		case IORESOURCE_IO:  printf(" IO"); break; +		case IORESOURCE_MEM: printf("MEM"); break; +		case IORESOURCE_IRQ: printf("IRQ"); break; +		case IORESOURCE_DMA: printf("DMA"); break; +	    } +	     +	    if (board_info->bar_flags[i]&IORESOURCE_MEM_64) printf("64"); +	    else printf("32"); +	     +	    printf(", Start: 0x%08lx, Length: 0x%8lx, Flags: 0x%08lx\n", board_info->bar_start[i], board_info->bar_length[i], board_info->bar_flags[i] ); +	} +    } +    printf("\n"); +     +    registers = pcilib_model_description[model].registers; +     +    if (registers) { +	printf("Registers: \n"); +	for (i = 0; registers[i].size; i++) { +	    const char *mode; +	    if (registers[i].mode == PCILIB_REGISTER_RW) mode = "RW"; +	    else if (registers[i].mode == PCILIB_REGISTER_R) mode = "R "; +	    else if (registers[i].mode == PCILIB_REGISTER_W) mode = " W"; +	    else mode = "  "; +	     +	    printf(" 0x%02x (%2i %s) %s", registers[i].id, registers[i].size, mode, registers[i].name); +	    if ((registers[i].description)&&(registers[i].description[0])) { +		printf(": %s", registers[i].description); +	    } +	    printf("\n"); + +	} +	printf("\n"); +    } +} + +void Info(int handle, pcilib_model_t model) { +    const pci_board_info *board_info = pcilib_get_board_info(handle); + +    printf("Vendor: %x, Device: %x, Interrupt Pin: %i, Interrupt Line: %i\n", board_info->vendor_id, board_info->device_id, board_info->interrupt_pin, board_info->interrupt_line); +    List(handle, model); +} + + +int Benchmark(int handle, int bar) { +    int err; +    int i, errors; +    void *data, *buf, *check; +    struct timeval start, end; +    unsigned long time; +    unsigned int size, max_size; +     +    const pci_board_info *board_info = pcilib_get_board_info(handle); +		 +    if (bar < 0) { +	unsigned long maxlength = 0; +	for (i = 0; i < PCILIB_MAX_BANKS; i++) { +	    if (board_info->bar_length[i] > maxlength) { +		maxlength = board_info->bar_length[i]; +		bar = i; +	    } +	} +	 +	if (bar < 0) Error("Data banks are not available"); +    } +     + +    max_size = board_info->bar_length[bar]; +     +    err = posix_memalign( (void**)&buf, 256, max_size ); +    if (!err) err = posix_memalign( (void**)&check, 256, max_size ); +    if ((err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size); + +    printf("Transfer time (Bank: %i):\n", bar);     +    data = pcilib_map_bar(handle, bar); +     +    for (size = 4 ; size < max_size; size *= 8) { +	gettimeofday(&start,NULL); +	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { +	    pcilib_memcpy(buf, data, size); +	} +	gettimeofday(&end,NULL); + +	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); +	printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); +	 +	fflush(0); + +	gettimeofday(&start,NULL); +	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { +	    pcilib_memcpy(data, buf, size); +	} +	gettimeofday(&end,NULL); + +	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); +	printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); +    } +     +    pcilib_unmap_bar(handle, bar, data); + +    printf("\n\nOpen-Transfer-Close time: \n"); +     +    for (size = 4 ; size < max_size; size *= 8) { +	gettimeofday(&start,NULL); +	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { +	    pcilib_read(buf, handle, bar, 0, size); +	} +	gettimeofday(&end,NULL); + +	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); +	printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); +	 +	fflush(0); + +	gettimeofday(&start,NULL); +	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { +	    pcilib_write(buf, handle, bar, 0, size); +	} +	gettimeofday(&end,NULL); + +	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); +	printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); + +	gettimeofday(&start,NULL); +	for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) { +	    pcilib_write(buf, handle, bar, 0, size); +	    pcilib_read(check, handle, bar, 0, size); +	    if (memcmp(buf, check, size)) ++errors; +	} +	gettimeofday(&end,NULL); + +	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); +	printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); +	if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS); +	printf("\n"); +    } +     +    printf("\n\n"); + +    free(check); +    free(buf); +} + + +int ReadData(int handle, int bar, unsigned long addr, int n, int access) { +    void *buf; +    int i, err; +    int size = n * abs(access); +    int block_width, blocks_per_line; +    int numbers_per_block, numbers_per_line;  +     +    numbers_per_block = BLOCK_SIZE / access; + +    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH); +    blocks_per_line = (LINE_WIDTH - 10) / (block_width +  BLOCK_SEPARATOR_WIDTH); +    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; +    numbers_per_line = blocks_per_line * numbers_per_block; + +//    buf = alloca(size); +    err = posix_memalign( (void**)&buf, 256, size ); + +    if ((err)||(!buf)) Error("Allocation of %i bytes of memory have failed", size); +     +    pcilib_read(buf, handle, bar, addr, size); + +    for (i = 0; i < n; i++) { +	if (i) { +	    if (i%numbers_per_line == 0) printf("\n"); +	    else { +		printf("%*s", SEPARATOR_WIDTH, ""); +		if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); +	    } +	} +	     +	if (i%numbers_per_line == 0) printf("%8lx:  ", addr + i * abs(access)); + +	switch (access) { +	    case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break; +	    case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break; +	    case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break; +	    case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break; +	} +    } +    printf("\n\n"); + +     +    free(buf); +} + +int ReadRegister(int handle, pcilib_model_t model, const char *reg) { +    int i; +     +    if (!reg) { +        pcilib_register_t *registers = pcilib_model_description[model].registers; +	 +	if (registers) { +	    printf("Registers:\n"); +	    for (i = 0; registers[i].size; i++) { +		if (registers[i].mode & PCILIB_REGISTER_R) { +	    	    printf(" %s = %i [%i]", registers[i].name, 0, registers[i].defvalue); +		} +		printf("\n"); +	    } +	} else { +	    printf("No registers"); +	} +	printf("\n"); +    } +} + +int ReadRegisterRange(int handle, pcilib_model_t model, int bar, unsigned long addr, int n, int access) { +} + +int WriteData(int handle, int bar, unsigned long addr, int n, int access, char ** data) { +    void *buf, *check; +    int res, i, err; +    int size = n * abs(access); +     +    err = posix_memalign( (void**)&buf, 256, size ); +    if (!err) err = posix_memalign( (void**)&check, 256, size ); +    if ((!err)||(!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); + +    for (i = 0; i < n; i++) { +	switch (access) { +	    case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break; +	    case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break; +	    case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break; +	    case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break; +	} +	 +	if (res != 1) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); +    } + +    pcilib_write(buf, handle, bar, addr, size); +    pcilib_read(check, handle, bar, addr, size); +     +    if (memcmp(buf, check, size)) { +	printf("Write failed: the data written and read differ, the foolowing is read back:\n"); +	ReadData(handle, bar, addr, n, access); +	exit(-1); +    } + +    free(check); +    free(buf); +} + +int WriteRegisterRange(int handle, pcilib_model_t model, int bar, unsigned long addr, int n, int access, char ** data) { +} + +int WriteRegister(int handle, pcilib_model_t model, const char *reg, char ** data) { +} + + +int main(int argc, char **argv) { +    unsigned char c; + +    pcilib_model_t model = (pcilib_model_t)-1; +    MODE mode = MODE_INVALID; +    const char *fpga_device = DEFAULT_FPGA_DEVICE; +    int bar = -1; +    const char *addr = NULL; +    unsigned long start = -1; +    int size = 1; +    int access = 4; +    int skip = 0; + +    int i; +    int handle; +     +    const char *reg = NULL; +     +    while ((c = getopt_long(argc, argv, "hilpr::w::d:b:a:s:", long_options, NULL)) != (unsigned char)-1) { +	extern int optind; +	switch (c) { +	    case OPT_HELP: +		Usage(argc, argv, NULL); +	    break; +	    case OPT_INFO: +		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + +		mode = MODE_INFO; +	    break; +	    case OPT_LIST: +		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + +		mode = MODE_LIST; +	    break; +	    case OPT_BENCHMARK: +		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + +		mode = MODE_BENCHMARK; +	    break; +	    case OPT_READ: +		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); +		 +		mode = MODE_READ; +		if (optarg) addr = optarg; +		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; +	    break; +	    case OPT_WRITE: +		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); + +		mode = MODE_WRITE; +		if (optarg) addr = optarg; +		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; +	    break; +	    case OPT_DEVICE: +		fpga_device = optarg; +	    break; +	    case OPT_MODEL: +		if (!strcasecmp(optarg, "pci")) model = PCILIB_MODEL_PCI; +		else if (!strcasecmp(optarg, "ipecamera")) model = PCILIB_MODEL_IPECAMERA; +		else Usage(argc, argv, "Invalid memory model (%s) is specified", optarg);\ +	    break; +	    case OPT_BAR: +		if ((sscanf(optarg,"%u", &bar) != 1)||(bar < 0)||(bar >= PCILIB_MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg); +	    break; +	    case OPT_ACCESS: +		if (sscanf(optarg, "%i", &access) != 1) access = 0; +		switch (access) { +		    case 8: access = 1; break; +		    case 16: access = 2; break; +		    case 32: access = 4; break; +		    case 64: access = 8; break; +		    default: Usage(argc, argv, "Invalid data width (%s) is specified", optarg); +		}	 +	    break; +	    case OPT_SIZE: +		if (sscanf(optarg, "%u", &size) != 1) +		    Usage(argc, argv, "Invalid size is specified (%s)", optarg); +	    break; +	    default: +		Usage(argc, argv, "Unknown option (%s)", argv[optind]); +	} +    } + +    if (mode == MODE_INVALID) { +	if (argc > 1) Usage(argc, argv, "Operation is not specified"); +	else Usage(argc, argv, NULL); +    } + +    pcilib_set_error_handler(&Error); + +    handle = pcilib_open(fpga_device); +    if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device); + +    if (model == (pcilib_model_t)-1) { +	model = pcilib_detect_model(handle); +    } + +    switch (mode) { +     case MODE_WRITE: +        if (!addr) Usage(argc, argv, "The address is not specified"); +        if ((argc - optind) != size) Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size); +     break; +     case MODE_READ: +        if (!addr) { +	    if (model == PCILIB_MODEL_PCI) { +		Usage(argc, argv, "The address is not specified"); +	    } else ++mode; +	} +     break; +     default: +        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied"); +    } +     + +    if (addr) { +	if (sscanf(addr, "%lx", &start) == 1) { +		// check if the address in the register range +	    pcilib_register_range_t *ranges =  pcilib_model_description[model].ranges; + +	    for (i = 0; ranges[i].start != ranges[i].end; i++)  +		if ((start >= ranges[i].start)&&(start <= ranges[i].end)) break; +		 +		// register access in plain mode +	    if (ranges[i].start != ranges[i].end) ++mode; +	} else { +	    if (pcilib_find_register(model, addr) >= 0) { +	        reg = addr; +		++mode; +	    } else { +	        Usage(argc, argv, "Invalid address (%s) is specified", addr); +	    } +	}  +    } + +     +    switch (mode) { +     case MODE_INFO: +        Info(handle, model); +     break; +     case MODE_LIST: +        List(handle, model); +     break; +     case MODE_BENCHMARK: +        Benchmark(handle, bar); +     break; +     case MODE_READ: +        if (addr) { +	    ReadData(handle, bar, start, size, access); +	} else { +	    Error("Address to read is not specified"); +	} +     break; +     case MODE_READ_REGISTER: +        if ((reg)||(!addr)) ReadRegister(handle, model, reg); +	else ReadRegisterRange(handle, model, bar, start, size, access); +     break; +     case MODE_WRITE: +	WriteData(handle, bar, start, size, access, argv + optind); +     break; +     case MODE_WRITE_REGISTER: +        if (reg) WriteRegister(handle, model, reg, argv + optind); +	else WriteRegisterRange(handle, model, bar, start, size, access, argv + optind); +     break; +    } + +    pcilib_close(handle); +} @@ -12,8 +12,8 @@ LIBDIR ?= $(ROOTDIR)  OBJDIR ?= $(ROOTDIR)  DEPENDDIR ?= $(ROOTDIR) -CXXFLAGS += $(addprefix -I ,$(INCDIR)) -CFLAGS += $(addprefix -I ,$(INCDIR)) +CXXFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC +CFLAGS += $(addprefix -I ,$(INCDIR)) -fPIC  # Source files in this directory  SRC = $(wildcard *.cpp) diff --git a/driver/common.h b/driver/common.h index c3f86a3..992f0ea 100644 --- a/driver/common.h +++ b/driver/common.h @@ -59,36 +59,6 @@ typedef struct  {  } pcidriver_privdata_t; -/* Identifies the mpRACE-1 boards */ -#define MPRACE1_VENDOR_ID 0x10b5 -#define MPRACE1_DEVICE_ID 0x9656 - -/* Identifies the PCI-X Test boards */ -#define PCIXTEST_VENDOR_ID 0x10dc -#define PCIXTEST_DEVICE_ID 0x0156 - -/* Identifies the PCIe-PLDA Test board */ -#define PCIEPLDA_VENDOR_ID 0x1556 -#define PCIEPLDA_DEVICE_ID 0x1100 - -/* Identifies the PCIe-ABB Test board */ -#define PCIEABB_VENDOR_ID 0x10dc -#define PCIEABB_DEVICE_ID 0x0153 - -/* Identifies the PCI-X PROGRAPE4 */ -#define PCIXPG4_VENDOR_ID 0x1679 -#define PCIXPG4_DEVICE_ID 0x0001 - -/* Identifies the PCI-64 PROGRAPE4 */ -#define PCI64PG4_VENDOR_ID 0x1679 -#define PCI64PG4_DEVICE_ID 0x0005 - -/* Identifies the PCI-E Xilinx ML605 */ -#define PCIE_XILINX_VENDOR_ID 0x10ee -#define PCIE_ML605_DEVICE_ID 0x04a0 - -/* Identifies the PCI-E IPE Camera */ -#define PCIE_IPECAMERA_DEVICE_ID 0x6018  /*************************************************************************/  /* Some nice defines that make code more readable */ diff --git a/driver/pciDriver.h b/driver/pciDriver.h index ed04d65..05326ab 100644 --- a/driver/pciDriver.h +++ b/driver/pciDriver.h @@ -58,6 +58,38 @@  #include <linux/ioctl.h> +/* Identifies the mpRACE-1 boards */ +#define MPRACE1_VENDOR_ID 0x10b5 +#define MPRACE1_DEVICE_ID 0x9656 + +/* Identifies the PCI-X Test boards */ +#define PCIXTEST_VENDOR_ID 0x10dc +#define PCIXTEST_DEVICE_ID 0x0156 + +/* Identifies the PCIe-PLDA Test board */ +#define PCIEPLDA_VENDOR_ID 0x1556 +#define PCIEPLDA_DEVICE_ID 0x1100 + +/* Identifies the PCIe-ABB Test board */ +#define PCIEABB_VENDOR_ID 0x10dc +#define PCIEABB_DEVICE_ID 0x0153 + +/* Identifies the PCI-X PROGRAPE4 */ +#define PCIXPG4_VENDOR_ID 0x1679 +#define PCIXPG4_DEVICE_ID 0x0001 + +/* Identifies the PCI-64 PROGRAPE4 */ +#define PCI64PG4_VENDOR_ID 0x1679 +#define PCI64PG4_DEVICE_ID 0x0005 + +/* Identifies the PCI-E Xilinx ML605 */ +#define PCIE_XILINX_VENDOR_ID 0x10ee +#define PCIE_ML605_DEVICE_ID 0x04a0 + +/* Identifies the PCI-E IPE Camera */ +#define PCIE_IPECAMERA_DEVICE_ID 0x6018 + +  /* Possible values for ioctl commands */  /* PCI mmap areas */ diff --git a/ipecamera.c b/ipecamera.c new file mode 100644 index 0000000..b51a2f8 --- /dev/null +++ b/ipecamera.c @@ -0,0 +1,4 @@ +#define _IPECAMERA_C +#include "ipecamera.h" + + diff --git a/ipecamera.h b/ipecamera.h new file mode 100644 index 0000000..51c99d9 --- /dev/null +++ b/ipecamera.h @@ -0,0 +1,70 @@ +#ifndef _IPECAMERA_H +#define _IPECAMERA_H + +#include <stdio.h> + +#include "pci.h" + +#define IPECAMERA_REGISTER_SPACE 0xfeaffc00 +#define IPECAMERA_REGISTER_WRITE (IPECAMERA_REGISTER_SPACE) +#define IPECAMERA_REGISTER_READ (IPECAMERA_REGISTER_SPACE + 4) + +#ifdef _IPECAMERA_C +pcilib_register_t ipecamera_registers[] = { +{1, 	16, 	1088, 	PCILIB_REGISTER_RW, "number_lines", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{3, 	16, 	0, 	PCILIB_REGISTER_RW, "start1", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{5, 	16, 	0, 	PCILIB_REGISTER_RW, "start2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{7, 	16, 	0, 	PCILIB_REGISTER_RW, "start3", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{9, 	16, 	0, 	PCILIB_REGISTER_RW, "start4", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{11,	16, 	0, 	PCILIB_REGISTER_RW, "start5", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{13, 	16, 	0, 	PCILIB_REGISTER_RW, "start6", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{15, 	16, 	0, 	PCILIB_REGISTER_RW, "start7", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{17, 	16, 	0, 	PCILIB_REGISTER_RW, "start8", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{19, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines1", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{21, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{23, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines3", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{25, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines4", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{27, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines5", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{29, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines6", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{31, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines7", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{33, 	16, 	0, 	PCILIB_REGISTER_RW, "number_lines8", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{35, 	16, 	0, 	PCILIB_REGISTER_RW, "sub_s", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{37, 	16, 	0, 	PCILIB_REGISTER_RW, "sub_a", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{39, 	1, 	1, 	PCILIB_REGISTER_RW, "color", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{40, 	2, 	0, 	PCILIB_REGISTER_RW, "image_flipping", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{41, 	2, 	0, 	PCILIB_REGISTER_RW, "exp_flags", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{42, 	24, 	1088, 	PCILIB_REGISTER_RW, "exp_time", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{45, 	24, 	1088, 	PCILIB_REGISTER_RW, "exp_step", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{48, 	24, 	1, 	PCILIB_REGISTER_RW, "exp_kp1", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{51, 	24, 	1, 	PCILIB_REGISTER_RW, "exp_kp2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{54, 	2, 	1, 	PCILIB_REGISTER_RW, "nr_slopes", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{55, 	8, 	1, 	PCILIB_REGISTER_RW, "exp_seq", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{56, 	24, 	1088, 	PCILIB_REGISTER_RW, "exp_time2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{59, 	24, 	1088, 	PCILIB_REGISTER_RW, "exp_step2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{68, 	2, 	1, 	PCILIB_REGISTER_RW, "nr_slopes2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{69, 	8, 	1, 	PCILIB_REGISTER_RW, "exp_seq2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{70, 	16, 	1, 	PCILIB_REGISTER_RW, "number_frames", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{72, 	2, 	0, 	PCILIB_REGISTER_RW, "output_mode", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{78, 	12, 	85, 	PCILIB_REGISTER_RW, "training_pattern", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{80, 	18, 	0x3FFFF,PCILIB_REGISTER_RW, "channel_en", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{89, 	8, 	96, 	PCILIB_REGISTER_RW, "vlow2", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{90, 	8, 	96, 	PCILIB_REGISTER_RW, "vlow3", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{100, 	14, 	16260, 	PCILIB_REGISTER_RW, "offset", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{102, 	2, 	0, 	PCILIB_REGISTER_RW, "pga", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{103, 	8, 	32, 	PCILIB_REGISTER_RW, "adc_gain", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{111, 	1, 	1, 	PCILIB_REGISTER_RW, "bit_mode", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{112, 	2, 	0, 	PCILIB_REGISTER_RW, "adc_resolution", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{126, 	16, 	0, 	PCILIB_REGISTER_RW, "temp", IPECAMERA_REGISTER_PROTOCOL, IPECAMERA_REGISTER_READ, IPECAMERA_REGISTER_WRITE, ""}, +{0,	0,	0,	0, NULL, 0, 0, 0, NULL} +}; + +pcilib_register_range_t ipecamera_register_range[] = { +    {0, 128}, {0,0} +}; + +#else +extern pcilib_register_t ipecamera_registers[]; +extern pcilib_register_range_t ipecamera_register_range[]; +#endif  + +#endif /* _IPECAMERA_H */ @@ -1,20 +1,4 @@ -/******************************************************************* - * This is a test program for the IOctl interface of the  - * pciDriver. - *  - * $Revision: 1.3 $ - * $Date: 2006-11-17 18:49:01 $ - *  - *******************************************************************/ - -/******************************************************************* - * Change History: - *  - * $Log: not supported by cvs2svn $ - * Revision 1.2  2006/10/16 16:56:09  marcus - * Added nice comment at the start. - * - *******************************************************************/ +#define _PCILIB_PCI_C  #include <stdio.h>  #include <string.h> @@ -26,125 +10,43 @@  #include <sys/ioctl.h>  #include <sys/mman.h>  #include <errno.h> -#include <alloca.h> - -#include <getopt.h> -  #include "driver/pciDriver.h"  #include "kernel.h"  #include "tools.h" -/* defines */ -#define MAX_KBUF 14 -//#define BIGBUFSIZE (512*1024*1024) -#define BIGBUFSIZE (1024*1024) - - -#define DEFAULT_FPGA_DEVICE "/dev/fpga0" -#define MAX_BANKS 6 - -#define LINE_WIDTH 80 -#define SEPARATOR_WIDTH 2 -#define BLOCK_SEPARATOR_WIDTH 2 -#define BLOCK_SIZE 8 -#define BENCHMARK_ITERATIONS 128 - -//#define FILE_IO - -typedef enum { -    MODE_INVALID, -    MODE_INFO, -    MODE_LIST, -    MODE_BENCHMARK, -    MODE_READ, -    MODE_WRITE -} MODE; - -typedef enum { -    OPT_DEVICE = 'd', -    OPT_BAR = 'b', -    OPT_ACCESS = 'a', -    OPT_SIZE = 's', -    OPT_INFO = 'i', -    OPT_BENCHMARK = 'p', -    OPT_LIST = 'l', -    OPT_READ = 'r', -    OPT_WRITE = 'w', -    OPT_HELP = 'h', -} OPTIONS; - -static struct option long_options[] = { -    {"device",			required_argument, 0, OPT_DEVICE }, -    {"bar",			required_argument, 0, OPT_BAR }, -    {"access",			required_argument, 0, OPT_ACCESS }, -    {"size",			required_argument, 0, OPT_SIZE }, -    {"info",			no_argument, 0, OPT_INFO }, -    {"list",			no_argument, 0, OPT_LIST }, -    {"benchmark",		no_argument, 0, OPT_BENCHMARK }, -    {"read",			optional_argument, 0, OPT_READ }, -    {"write",			optional_argument, 0, OPT_WRITE }, -    {"help",			no_argument, 0, OPT_HELP }, -    { 0, 0, 0, 0 } -}; +#include "pci.h" +#include "ipecamera.h" +static pci_board_info board_info; +static page_mask = -1; -void Usage(int argc, char *argv[], const char *format, ...) { -    if (format) { -	va_list ap; -     -	va_start(ap, format); -	printf("Error %i: ", errno); -	vprintf(format, ap); -	printf("\n"); -	va_end(ap); + +static void pcilib_print_error(const char *msg, ...) { +    va_list va; -        printf("\n"); -    } +    va_start(va, msg); +    vprintf(msg, va); +    va_end(va); +} +static void (*Error)(const char *msg, ...) = pcilib_print_error; -    printf( -"Usage:\n" -" %s <mode> [options] [hex data]\n" -"  Modes:\n" -"	-i		- Device Info\n" -"	-l		- List Data Banks\n" -"	-p		- Performance Evaluation\n" -"	-r <addr>	- Read Data\n" -"	-w <addr>	- Write Data\n" -"	--help		- Help message\n" -"\n" -"  Addressing:\n" -"	-d <device>	- FPGA device (/dev/fpga0)\n" -"	-b <bank>	- Data bank (autodetected)\n" -"\n" -"  Options:\n" -"	-s <size>	- Number of words (default: 1)\n" -"	-a <bitness>	- Bits per word (default: 32)\n" -"\n\n", -argv[0]); - -    exit(0); +int pcilib_open(const char *device) { +    int handle = open(device, O_RDWR); +    return handle;  } -void Error(const char *format, ...) { -    va_list ap; -     -    va_start(ap, format); -    printf("Error %i: ", errno); -    vprintf(format, ap); -    if (errno) printf("\n errno: %s", strerror(errno)); -    printf("\n\n"); -    va_end(ap); -     -    exit(-1); +void pcilib_close(int handle) { +    close(handle);  } -static pci_board_info board_info; -static page_mask = -1; +int pcilib_set_error_handler(void (*err)(const char *msg, ...)) { +    Error = err; +} -void GetBoardInfo(int handle) { +const pci_board_info *pcilib_get_board_info(int handle) {      int ret;      if (page_mask < 0) { @@ -153,58 +55,39 @@ void GetBoardInfo(int handle) {  	page_mask = get_page_mask();      } +     +    return &board_info;  } -void List(int handle) { -    int i; -    GetBoardInfo(handle); - -    for (i = 0; i < MAX_BANKS; i++) { -	if (board_info.bar_length[i] > 0) { -	    printf(" BAR %d - ", i); - -	    switch ( board_info.bar_flags[i]&IORESOURCE_TYPE_BITS) { -		case IORESOURCE_IO:  printf(" IO"); break; -		case IORESOURCE_MEM: printf("MEM"); break; -		case IORESOURCE_IRQ: printf("IRQ"); break; -		case IORESOURCE_DMA: printf("DMA"); break; -	    } -	     -	    if (board_info.bar_flags[i]&IORESOURCE_MEM_64) printf("64"); -	    else printf("32"); -	     -	    printf(", Start: 0x%08lx, Length: 0x% 8lx, Flags: 0x%08lx\n", board_info.bar_start[i], board_info.bar_length[i], board_info.bar_flags[i] ); -	} -    } -} +pcilib_model_t pcilib_detect_model(int handle) { +	unsigned short vendor_id; +	unsigned short device_id; -void Info(int handle) { -    GetBoardInfo(handle); +    pcilib_get_board_info(handle); -    printf("Vendor: %x, Device: %x, Interrupt Pin: %i, Interrupt Line: %i\n", board_info.vendor_id, board_info.device_id, board_info.interrupt_pin, board_info.interrupt_line); -    List(handle); +    if ((board_info.vendor_id == PCIE_XILINX_VENDOR_ID)&&(board_info.device_id ==  PCIE_IPECAMERA_DEVICE_ID)) return PCILIB_MODEL_IPECAMERA; +    return PCILIB_MODEL_PCI;  } - -int DetectBar(int handle, unsigned long addr, int size) { +static int pcilib_detect_bar(int handle, unsigned long addr, int size) {      int ret,i; -    GetBoardInfo(handle); +    pcilib_get_board_info(handle); -    for (i = 0; i < MAX_BANKS; i++) { +    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;  } -void *DetectAddress(int handle, int *bar, unsigned long *addr, int size) { +static void *pcilib_detect_address(int handle, int *bar, unsigned long *addr, int size) {      if (*bar < 0) { -	*bar = DetectBar(handle, *addr, size); +	*bar = pcilib_detect_bar(handle, *addr, size);  	if (*bar < 0) Error("The requested data block at address 0x%x with size 0x%x does not belongs to any available memory bank", *addr, size);      } else { -	GetBoardInfo(handle); +	pcilib_get_board_info(handle);  	if ((*addr < board_info.bar_start[*bar])||((board_info.bar_start[*bar] + board_info.bar_length[*bar]) < (((uintptr_t)*addr) + size))) {  	    if ((board_info.bar_length[*bar]) >= (((uintptr_t)*addr) + size))  @@ -223,11 +106,11 @@ void *DetectAddress(int handle, int *bar, unsigned long *addr, int size) {  int file_io_handle;  #endif /* FILE_IO */ -void *MapBar(int handle, int bar) { +void *pcilib_map_bar(int handle, int bar) {      void *res;      int ret;  -    GetBoardInfo(handle); +    pcilib_get_board_info(handle);      ret = ioctl( handle, PCIDRIVER_IOC_MMAP_MODE, PCIDRIVER_MMAP_PCI );      if (ret) Error("PCIDRIVER_IOC_MMAP_MODE ioctl have failed", bar); @@ -247,16 +130,14 @@ void *MapBar(int handle, int bar) {      return res;  } -void UnmapBar(int handle, int bar, void *data) { +void pcilib_unmap_bar(int handle, int bar, void *data) {      munmap(data, board_info.bar_length[bar]);  #ifdef FILE_IO      close(file_io_handle);  #endif  } - - -int Read(void *buf, int handle, int bar, unsigned long addr, int size) { +int pcilib_read(void *buf, int handle, int bar, unsigned long addr, int size) {      int i;      void *data;      unsigned int offset; @@ -264,8 +145,8 @@ int Read(void *buf, int handle, int bar, unsigned long addr, int size) { -    DetectAddress(handle, &bar, &addr, size); -    data = MapBar(handle, bar); +    pcilib_detect_address(handle, &bar, &addr, size); +    data = pcilib_map_bar(handle, bar);  /*      for (i = 0; i < size/4; i++)  { @@ -273,322 +154,37 @@ int Read(void *buf, int handle, int bar, unsigned long addr, int size) {      }  */ -    memcpy0(buf, data + addr, size); +    pcilib_memcpy(buf, data + addr, size); -    UnmapBar(handle, bar, data);     +    pcilib_unmap_bar(handle, bar, data);      } -int Write(void *buf, int handle, int bar, unsigned long addr, int size) { +int pcilib_write(void *buf, int handle, int bar, unsigned long addr, int size) {      int i;      void *data;      unsigned int offset;      char local_buf[size]; -    DetectAddress(handle, &bar, &addr, size); -    data = MapBar(handle, bar); +    pcilib_detect_address(handle, &bar, &addr, size); +    data = pcilib_map_bar(handle, bar); -    memcpy0(data + addr, buf, size); +    pcilib_memcpy(data + addr, buf, size); -    UnmapBar(handle, bar, data);     +    pcilib_unmap_bar(handle, bar, data);      } -int Benchmark(int handle, int bar) { -    int i, errors; -    void *data, *buf, *check; -    struct timeval start, end; -    unsigned long time; -    unsigned int size, max_size; -     -    GetBoardInfo(handle); -		 -    if (bar < 0) { -	for (i = 0; i < MAX_BANKS; i++) { -	    if (board_info.bar_length[i] > 0) { -		bar = i; -		break; -	    } -	} -	 -	if (bar < 0) Error("Data banks are not available"); -    } -     - -    max_size = board_info.bar_length[bar]; -     -    posix_memalign( (void**)&buf, 256, max_size ); -    posix_memalign( (void**)&check, 256, max_size ); -    if ((!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", max_size); - -    printf("Transfer time:\n");     -    data = MapBar(handle, bar); -     -    for (size = 4 ; size < max_size; size *= 8) { -	gettimeofday(&start,NULL); -	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { -	    memcpy0(buf, data, size); -	} -	gettimeofday(&end,NULL); - -	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); -	printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); -	 -	fflush(0); - -	gettimeofday(&start,NULL); -	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { -	    memcpy0(data, buf, size); -	} -	gettimeofday(&end,NULL); - -	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); -	printf(", write: %8.2lf MB/s\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); -    } -     -    UnmapBar(handle, bar, data); - -    printf("\n\nOpen-Transfer-Close time: \n"); -     -    for (size = 4 ; size < max_size; size *= 8) { -	gettimeofday(&start,NULL); -	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { -	    Read(buf, handle, bar, 0, size); -	} -	gettimeofday(&end,NULL); - -	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); -	printf("%8i bytes - read: %8.2lf MB/s", size, 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); -	 -	fflush(0); - -	gettimeofday(&start,NULL); -	for (i = 0; i < BENCHMARK_ITERATIONS; i++) { -	    Write(buf, handle, bar, 0, size); -	} -	gettimeofday(&end,NULL); - -	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); -	printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); - -	gettimeofday(&start,NULL); -	for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) { -	    Write(buf, handle, bar, 0, size); -	    Read(check, handle, bar, 0, size); -	    if (memcmp(buf, check, size)) ++errors; -	} -	gettimeofday(&end,NULL); - -	time = (end.tv_sec - start.tv_sec)*1000000 + (end.tv_usec - start.tv_usec); -	printf(", write-verify: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024)); -	if (errors) printf(", errors: %u of %u", errors, BENCHMARK_ITERATIONS); -	printf("\n"); -    } -     -    printf("\n\n"); - -    free(check); -    free(buf); -} - -int ReadData(int handle, int bar, unsigned long addr, int n, int access) { -    void *buf; +int pcilib_find_register(pcilib_model_t model, const char *reg) {      int i; -    int size = n * abs(access); -    int block_width, blocks_per_line; -    int numbers_per_block, numbers_per_line;  -     -    numbers_per_block = BLOCK_SIZE / access; - -    block_width = numbers_per_block * ((access * 2) +  SEPARATOR_WIDTH); -    blocks_per_line = (LINE_WIDTH - 10) / (block_width +  BLOCK_SEPARATOR_WIDTH); -    if ((blocks_per_line > 1)&&(blocks_per_line % 2)) --blocks_per_line; -    numbers_per_line = blocks_per_line * numbers_per_block; - -//    buf = alloca(size); -    posix_memalign( (void**)&buf, 256, size ); - -    if (!buf) Error("Allocation of %i bytes of memory have failed", size); -     -    Read(buf, handle, bar, addr, size); - -    for (i = 0; i < n; i++) { -	if (i) { -	    if (i%numbers_per_line == 0) printf("\n"); -	    else { -		printf("%*s", SEPARATOR_WIDTH, ""); -		if (i%numbers_per_block == 0) printf("%*s", BLOCK_SEPARATOR_WIDTH, ""); -	    } -	} -	     -	if (i%numbers_per_line == 0) printf("%8lx:  ", addr + i * abs(access)); - -	switch (access) { -	    case 1: printf("%0*hhx", access * 2, ((uint8_t*)buf)[i]); break; -	    case 2: printf("%0*hx", access * 2, ((uint16_t*)buf)[i]); break; -	    case 4: printf("%0*x", access * 2, ((uint32_t*)buf)[i]); break; -	    case 8: printf("%0*lx", access * 2, ((uint64_t*)buf)[i]); break; -	} -    } -    printf("\n\n"); - -     -    free(buf); -} - -int WriteData(int handle, int bar, unsigned long addr, int n, int access, char ** data) { -    void *buf, *check; -    int res, i; -    int size = n * abs(access); -     -    posix_memalign( (void**)&buf, 256, size ); -    posix_memalign( (void**)&check, 256, size ); -    if ((!buf)||(!check)) Error("Allocation of %i bytes of memory have failed", size); - -    for (i = 0; i < n; i++) { -	switch (access) { -	    case 1: res = sscanf(data[i], "%hhx", ((uint8_t*)buf)+i); break; -	    case 2: res = sscanf(data[i], "%hx", ((uint16_t*)buf)+i); break; -	    case 4: res = sscanf(data[i], "%x", ((uint32_t*)buf)+i); break; -	    case 8: res = sscanf(data[i], "%lx", ((uint64_t*)buf)+i); break; -	} -	 -	if (res != 1) Error("Can't parse data value at poition %i, (%s) is not valid hex number", i, data[i]); -    } - -    Write(buf, handle, bar, addr, size); -//    ReadData(handle, bar, addr, n, access); -    Read(check, handle, bar, addr, size); -     -    if (memcmp(buf, check, size)) { -	printf("Write failed: the data written and read differ, the foolowing is read back:\n"); -	ReadData(handle, bar, addr, n, access); -	exit(-1); -    } - -    free(check); -    free(buf); -} - - -int main(int argc, char **argv) { -    unsigned char c; - -    MODE mode = MODE_INVALID; -    const char *fpga_device = DEFAULT_FPGA_DEVICE; -    int bar = -1; -    const char *addr = NULL; -    unsigned long start = -1; -    int size = 1; -    int access = 4; -    int skip = 0; - -    int handle; +    pcilib_register_t *registers =  pcilib_model_description[model].registers; -    while ((c = getopt_long(argc, argv, "hilpr::w::d:b:a:s:", long_options, NULL)) != (unsigned char)-1) { -	extern int optind; -	switch (c) { -	    case OPT_HELP: -		Usage(argc, argv, NULL); -	    break; -	    case OPT_INFO: -		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - -		mode = MODE_INFO; -	    break; -	    case OPT_LIST: -		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - -		mode = MODE_LIST; -	    break; -	    case OPT_BENCHMARK: -		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - -		mode = MODE_BENCHMARK; -	    break; -	    case OPT_READ: -		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); -		 -		mode = MODE_READ; -		if (optarg) addr = optarg; -		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; -	    break; -	    case OPT_WRITE: -		if (mode != MODE_INVALID) Usage(argc, argv, "Multiple operations are not supported"); - -		mode = MODE_WRITE; -		if (optarg) addr = optarg; -		else if ((optind < argc)&&(argv[optind][0] != '-')) addr = argv[optind++]; -	    break; -	    case OPT_DEVICE: -		fpga_device = optarg; -	    break; -	    case OPT_BAR: -		if ((sscanf(optarg,"%u", &bar) != 1)||(bar < 0)||(bar >= MAX_BANKS)) Usage(argc, argv, "Invalid data bank (%s) is specified", optarg); -	    break; -	    case OPT_ACCESS: -		if (sscanf(optarg, "%i", &access) != 1) access = 0; -		switch (access) { -		    case 8: access = 1; break; -		    case 16: access = 2; break; -		    case 32: access = 4; break; -		    case 64: access = 8; break; -		    default: Usage(argc, argv, "Invalid data width (%s) is specified", optarg); -		}	 -	    break; -	    case OPT_SIZE: -		if (sscanf(optarg, "%u", &size) != 1) -		    Usage(argc, argv, "Invalid size is specified (%s)", optarg); -	    break; -	    default: -		Usage(argc, argv, "Unknown option (%s)", argv[optind]); -	} -    } - -    if (mode == MODE_INVALID) { -	if (argc > 1) Usage(argc, argv, "Operation is not specified"); -	else Usage(argc, argv, NULL); -    } - -    if (addr) { -	if (sscanf(addr, "%lx", &start) != 1) Usage(argc, argv, "Invalid address (%s) is specified", addr); +    for (i = 0; registers[i].size; i++) { +	if (!strcasecmp(registers[i].name, reg)) return i;      } -    switch (mode) { -     case MODE_WRITE: -        if ((argc - optind) != size) Usage(argc, argv, "The %i data values is specified, but %i required", argc - optind, size); -     case MODE_READ: -        if (!addr) Usage(argc, argv, "The address is not specified"); -     break; -     default: -        if (argc > optind) Usage(argc, argv, "Invalid non-option parameters are supplied"); -    } +    return -1; +}; -    handle = open(fpga_device, O_RDWR); -    if (handle < 0) Error("Failed to open FPGA device: %s", fpga_device); -     -    switch (mode) { -     case MODE_INFO: -        Info(handle); -     break; -     case MODE_LIST: -        List(handle); -     break; -     case MODE_BENCHMARK: -        Benchmark(handle, bar); -     break; -     case MODE_READ: -        if (addr) { -	    ReadData(handle, bar, start, size, access); -	} else { -	    Error("Address to read is not specified"); -	} -     break; -     case MODE_WRITE: -	WriteData(handle, bar, start, size, access, argv + optind); -     break; -    } -    close(handle); -} @@ -0,0 +1,81 @@ +#ifndef _PCITOOL_PCI_H +#define _PCITOOL_PCI_H + +#define PCILIB_MAX_BANKS 6 + +#include <stdint.h> + +#include "driver/pciDriver.h" +#include "kernel.h" + +#define pcilib_memcpy memcpy32 + +typedef enum { +    PCILIB_MODEL_PCI, +    PCILIB_MODEL_IPECAMERA +} pcilib_model_t; + + +typedef enum { +    PCILIB_REGISTER_R = 1, +    PCILIB_REGISTER_W = 2, +    PCILIB_REGISTER_RW = 3 +} pcilib_register_mode_t; + +typedef enum { +    IPECAMERA_REGISTER_PROTOCOL +} pcilib_register_protocol_t; + +typedef struct { +    uint8_t id; +    uint8_t size; +    uint32_t defvalue; +    pcilib_register_mode_t mode; + +    const char *name; +     +    pcilib_register_protocol_t protocol; +    uint64_t read_addr; +    uint64_t write_addr; + +    const char *description; +} pcilib_register_t; + +typedef struct { +    uint32_t start; +    uint32_t end; +} pcilib_register_range_t; + +#include "ipecamera.h" + +typedef struct { +    pcilib_register_t *registers; +    pcilib_register_range_t *ranges; +} pcilib_model_description_t; + +#ifdef _PCILIB_PCI_C +pcilib_model_description_t pcilib_model_description[2] = { +    { NULL, NULL }, +    { ipecamera_registers, ipecamera_register_range } +}; +#else +extern pcilib_model_description_t pcilib_model_description[]; +#endif /* _PCILIB_PCI_C */ + + +int pcilib_open(const char *device); +void pcilib_close(int handle); + +int pcilib_set_error_handler(void (*err)(const char *msg, ...)); + +const pci_board_info *pcilib_get_board_info(int handle); +pcilib_model_t pcilib_detect_model(int handle); +void *pcilib_map_bar(int handle, int bar); +void pcilib_unmap_bar(int handle, int bar, void *data); + +int pcilib_read(void *buf, int handle, int bar, unsigned long addr, int size); +int pcilib_write(void *buf, int handle, int bar, unsigned long addr, int size); + +int pcilib_find_register(pcilib_model_t model, const char *reg); + +#endif /* _PCITOOL_PCI_H */ @@ -1,6 +1,9 @@ -#define memcpy0 memcpy32 +#ifndef _PCITOOL_TOOLS_H +#define _PCITOOL_TOOLS_H  void * memcpy8(void * dst, void const * src, size_t len);  void * memcpy32(void * dst, void const * src, size_t len);  void * memcpy64(void * dst, void const * src, size_t len);  int get_page_mask(); + +#endif /* _PCITOOL_TOOS_H */  | 
