X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=Usermode%2FApplications%2Flspci_src%2Fmain.c;h=669edb319ab0bf0d76b1890ecc9764bc810f64ac;hb=345637737376855a6bdea7b158b545351a3da642;hp=44dc61ab20d05cf798b7fa39f8b6c79180c0260e;hpb=479d0634670b58da044bc58149662adba0ad1d0b;p=tpg%2Facess2.git diff --git a/Usermode/Applications/lspci_src/main.c b/Usermode/Applications/lspci_src/main.c index 44dc61ab..669edb31 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; @@ -40,8 +135,11 @@ void show_device(int PFD, const char *File, int bVerbose) struct { uint16_t vendor; uint16_t device; - uint32_t _unused; + uint16_t command; + uint16_t status; uint32_t revclass; + uint32_t _unused2; + uint32_t bar[6]; } pciinfo; fd = _SysOpenChild(PFD, File, OPENFLAG_READ); @@ -57,14 +155,52 @@ 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 ) { + printf("Command: "); + if(pciinfo.command & (1 <<10)) printf("INTx# Disabled, "); + if(pciinfo.command & (1 << 2)) printf("Bus Master, "); + if(pciinfo.command & (1 << 1)) printf("MMIO Enabled, "); + if(pciinfo.command & (1 << 0)) printf("IO Enabled, "); + printf("\n"); + 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"); }