Suren A. Chilingaryan пре 13 година
родитељ
комит
813c7abf04
6 измењених фајлова са 143 додато и 15 уклоњено
  1. 1 0
      driver/ioctl.c
  2. 1 0
      driver/pciDriver.h
  3. 81 0
      kernel.h
  4. 40 15
      pci.c
  5. 19 0
      tools.c
  6. 1 0
      tools.h

+ 1 - 0
driver/ioctl.c

@@ -160,6 +160,7 @@ static int ioctl_pci_info(pcidriver_privdata_t *privdata, unsigned long arg)
 	for (bar = 0; bar < 6; bar++) {
 		pci_info.bar_start[bar] = pci_resource_start(privdata->pdev, bar);
 		pci_info.bar_length[bar] = pci_resource_len(privdata->pdev, bar);
+		pci_info.bar_flags[bar] = pci_resource_flags(privdata->pdev, bar);
 	}
 
 	WRITE_TO_USER(pci_board_info, pci_info);

+ 1 - 0
driver/pciDriver.h

@@ -142,6 +142,7 @@ typedef struct {
 	unsigned int irq;
 	unsigned long bar_start[6];
 	unsigned long bar_length[6];
+	unsigned long bar_flags[6];
 } pci_board_info;
 
 

+ 81 - 0
kernel.h

@@ -0,0 +1,81 @@
+/*
+ * Extract from kernel headers
+ * iomap.h
+ */
+
+/*
+ * IO resources have these defined flags.
+ */
+#define IORESOURCE_BITS		0x000000ff	/* Bus-specific bits */
+
+#define IORESOURCE_TYPE_BITS	0x00000f00	/* Resource type */
+#define IORESOURCE_IO		0x00000100
+#define IORESOURCE_MEM		0x00000200
+#define IORESOURCE_IRQ		0x00000400
+#define IORESOURCE_DMA		0x00000800
+
+#define IORESOURCE_PREFETCH	0x00001000	/* No side effects */
+#define IORESOURCE_READONLY	0x00002000
+#define IORESOURCE_CACHEABLE	0x00004000
+#define IORESOURCE_RANGELENGTH	0x00008000
+#define IORESOURCE_SHADOWABLE	0x00010000
+
+#define IORESOURCE_SIZEALIGN	0x00020000	/* size indicates alignment */
+#define IORESOURCE_STARTALIGN	0x00040000	/* start field is alignment */
+
+#define IORESOURCE_MEM_64	0x00100000
+
+#define IORESOURCE_EXCLUSIVE	0x08000000	/* Userland may not map this resource */
+#define IORESOURCE_DISABLED	0x10000000
+#define IORESOURCE_UNSET	0x20000000
+#define IORESOURCE_AUTO		0x40000000
+#define IORESOURCE_BUSY		0x80000000	/* Driver has marked this resource busy */
+
+/* PnP IRQ specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IRQ_HIGHEDGE		(1<<0)
+#define IORESOURCE_IRQ_LOWEDGE		(1<<1)
+#define IORESOURCE_IRQ_HIGHLEVEL	(1<<2)
+#define IORESOURCE_IRQ_LOWLEVEL		(1<<3)
+#define IORESOURCE_IRQ_SHAREABLE	(1<<4)
+#define IORESOURCE_IRQ_OPTIONAL 	(1<<5)
+
+/* PnP DMA specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_DMA_TYPE_MASK	(3<<0)
+#define IORESOURCE_DMA_8BIT		(0<<0)
+#define IORESOURCE_DMA_8AND16BIT	(1<<0)
+#define IORESOURCE_DMA_16BIT		(2<<0)
+
+#define IORESOURCE_DMA_MASTER		(1<<2)
+#define IORESOURCE_DMA_BYTE		(1<<3)
+#define IORESOURCE_DMA_WORD		(1<<4)
+
+#define IORESOURCE_DMA_SPEED_MASK	(3<<6)
+#define IORESOURCE_DMA_COMPATIBLE	(0<<6)
+#define IORESOURCE_DMA_TYPEA		(1<<6)
+#define IORESOURCE_DMA_TYPEB		(2<<6)
+#define IORESOURCE_DMA_TYPEF		(3<<6)
+
+/* PnP memory I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_MEM_WRITEABLE	(1<<0)	/* dup: IORESOURCE_READONLY */
+#define IORESOURCE_MEM_CACHEABLE	(1<<1)	/* dup: IORESOURCE_CACHEABLE */
+#define IORESOURCE_MEM_RANGELENGTH	(1<<2)	/* dup: IORESOURCE_RANGELENGTH */
+#define IORESOURCE_MEM_TYPE_MASK	(3<<3)
+#define IORESOURCE_MEM_8BIT		(0<<3)
+#define IORESOURCE_MEM_16BIT		(1<<3)
+#define IORESOURCE_MEM_8AND16BIT	(2<<3)
+#define IORESOURCE_MEM_32BIT		(3<<3)
+#define IORESOURCE_MEM_SHADOWABLE	(1<<5)	/* dup: IORESOURCE_SHADOWABLE */
+#define IORESOURCE_MEM_EXPANSIONROM	(1<<6)
+
+/* PnP I/O specific bits (IORESOURCE_BITS) */
+#define IORESOURCE_IO_16BIT_ADDR	(1<<0)
+#define IORESOURCE_IO_FIXED		(1<<1)
+
+/* PCI ROM control bits (IORESOURCE_BITS) */
+#define IORESOURCE_ROM_ENABLE		(1<<0)	/* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */
+#define IORESOURCE_ROM_SHADOW		(1<<1)	/* ROM is copy at C000:0 */
+#define IORESOURCE_ROM_COPY		(1<<2)	/* ROM is alloc'd copy, resource field overlaid */
+#define IORESOURCE_ROM_BIOS_COPY	(1<<3)	/* ROM is BIOS copy, resource field overlaid */
+
+/* PCI control bits.  Shares IORESOURCE_BITS with above PCI ROM.  */
+#define IORESOURCE_PCI_FIXED		(1<<4)	/* Do not move resource */

+ 40 - 15
pci.c

@@ -30,8 +30,10 @@
 
 #include <getopt.h>
 
+
 #include "driver/pciDriver.h"
 
+#include "kernel.h"
 #include "tools.h"
 
 /* defines */
@@ -160,7 +162,19 @@ void List(int handle) {
 
     for (i = 0; i < MAX_BANKS; i++) {
 	if (board_info.bar_length[i] > 0) {
-	    printf(" BAR %d - Start: 0x%x, Length: 0x%x\n", i, board_info.bar_start[i], board_info.bar_length[i] );
+	    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] );
 	}
     }
 }
@@ -168,7 +182,7 @@ void List(int handle) {
 void Info(int handle) {
     GetBoardInfo(handle);
 
-    printf("Vendor: %lx, Device: %lx, Interrupt Pin: %i, Interrupt Line: %i\n", board_info.vendor_id, board_info.device_id, board_info.interrupt_pin, board_info.interrupt_line);
+    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);
 }
 
@@ -281,7 +295,7 @@ int Write(void *buf, int handle, int bar, unsigned long addr, int size) {
 
 
 int Benchmark(int handle, int bar) {
-    int i;
+    int i, errors;
     void *data, *buf, *check;
     struct timeval start, end;
     unsigned long time;
@@ -358,15 +372,17 @@ int Benchmark(int handle, int bar) {
 	printf(", write: %8.2lf MB/s", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024));
 
 	gettimeofday(&start,NULL);
-	for (i = 0; i < BENCHMARK_ITERATIONS; i++) {
+	for (i = 0, errors = 0; i < BENCHMARK_ITERATIONS; i++) {
 	    Write(buf, handle, bar, 0, size);
 	    Read(check, handle, bar, 0, size);
-	    memcmp(buf, check, 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\n", 1000000. * size * BENCHMARK_ITERATIONS / (time * 1024 * 1024));
+	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");
@@ -397,16 +413,21 @@ int ReadData(int handle, int bar, unsigned long addr, int n, int access) {
     Read(buf, handle, bar, addr, size);
 
     for (i = 0; i < n; i++) {
-	if ((i)&&(i%numbers_per_line == 0)) printf("\n");
-	else if ((i)&&(i%numbers_per_block == 0)) printf("%*s", BLOCK_SEPARATOR_WIDTH, "");
-
-	if (i%numbers_per_line == 0) printf("%8lx: ", addr + i * abs(access));
+	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("% *hhx", access * 2 +  SEPARATOR_WIDTH, ((uint8_t*)buf)[i]); break;
-	    case 2: printf("% *hx", access * 2 +  SEPARATOR_WIDTH, ((uint16_t*)buf)[i]); break;
-	    case 4: printf("% *x", access * 2 +  SEPARATOR_WIDTH, ((uint32_t*)buf)[i]); break;
-	    case 8: printf("% *lx", access * 2 +  SEPARATOR_WIDTH, ((uint64_t*)buf)[i]); break;
+	    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");
@@ -439,7 +460,11 @@ int WriteData(int handle, int bar, unsigned long addr, int n, int access, char *
 //    ReadData(handle, bar, addr, n, access);
     Read(check, handle, bar, addr, size);
     
-    if (memcmp(buf, check, size)) Error("Write failed, the data written and read differ");
+    if (memcmp(buf, check, size)) {
+	printf("Write failed: the data written and read differ, the foolowing is read back:");
+	ReadData(handle, bar, addr, n, access);
+	exit(-1);
+    }
 
     free(check);
     free(buf);

+ 19 - 0
tools.c

@@ -29,6 +29,25 @@ void *memcpy32(void * dst, void const * src, size_t len) {
     return (dst);
 } 
 
+void *memcpy64(void * dst, void const * src, size_t len) {
+    uint64_t * plDst = (uint64_t *) dst;
+    uint64_t const * plSrc = (uint64_t const *) src;
+
+    while (len >= 8) {
+        *plDst++ = *plSrc++;
+        len -= 4;
+    }
+
+    char * pcDst = (char *) plDst;
+    char const * pcSrc = (char const *) plSrc;
+
+    while (len--) {
+        *pcDst++ = *pcSrc++;
+    }
+
+    return (dst);
+} 
+
 
 int get_page_mask() {
     int pagesize,pagemask,temp;

+ 1 - 0
tools.h

@@ -2,4 +2,5 @@
 
 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();