#include <stdlib.h>
#include <stdio.h>
#include <acess/sys.h>
+#include <string.h>
#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] [<pcidev>]\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;
uint16_t device;
uint32_t _unused;
uint32_t revclass;
+ uint32_t _unused2;
+ uint32_t bar[6];
} pciinfo;
fd = _SysOpenChild(PFD, File, OPENFLAG_READ);
}
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");
}