Usermode/lspci - Dump command state in verbose
[tpg/acess2.git] / Usermode / Applications / lspci_src / main.c
1 /*
2  * Acess2 lspci
3  * - By John Hodge (thePowersGang)
4  *
5  * main.c
6  */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <acess/sys.h>
10 #include <string.h>
11
12 #define PCI_BASE        "/Devices/pci"
13 // === PROTOTYPES ===
14  int    main(int argc, char *argv[]);
15  int    ParseCommandline(int argc, char *argv[]);
16 void    show_device(int PFD, const char *File, int bVerbose);
17
18 // === GLOBALS ===
19  int    gbEnableVerbose = 0;
20 const char      *gsDeviceName;
21
22 // === CODE ===
23 int main(int argc, char *argv[])
24 {
25          int    rv;
26         
27         rv = ParseCommandline(argc, argv);
28         if(rv)  return rv;
29
30         int fd = _SysOpen(PCI_BASE, OPENFLAG_READ);
31         if( gsDeviceName )
32         {
33                 show_device(fd, gsDeviceName, gbEnableVerbose);
34         }
35         else
36         {
37                 char name[256]; 
38                 while( _SysReadDir(fd, name) )
39                 {
40                         if(name[0] == '.')      continue ;
41                         
42                         show_device(fd, name, gbEnableVerbose);
43                 }
44         }
45         _SysClose(fd);
46
47         return 0;
48 }
49
50 void ShowUsage(const char *progname)
51 {
52         fprintf(stderr, "Usage: %s [-v|--verbose] [<pcidev>]\n", progname);
53         fprintf(stderr,
54                 "\n"
55                 "-v | --verbose : Enable dump of BARs\n"
56                 "\n"
57                 );
58 }
59
60 int ParseCommandline(int argc, char *argv[])
61 {
62         for( int i = 1; i < argc; i ++ )
63         {
64                 const char *arg = argv[i];
65                 if( arg[0] != '-' ) {
66                         // Show an individual device
67                         gsDeviceName = arg;
68                 }
69                 else if( arg[1] != '-' ) {
70                         // Short args
71                         switch(arg[1])
72                         {
73                         case 'v':
74                                 gbEnableVerbose ++;
75                                 break;
76                         default:
77                                 ShowUsage(argv[0]);
78                                 return 1;
79                         }
80                 }
81                 else {
82                         // Long args
83                         if(strcmp(arg, "--verbose") == 0) {
84                                 gbEnableVerbose ++;
85                         }
86                         else {
87                                 ShowUsage(argv[0]);
88                                 return 1;
89                         }
90                 }
91         }
92         return 0;
93 }
94
95 const char *get_device_class(uint32_t revclass)
96 {
97         uint8_t class = revclass >> 24;
98         uint8_t subclass = revclass >> 16;
99         switch(class)
100         {
101         case 0x00:
102                 switch( subclass )
103                 {
104                 case 0x01:      return "VGA-Compatible";
105                 }
106                 return "Pre Classcodes";
107         case 0x01:
108                 switch( subclass )
109                 {
110                 case 0x00:      return "SCSI Bus Controller";
111                 case 0x01:      return "IDE Controller";
112                 case 0x02:      return "Floppy Disk Controller";
113                 }
114                 return "Mass Storage Controller";
115         case 0x02:      return "Network Controller";
116         case 0x03:      return "Display Controller";
117         case 0x04:      return "Multimedia Controller";
118         case 0x05:      return "Memory Controller";
119         case 0x06:      return "Bridge Device";
120         case 0x07:      return "Simple Communications Controller";
121         case 0x08:      return "Base System Peripherals";
122         case 0x09:      return "Input Device";
123         case 0x0A:      return "Docing Station";
124         case 0x0B:      return "Processor";
125         case 0x0C:      return "Serial Bus Controller";
126         }
127         return "";
128 }
129
130 void show_device(int PFD, const char *File, int bVerbose)
131 {
132          int    fd;
133          int    rv;
134
135         struct {
136                 uint16_t        vendor;
137                 uint16_t        device;
138                 uint16_t        command;
139                 uint16_t        status;
140                 uint32_t        revclass;
141                 uint32_t        _unused2;
142                 uint32_t        bar[6];
143         } pciinfo;
144
145         fd = _SysOpenChild(PFD, File, OPENFLAG_READ);
146         if( fd == -1 ) {
147                 printf("%s - ERR (open failure)\n", File);
148                 return ;
149         }
150         rv = _SysRead(fd, &pciinfo, sizeof(pciinfo));
151         if( rv != sizeof(pciinfo) ) {
152                 printf("%s - ERR (read %i < %i)\n", File, rv, sizeof(pciinfo));
153                 _SysClose(fd);
154                 return ;
155         }
156         uint32_t        class_if = pciinfo.revclass >> 8;
157         uint8_t         revision = pciinfo.revclass & 0xFF;
158         printf("%s - %04x:%04x %06x:%02x %s\n",
159                 File,
160                 pciinfo.vendor, pciinfo.device,
161                 class_if, revision,
162                 get_device_class(pciinfo.revclass)
163                 );
164
165         if( bVerbose )
166         {
167                 printf("Command: ");
168                 if(pciinfo.command & (1 <<10))  printf("INTx# Disabled, ");
169                 if(pciinfo.command & (1 << 2))  printf("Bus Master, ");
170                 if(pciinfo.command & (1 << 1))  printf("MMIO Enabled, ");
171                 if(pciinfo.command & (1 << 0))  printf("IO Enabled, ");
172                 printf("\n");
173                 for( int i = 0; i < 6; i ++ )
174                 {
175                         uint32_t        bar = pciinfo.bar[i];
176                         if( bar == 0 )
177                                 continue ;
178                         printf("BAR%i: ", i);
179                         if( bar & 1 ) {
180                                 printf("IO  0x%02x", bar & ~3);
181                         }
182                         else {
183                                 // Memory type
184                                 switch( (bar & 6) >> 1 )
185                                 {
186                                 case 0:
187                                         printf("Mem32 0x%08x", bar & ~15);
188                                         break;
189                                 case 2:
190                                         printf("Mem20 0x%05x", bar & ~15);
191                                         break;
192                                 case 4:
193                                         printf("Mem64 0x%08x%08x", pciinfo.bar[i+1], bar & ~15);
194                                         i ++;
195                                         break;
196                                 case 6:
197                                         printf("UNK %08x", bar & ~15);
198                                         break;
199                                 }
200                                 printf(" %s", (bar & 8 ? "Prefetchable" : ""));
201                         }
202                         printf("\n");
203                 }
204                 printf("\n");
205         }
206
207         _SysClose(fd);
208 }
209

UCC git Repository :: git.ucc.asn.au