summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--driver/ioctl.c1
-rw-r--r--driver/pciDriver.h1
-rw-r--r--kernel.h81
-rw-r--r--pci.c55
-rw-r--r--tools.c19
-rw-r--r--tools.h1
6 files changed, 143 insertions, 15 deletions
diff --git a/driver/ioctl.c b/driver/ioctl.c
index 59d9245..6240d31 100644
--- a/driver/ioctl.c
+++ b/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);
diff --git a/driver/pciDriver.h b/driver/pciDriver.h
index 9abf3ab..ed04d65 100644
--- a/driver/pciDriver.h
+++ b/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;
diff --git a/kernel.h b/kernel.h
new file mode 100644
index 0000000..161d2aa
--- /dev/null
+++ b/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 */
diff --git a/pci.c b/pci.c
index 9929577..cf03c9c 100644
--- a/pci.c
+++ b/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);
diff --git a/tools.c b/tools.c
index 608a4ec..7766c6a 100644
--- a/tools.c
+++ b/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;
diff --git a/tools.h b/tools.h
index d112b1d..c49f137 100644
--- a/tools.h
+++ b/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();