From cd6ab1b40354d8bba8e011731c9d1c60f60053c3 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Thu, 11 Jul 2013 14:30:58 +0800 Subject: [PATCH] Usermode/lspci - Cleanup and BAR dump --- Usermode/Applications/lspci_src/main.c | 149 +++++++++++++++++++++++-- 1 file changed, 139 insertions(+), 10 deletions(-) diff --git a/Usermode/Applications/lspci_src/main.c b/Usermode/Applications/lspci_src/main.c index 44dc61ab..8b8755ff 100644 --- a/Usermode/Applications/lspci_src/main.c +++ b/Usermode/Applications/lspci_src/main.c @@ -7,31 +7,126 @@ #include #include #include +#include #define PCI_BASE "/Devices/pci" // === PROTOTYPES === int main(int argc, char *argv[]); + int ParseCommandline(int argc, char *argv[]); void show_device(int PFD, const char *File, int bVerbose); +// === GLOBALS === + int gbEnableVerbose = 0; +const char *gsDeviceName; + // === CODE === int main(int argc, char *argv[]) { - int fd = _SysOpen(PCI_BASE, OPENFLAG_READ); - - char name[256]; + int rv; + + rv = ParseCommandline(argc, argv); + if(rv) return rv; - while( _SysReadDir(fd, name) ) + int fd = _SysOpen(PCI_BASE, OPENFLAG_READ); + if( gsDeviceName ) { - if(name[0] == '.') continue ; - - show_device(fd, name, 0); + show_device(fd, gsDeviceName, gbEnableVerbose); + } + else + { + char name[256]; + while( _SysReadDir(fd, name) ) + { + if(name[0] == '.') continue ; + + show_device(fd, name, gbEnableVerbose); + } } - _SysClose(fd); return 0; } +void ShowUsage(const char *progname) +{ + fprintf(stderr, "Usage: %s [-v|--verbose] []\n", progname); + fprintf(stderr, + "\n" + "-v | --verbose : Enable dump of BARs\n" + "\n" + ); +} + +int ParseCommandline(int argc, char *argv[]) +{ + for( int i = 1; i < argc; i ++ ) + { + const char *arg = argv[i]; + if( arg[0] != '-' ) { + // Show an individual device + gsDeviceName = arg; + } + else if( arg[1] != '-' ) { + // Short args + switch(arg[1]) + { + case 'v': + gbEnableVerbose ++; + break; + default: + ShowUsage(argv[0]); + return 1; + } + } + else { + // Long args + if(strcmp(arg, "--verbose") == 0) { + gbEnableVerbose ++; + } + else { + ShowUsage(argv[0]); + return 1; + } + } + } + return 0; +} + +const char *get_device_class(uint32_t revclass) +{ + uint8_t class = revclass >> 24; + uint8_t subclass = revclass >> 16; + switch(class) + { + case 0x00: + switch( subclass ) + { + case 0x01: return "VGA-Compatible"; + } + return "Pre Classcodes"; + case 0x01: + switch( subclass ) + { + case 0x00: return "SCSI Bus Controller"; + case 0x01: return "IDE Controller"; + case 0x02: return "Floppy Disk Controller"; + } + return "Mass Storage Controller"; + case 0x02: return "Network Controller"; + case 0x03: return "Display Controller"; + case 0x04: return "Multimedia Controller"; + case 0x05: return "Memory Controller"; + case 0x06: return "Bridge Device"; + case 0x07: return "Simple Communications Controller"; + case 0x08: return "Base System Peripherals"; + case 0x09: return "Input Device"; + case 0x0A: return "Docing Station"; + case 0x0B: return "Processor"; + case 0x0C: return "Serial Bus Controller"; + } + return ""; +} + void show_device(int PFD, const char *File, int bVerbose) { int fd; @@ -42,6 +137,8 @@ void show_device(int PFD, const char *File, int bVerbose) uint16_t device; uint32_t _unused; uint32_t revclass; + uint32_t _unused2; + uint32_t bar[6]; } pciinfo; fd = _SysOpenChild(PFD, File, OPENFLAG_READ); @@ -57,14 +154,46 @@ void show_device(int PFD, const char *File, int bVerbose) } uint32_t class_if = pciinfo.revclass >> 8; uint8_t revision = pciinfo.revclass & 0xFF; - printf("%s - %04x:%04x %06x:%02x\n", + printf("%s - %04x:%04x %06x:%02x %s\n", File, pciinfo.vendor, pciinfo.device, - class_if, revision + class_if, revision, + get_device_class(pciinfo.revclass) ); if( bVerbose ) { + for( int i = 0; i < 6; i ++ ) + { + uint32_t bar = pciinfo.bar[i]; + if( bar == 0 ) + continue ; + printf("BAR%i: ", i); + if( bar & 1 ) { + printf("IO 0x%02x", bar & ~3); + } + else { + // Memory type + switch( (bar & 6) >> 1 ) + { + case 0: + printf("Mem32 0x%08x", bar & ~15); + break; + case 2: + printf("Mem20 0x%05x", bar & ~15); + break; + case 4: + printf("Mem64 0x%08x%08x", pciinfo.bar[i+1], bar & ~15); + i ++; + break; + case 6: + printf("UNK %08x", bar & ~15); + break; + } + printf(" %s", (bar & 8 ? "Prefetchable" : "")); + } + printf("\n"); + } printf("\n"); } -- 2.20.1