3 # Copyright 2006, Haiku.
4 # Distributed under the terms of the MIT License.
7 # John Drinkwater, john@nextraweb.com
9 # Use with http://pciids.sourceforge.net/pci.ids
10 # run as: awk -v HEADERFILE=pcihdr.h -f pci-header.awk pci.ids
14 # field separator, defining because user could have overridden
17 # Pass this in from outside with -v HEADERFILE=filenametouse
18 # we require pcihdr.h for our system
21 # possibly use this in the future
22 cleanvalues =
"[^A-Za-z0-9{}\"'&@?!*.,:;+<> \\t\\/_\\[\\]=#()-]"
23 # ToDo: currently IDs aren't checked, we dumbly assume the source is clean
25 # descriptive output header
27 print "#\tPCIHDR.H: PCI Vendors, Devices, and Class Type information\n#" > ofile
28 print "#\tGenerated by pci-header.awk, source data from the following URI:\n#\thttp://pciids.sourceforge.net/pci.ids\n#" > ofile
29 print "#\tHeader created on " strftime
( "%A, %d %b %Y %H:%M:%S %Z", systime
() ) > ofile
30 print "#endif" > ofile
32 # and we start with vendors..
33 print "\ntypedef struct _PCI_VENTABLE\n{\n\tunsigned short\tVenId ;\n\tconst char *\tVenFull ;\n\tconst char *\tVenShort ;\n} PCI_VENTABLE, *PPCI_VENTABLE ;\n" > ofile
34 print "PCI_VENTABLE\tPciVenTable [] =\n{" > ofile
37 # matches vendor - starts with an id as first thing on the line
38 # because this occurs first in the header file, we output it without worry
39 /^
[[:xdigit
:]][[:xdigit
:]][[:xdigit
:]][[:xdigit
:]] / {
41 if ( vendorcount
++ > 0 ) {
47 # store vendor ID for possible devices afterwards
49 vendor =
substr($
0, 7)
50 gsub( /\"/, "&&", vendor
)
52 printf formatting
"\t{ 0x" vendorid
", \"" vendor
"\", \"\" }" > ofile
56 /^
\t[[:xdigit
:]][[:xdigit
:]][[:xdigit
:]][[:xdigit
:]] / {
58 device =
substr($
0, 8)
59 gsub( /\\/, "&&", device
)
60 gsub( /\"/, "&&", device
)
62 # store device ID for possible devices afterwards
65 devices
[devicecount
, 1] = vendorid
66 devices
[devicecount
, 2] = $
1
67 devices
[devicecount
, 3] =
0
68 devices
[devicecount
, 4] =
0
69 devices
[devicecount
, 5] = device
72 # matches subvendor device
73 /^
\t\t[[:xdigit
:]][[:xdigit
:]][[:xdigit
:]][[:xdigit
:]] / {
75 device =
substr($
0, 14)
76 gsub( /\"/, "\\\"", device
)
79 devices
[devicecount
, 1] = vendorid
80 devices
[devicecount
, 2] = deviceid
81 devices
[devicecount
, 3] = $
1
82 devices
[devicecount
, 4] = $
2
83 devices
[devicecount
, 5] = device
86 # match device class - store data for later
87 /^C
[[:xdigit
:]][[:xdigit
:]] / {
90 classname =
substr($
0, 7)
91 gsub( /\"/, "\\\"", classname
)
94 # match subclass, use device class data captured earlier, and output
95 /^
\t[[:xdigit
:]][[:xdigit
:]] / {
98 subclassname =
substr($
0, 6)
99 gsub( /\"/, "\\\"", subclassname
)
102 classes
[classcount
, 1] = class
103 classes
[classcount
, 2] = subclass
104 classes
[classcount
, 3] =
"00"
105 classes
[classcount
, 4] = classname
106 classes
[classcount
, 5] = subclassname
107 classes
[classcount
, 6] =
""
110 # match programming interface
111 /^
\t\t[[:xdigit
:]][[:xdigit
:]] / {
114 proginterfacename =
substr($
0, 7)
115 gsub( /\"/, "\\\"", proginterfacename
)
118 classes
[classcount
, 1] = class
119 classes
[classcount
, 2] = subclass
120 classes
[classcount
, 3] = proginterface
121 classes
[classcount
, 4] = classname
122 classes
[classcount
, 5] = subclassname
123 classes
[classcount
, 6] = proginterfacename
126 # We've processed the file, now output.
129 print "\n};\n\n// Use this value for loop control during searching:\n#define\tPCI_VENTABLE_LEN\t(sizeof(PciVenTable)/sizeof(PCI_VENTABLE))\n" > ofile
131 if ( devicecount
> 0 ) {
133 print "typedef struct _PCI_DEVTABLE\n{\n\tunsigned short VenId ;\n\tunsigned short DevId ;\n\tunsigned short\tSubVenId ;\n\tunsigned short\tSubDevId ;\n\tconst char *\tChipDesc ;\n} PCI_DEVTABLE, *PPCI_DEVTABLE ;\n" > ofile
134 print "PCI_DEVTABLE\tPciDevTable [] =\n{" > ofile
135 for (i =
1; i
<= devicecount
; i
++) {
142 printf formatting
"\t{ 0x" devices
[i
, 1] ", 0x" devices
[i
, 2] ", 0x" devices
[i
, 3] ", 0x" devices
[i
, 4] ", \"" devices
[i
, 5] "\" }" > ofile
144 print "\n} ;\n\n// Use this value for loop control during searching:\n#define PCI_DEVTABLE_LEN (sizeof(PciDevTable)/sizeof(PCI_DEVTABLE))\n" > ofile
148 if ( classcount
> 0 ) {
149 print "typedef struct _PCI_CLASSCODETABLE\n{\n\tunsigned char BaseClass ;\n\tunsigned char SubClass ;\n\tunsigned char ProgIf ;" > ofile
150 print "\tconst char *\t\tBaseDesc ;\n\tconst char *\t\tSubDesc ;\n\tconst char *\t\tProgDesc ;\n} PCI_CLASSCODETABLE, *PPCI_CLASSCODETABLE ;\n" > ofile
151 print "PCI_CLASSCODETABLE PciClassCodeTable [] =\n{" > ofile
152 currentclass = classes
[1, 1]
153 for (i =
1; i
<= classcount
; i
++) {
161 # pretty print separate classes
162 if ( currentclass
!= classes
[i
, 1] ) {
163 formatting = formatting
"\n"
164 currentclass = classes
[i
, 1]
167 # if the next item has the same details, we know we're to skip ourselves
168 # this is because the programming interface name needs to be used, and we dont have it ourselves
169 if ( ( classes
[i
, 1] != classes
[i
+1, 1] ) || ( classes
[i
, 2] != classes
[i
+1, 2] ) || ( classes
[i
, 3] != classes
[i
+1, 3] ) ) {
170 printf formatting
"\t{ 0x" classes
[i
, 1] ", 0x" classes
[i
, 2] ", 0x" classes
[i
, 3] ", \"" classes
[i
, 4] "\", \"" classes
[i
, 5] "\", \"" classes
[i
, 6] "\" }" > ofile
173 print "\n} ;\n\n// Use this value for loop control during searching:\n#define PCI_CLASSCODETABLE_LEN (sizeof(PciClassCodeTable)/sizeof(PCI_CLASSCODETABLE))\n" > ofile
177 # this is rather ugly, maybe we should include this in a seperate file, and pull it in ?
178 print "const char *\tPciCommandFlags [] =\n{\n\t\"I/O Access\",\n\t\"Memory Access\",\n\t\"Bus Mastering\",\n\t\"Special Cycles\",\n\t\"Memory Write & Invalidate\",\n\t\"Palette Snoop\",\n\t\"Parity Errors\",\n\t\"Wait Cycles\",\n\t\"System Errors\",\n\t\"Fast Back-To-Back\",\n\t\"Reserved 10\",\n\t\"Reserved 11\",\n\t\"Reserved 12\",\n\t\"Reserved 13\",\n\t\"Reserved 14\",\n\t\"Reserved 15\"\n} ;\n" > ofile
179 print "// Use this value for loop control during searching:\n#define PCI_COMMANDFLAGS_LEN (sizeof(PciCommandFlags)/sizeof(char *))\n" > ofile
180 print "const char *\tPciStatusFlags [] =\n{\n\t\"Reserved 0\",\n\t\"Reserved 1\",\n\t\"Reserved 2\",\n\t\"Reserved 3\",\n\t\"Reserved 4\",\n\t\"66 MHz Capable\",\n\t\"User-Defined Features\",\n\t\"Fast Back-To-Back\",\n\t\"Data Parity Reported\",\n\t\"\",\n\t\"\",\n\t\"Signalled Target Abort\",\n\t\"Received Target Abort\",\n\t\"Received Master Abort\",\n\t\"Signalled System Error\",\n\t\"Detected Parity Error\"\n} ;\n" > ofile
181 print "// Use this value for loop control during searching:\n#define PCI_STATUSFLAGS_LEN (sizeof(PciStatusFlags)/sizeof(char *))\n" > ofile
182 print "const char *\tPciDevSelFlags [] =\n{\n\t\"Fast Devsel Speed\",\n\t\"Medium Devsel Speed\",\n\t\"Slow Devsel Speed\",\n\t\"Reserved 9&10\"\n} ;\n" > ofile
183 print "// Use this value for loop control during searching:\n#define PCI_DEVSELFLAGS_LEN (sizeof(PciDevSelFlags)/sizeof(char *))\n\n" > ofile