xref: /aosp_15_r20/external/coreboot/src/device/pci_class.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <commonlib/bsd/helpers.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
7 #include <stddef.h>
8 
9 typedef struct {
10 	const unsigned char subclass_id;
11 	const char *subclass_name;
12 } PCI_SUBCLASS;
13 
14 typedef struct {
15 	const unsigned char class_id;
16 	const PCI_SUBCLASS *subclass_list;
17 	const unsigned int subclass_entries;
18 	const char *class_name;
19 } PCI_CLASS;
20 
21 static const PCI_SUBCLASS unclassified[] = {
22 	{ 0x00, "Non-VGA device" },
23 	{ 0x01, "VGA compatible device" }
24 };
25 
26 static const PCI_SUBCLASS mass_storage[] = {
27 	{ 0x00, "SCSI storage controller" },
28 	{ 0x01, "IDE interface" },
29 	{ 0x02, "Floppy disk controller" },
30 	{ 0x03, "IPI bus controller" },
31 	{ 0x04, "RAID bus controller" },
32 	{ 0x05, "ATA controller" },
33 	{ 0x06, "SATA controller" },
34 	{ 0x07, "Serial Attached SCSI controller" },
35 	{ 0x08, "Non-Volatile memory controller" },
36 	{ 0x09, "Universal Flash Storage controller" },
37 	{ 0x80, "Mass storage controller" }
38 };
39 
40 static const PCI_SUBCLASS network[] = {
41 	{ 0x00, "Ethernet controller" },
42 	{ 0x01, "Token ring network controller" },
43 	{ 0x02, "FDDI network controller" },
44 	{ 0x03, "ATM network controller" },
45 	{ 0x04, "ISDN controller" },
46 	{ 0x05, "WorldFip controller" },
47 	{ 0x06, "PICMG controller" },
48 	{ 0x07, "InfiniBand Controller" },
49 	{ 0x08, "Host fabric controller" },
50 	{ 0x80, "Network controller" }
51 };
52 
53 static const PCI_SUBCLASS display[] = {
54 	{ 0x00, "VGA compatible controller" },
55 	{ 0x01, "XGA compatible controller" },
56 	{ 0x02, "3D controller" },
57 	{ 0x80, "Display controller" }
58 };
59 
60 static const PCI_SUBCLASS multimedia[] = {
61 	{ 0x00, "Multimedia video controller" },
62 	{ 0x01, "Multimedia audio controller" },
63 	{ 0x02, "Computer telephony device" },
64 	{ 0x03, "Audio device" },
65 	{ 0x80, "Multimedia controller" }
66 };
67 
68 static const PCI_SUBCLASS memory[] = {
69 	{ 0x00, "RAM memory" },
70 	{ 0x01, "FLASH memory" },
71 	{ 0x80, "Memory controller" }
72 };
73 
74 static const PCI_SUBCLASS bridge[] = {
75 	{ 0x00, "Host bridge" },
76 	{ 0x01, "ISA bridge" },
77 	{ 0x02, "EISA bridge" },
78 	{ 0x03, "MicroChannel bridge" },
79 	{ 0x04, "PCI bridge" },
80 	{ 0x05, "PCMCIA bridge" },
81 	{ 0x06, "NuBus bridge" },
82 	{ 0x07, "CardBus bridge" },
83 	{ 0x08, "RACEway bridge" },
84 	{ 0x09, "Semi-transparent PCI-to-PCI bridge" },
85 	{ 0x0a, "InfiniBand to PCI host bridge" },
86 	{ 0x0b, "Advanced Switching to PCI host bridge" },
87 	{ 0x80, "Bridge" }
88 };
89 
90 static const PCI_SUBCLASS communication[] = {
91 	{ 0x00, "Serial controller" },
92 	{ 0x01, "Parallel controller" },
93 	{ 0x02, "Multiport serial controller" },
94 	{ 0x03, "Modem" },
95 	{ 0x04, "GPIB controller" },
96 	{ 0x05, "Smart Card controller" },
97 	{ 0x80, "Communication controller" }
98 };
99 
100 static const PCI_SUBCLASS generic[] = {
101 	{ 0x00, "PIC" },
102 	{ 0x01, "DMA controller" },
103 	{ 0x02, "Timer" },
104 	{ 0x03, "RTC" },
105 	{ 0x04, "PCI Hot-plug controller" },
106 	{ 0x05, "SD Host controller" },
107 	{ 0x06, "IOMMU" },
108 	{ 0x07, "Root Complex Event Collector" },
109 	{ 0x80, "System peripheral" }
110 };
111 
112 static const PCI_SUBCLASS input_device[] = {
113 	{ 0x00, "Keyboard controller" },
114 	{ 0x01, "Digitizer Pen" },
115 	{ 0x02, "Mouse controller" },
116 	{ 0x03, "Scanner controller" },
117 	{ 0x04, "Gameport controller" },
118 	{ 0x80, "Input device controller" }
119 };
120 
121 static const PCI_SUBCLASS docking_station[] = {
122 	{ 0x00, "Generic Docking Station" },
123 	{ 0x80, "Docking Station" }
124 };
125 
126 static const PCI_SUBCLASS processor[] = {
127 	{ 0x00, "386" },
128 	{ 0x01, "486" },
129 	{ 0x02, "Pentium" },
130 	{ 0x10, "Alpha" },
131 	{ 0x20, "Power PC" },
132 	{ 0x30, "MIPS" },
133 	{ 0x40, "Co-processor" },
134 	{ 0x80, "Processor" }
135 };
136 
137 static const PCI_SUBCLASS serial_bus[] = {
138 	{ 0x00, "FireWire (IEEE 1394)" },
139 	{ 0x01, "ACCESS Bus" },
140 	{ 0x02, "SSA" },
141 	{ 0x03, "USB controller" },
142 	{ 0x04, "Fibre Channel" },
143 	{ 0x05, "SMBus" },
144 	{ 0x06, "InfiniBand" },
145 	{ 0x07, "IPMI SMIC interface" },
146 	{ 0x08, "SERCOS interface" },
147 	{ 0x09, "CANBUS" },
148 	{ 0x0a, "MIPI I3C SM Host Controller Interface" },
149 	{ 0x80, "Serial Bus Controller" }
150 };
151 
152 static const PCI_SUBCLASS wireless[] = {
153 	{ 0x00, "IRDA controller" },
154 	{ 0x01, "Consumer IR controller" },
155 	{ 0x10, "RF controller" },
156 	{ 0x11, "Bluetooth" },
157 	{ 0x12, "Broadband" },
158 	{ 0x20, "802.1a controller" },
159 	{ 0x21, "802.1b controller" },
160 	{ 0x40, "Cellular controller/modem" },
161 	{ 0x41, "Cellular controller/modem plus Ethernet (802.11)" },
162 	{ 0x80, "Wireless controller" }
163 };
164 
165 static const PCI_SUBCLASS intellegient_controller[] = {
166 	{ 0x00, "I2O" }
167 };
168 
169 static const PCI_SUBCLASS satellite_controller[] = {
170 	{ 0x01, "Satellite TV controller" },
171 	{ 0x02, "Satellite audio communication controller" },
172 	{ 0x03, "Satellite voice communication controller" },
173 	{ 0x04, "Satellite data communication controller" }
174 };
175 
176 static const PCI_SUBCLASS encryption[] = {
177 	{ 0x00, "Network and computing encryption device" },
178 	{ 0x10, "Entertainment encryption device" },
179 	{ 0x80, "Encryption controller" }
180 };
181 
182 static const PCI_SUBCLASS signal_processing[] = {
183 	{ 0x00, "DPIO module" },
184 	{ 0x01, "Performance counters" },
185 	{ 0x10, "Communication synchronizer" },
186 	{ 0x20, "Signal processing management" },
187 	{ 0x80, "Signal processing controller" }
188 };
189 
190 static const PCI_CLASS class_list[] = {
191 	{ 0x00, &unclassified[0], ARRAY_SIZE(unclassified),
192 		"Unclassified device" },
193 	{ 0x01, &mass_storage[0], ARRAY_SIZE(mass_storage), "Mass storage" },
194 	{ 0x02, &network[0], ARRAY_SIZE(network), "Network" },
195 	{ 0x03, &display[0], ARRAY_SIZE(display), "Display" },
196 	{ 0x04, &multimedia[0], ARRAY_SIZE(multimedia), "Multimedia" },
197 	{ 0x05, &memory[0], ARRAY_SIZE(memory), "Memory" },
198 	{ 0x06, &bridge[0], ARRAY_SIZE(bridge), "Bridge" },
199 	{ 0x07, &communication[0], ARRAY_SIZE(communication), "Communication" },
200 	{ 0x08, &generic[0], ARRAY_SIZE(generic), "Generic system peripheral" },
201 	{ 0x09, &input_device[0], ARRAY_SIZE(input_device), "Input device" },
202 	{ 0x0a, &docking_station[0], ARRAY_SIZE(docking_station),
203 		"Docking station" },
204 	{ 0x0b, &processor[0], ARRAY_SIZE(processor), "Processor" },
205 	{ 0x0c, &serial_bus[0], ARRAY_SIZE(serial_bus), "Serial bus" },
206 	{ 0x0d, &wireless[0], ARRAY_SIZE(wireless), "Wireless" },
207 	{ 0x0e, &intellegient_controller[0],
208 			ARRAY_SIZE(intellegient_controller),
209 			"Intelligent controller" },
210 	{ 0x0f, &satellite_controller[0], ARRAY_SIZE(satellite_controller),
211 			"Satellite communications" },
212 	{ 0x10, &encryption[0], ARRAY_SIZE(encryption), "Encryption" },
213 	{ 0x11, &signal_processing[0], ARRAY_SIZE(signal_processing),
214 			"Signal processing" },
215 	{ 0xff, NULL, 0, "Unassigned class" }
216 };
217 static const unsigned int class_entries = ARRAY_SIZE(class_list);
218 
get_pci_class_entry(struct device * dev)219 static const PCI_CLASS *get_pci_class_entry(struct device *dev)
220 {
221 	unsigned char class;
222 	const PCI_CLASS *class_entry;
223 	const PCI_CLASS *class_list_end;
224 
225 	/* Get the PCI device class */
226 	class = pci_read_config8(dev, PCI_CLASS_DEVICE+1);
227 
228 	/* Locate the class entry */
229 	class_entry = &class_list[0];
230 	class_list_end = &class_entry[class_entries];
231 	while (class_list_end > class_entry) {
232 		if (class_entry->class_id == class)
233 			return class_entry;
234 		class_entry += 1;
235 	}
236 	return NULL;
237 }
238 
get_pci_class_name(struct device * dev)239 const char *get_pci_class_name(struct device *dev)
240 {
241 	const PCI_CLASS *class_entry;
242 
243 	class_entry = get_pci_class_entry(dev);
244 	return class_entry ? class_entry->class_name : "???";
245 }
246 
get_pci_subclass_name(struct device * dev)247 const char *get_pci_subclass_name(struct device *dev)
248 {
249 	const PCI_CLASS *class_entry;
250 	unsigned char subclass;
251 	const PCI_SUBCLASS *subclass_entry;
252 	const PCI_SUBCLASS *subclass_list_end;
253 	const char *subclass_name;
254 
255 	/* Get the PCI device subclass */
256 	subclass = pci_read_config8(dev, PCI_CLASS_DEVICE);
257 
258 	/* Locate the subclass name */
259 	subclass_name = "???";
260 	class_entry = get_pci_class_entry(dev);
261 	subclass_entry = class_entry ? class_entry->subclass_list : NULL;
262 	if (subclass_entry != NULL) {
263 		subclass_list_end =
264 			&subclass_entry[class_entry->subclass_entries];
265 		while (subclass_list_end > subclass_entry) {
266 			if (subclass_entry->subclass_id == subclass) {
267 				subclass_name = subclass_entry->subclass_name;
268 				break;
269 			}
270 			subclass_entry += 1;
271 		}
272 	}
273 	return subclass_name;
274 }
275