Forráskód Böngészése

Initial support for registers, infrastructure only

Suren A. Chilingaryan 13 éve
szülő
commit
c428e3496a
11 módosított fájl, 838 hozzáadás és 495 törlés
  1. 4 0
      .bzrignore
  2. 7 3
      Makefile
  3. 579 0
      cli.c
  4. 2 2
      common.mk
  5. 0 30
      driver/common.h
  6. 32 0
      driver/pciDriver.h
  7. 4 0
      ipecamera.c
  8. 70 0
      ipecamera.h
  9. 55 459
      pci.c
  10. 81 0
      pci.h
  11. 4 1
      tools.h

+ 4 - 0
.bzrignore

@@ -7,3 +7,7 @@ modules.order
 Module.symvers
 ./pci
 .tmp_versions
+cli.d
+ipecamera.d
+pci.d
+tools.d

+ 7 - 3
Makefile

@@ -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)"

+ 579 - 0
cli.c

@@ -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);
+}

+ 2 - 2
common.mk

@@ -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)

+ 0 - 30
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 */

+ 32 - 0
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 */

+ 4 - 0
ipecamera.c

@@ -0,0 +1,4 @@
+#define _IPECAMERA_C
+#include "ipecamera.h"
+
+

+ 70 - 0
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 */

+ 55 - 459
pci.c

@@ -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);
-}

+ 81 - 0
pci.h

@@ -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 */

+ 4 - 1
tools.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 */