From 813c7abf04ab9f7f9c30059b258612e18dec5ce7 Mon Sep 17 00:00:00 2001 From: "Suren A. Chilingaryan" Date: Sun, 13 Feb 2011 15:33:26 +0100 Subject: Print a bit more details --- driver/ioctl.c | 1 + driver/pciDriver.h | 1 + kernel.h | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ pci.c | 55 ++++++++++++++++++++++++++---------- tools.c | 19 +++++++++++++ tools.h | 1 + 6 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 kernel.h 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 + #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(); -- cgit v1.2.3