Usermode/lspci - Cleanup and BAR dump
[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                 uint32_t        _unused;
139                 uint32_t        revclass;
140                 uint32_t        _unused2;
141                 uint32_t        bar[6];
142         } pciinfo;
143
144         fd = _SysOpenChild(PFD, File, OPENFLAG_READ);
145         if( fd == -1 ) {
146                 printf("%s - ERR (open failure)\n", File);
147                 return ;
148         }
149         rv = _SysRead(fd, &pciinfo, sizeof(pciinfo));
150         if( rv != sizeof(pciinfo) ) {
151                 printf("%s - ERR (read %i < %i)\n", File, rv, sizeof(pciinfo));
152                 _SysClose(fd);
153                 return ;
154         }
155         uint32_t        class_if = pciinfo.revclass >> 8;
156         uint8_t         revision = pciinfo.revclass & 0xFF;
157         printf("%s - %04x:%04x %06x:%02x %s\n",
158                 File,
159                 pciinfo.vendor, pciinfo.device,
160                 class_if, revision,
161                 get_device_class(pciinfo.revclass)
162                 );
163
164         if( bVerbose )
165         {
166                 for( int i = 0; i < 6; i ++ )
167                 {
168                         uint32_t        bar = pciinfo.bar[i];
169                         if( bar == 0 )
170                                 continue ;
171                         printf("BAR%i: ", i);
172                         if( bar & 1 ) {
173                                 printf("IO  0x%02x", bar & ~3);
174                         }
175                         else {
176                                 // Memory type
177                                 switch( (bar & 6) >> 1 )
178                                 {
179                                 case 0:
180                                         printf("Mem32 0x%08x", bar & ~15);
181                                         break;
182                                 case 2:
183                                         printf("Mem20 0x%05x", bar & ~15);
184                                         break;
185                                 case 4:
186                                         printf("Mem64 0x%08x%08x", pciinfo.bar[i+1], bar & ~15);
187                                         i ++;
188                                         break;
189                                 case 6:
190                                         printf("UNK %08x", bar & ~15);
191                                         break;
192                                 }
193                                 printf(" %s", (bar & 8 ? "Prefetchable" : ""));
194                         }
195                         printf("\n");
196                 }
197                 printf("\n");
198         }
199
200         _SysClose(fd);
201 }
202

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