2 * Copyright 2003-2006, Marcus Overhagen. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 #include <KernelExport.h>
8 #define __HAIKU_PCI_BUS_MANAGER_TESTING 1
12 #include "pci_private.h"
16 #if defined(__INTEL__) || defined(__x86_64__)
17 // enabling it makes the pci bus_manager binary about 1MB
18 // some other platforms have issues with floppy image size...
19 // TODO: Move this define to BuildSetup?
20 #define USE_PCI_HEADER 1
25 # include "pci-utils.h"
28 const char *get_capability_name(uint8 cap_id
);
29 const char *get_extended_capability_name(uint16 cap_id
);
33 print_pci2pci_bridge_info(const pci_info
*info
, bool verbose
)
35 TRACE(("PCI: subsystem_id %04x, subsystem_vendor_id %04x\n",
36 info
->u
.h1
.subsystem_id
, info
->u
.h1
.subsystem_vendor_id
));
37 TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x,"
38 " secondary_latency %02x\n", info
->u
.h1
.primary_bus
,
39 info
->u
.h1
.secondary_bus
, info
->u
.h1
.subordinate_bus
, info
->u
.h1
.secondary_latency
));
40 uint32 io_base
= ((uint32
)info
->u
.h1
.io_base
& 0xf0) << 8;
41 if (info
->u
.h1
.io_base
& 1)
42 io_base
+= ((uint32
)info
->u
.h1
.io_base_upper16
<< 16);
43 uint32 io_limit
= (((uint32
)info
->u
.h1
.io_limit
& 0xf0) << 8) + 0xfff;
44 if (info
->u
.h1
.io_limit
& 1)
45 io_limit
+= info
->u
.h1
.io_limit_upper16
<< 16;
46 TRACE(("PCI: I/O window %04" B_PRIx32
"-%04" B_PRIx32
"\n", io_base
,
48 uint32 memory_base
= ((uint32
)info
->u
.h1
.memory_base
& 0xfff0) << 16;
49 uint32 memory_limit
= (((uint32
)info
->u
.h1
.memory_limit
& 0xfff0) << 16)
51 TRACE(("PCI: memory window %08" B_PRIx32
"-%08" B_PRIx32
"\n",
52 memory_base
, memory_limit
));
53 uint64 prefetchable_memory_base
=
54 ((uint32
)info
->u
.h1
.prefetchable_memory_base
& 0xfff0) << 16;
55 if (info
->u
.h1
.prefetchable_memory_base
& 1) {
56 prefetchable_memory_base
+=
57 (uint64
)info
->u
.h1
.prefetchable_memory_base_upper32
<< 32;
59 uint64 prefetchable_memory_limit
=
60 (((uint32
)info
->u
.h1
.prefetchable_memory_limit
& 0xfff0) << 16)
62 if (info
->u
.h1
.prefetchable_memory_limit
& 1) {
63 prefetchable_memory_limit
+=
64 (uint64
)info
->u
.h1
.prefetchable_memory_limit_upper32
<< 32;
66 TRACE(("PCI: prefetchable memory window %016" B_PRIx64
"-%016" B_PRIx64
"\n",
67 prefetchable_memory_base
, prefetchable_memory_limit
));
68 TRACE(("PCI: bridge_control %04x, secondary_status %04x\n",
69 info
->u
.h1
.bridge_control
, info
->u
.h1
.secondary_status
));
70 TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x\n",
71 info
->u
.h1
.interrupt_line
, info
->u
.h1
.interrupt_pin
));
72 TRACE(("PCI: ROM base host %08" B_PRIx32
", pci %08" B_PRIx32
", size ??\n",
73 info
->u
.h1
.rom_base
, info
->u
.h1
.rom_base_pci
));
74 for (int i
= 0; i
< 2; i
++)
75 TRACE(("PCI: base reg %d: host %08" B_PRIx32
", pci %08" B_PRIx32
", "
76 "size %08" B_PRIx32
", flags %02x\n", i
, info
->u
.h1
.base_registers
[i
],
77 info
->u
.h1
.base_registers_pci
[i
], info
->u
.h1
.base_register_sizes
[i
],
78 info
->u
.h1
.base_register_flags
[i
]));
83 print_pci2cardbus_bridge_info(const pci_info
*info
, bool verbose
)
85 TRACE(("PCI: subsystem_id %04x, subsystem_vendor_id %04x\n",
86 info
->u
.h2
.subsystem_id
, info
->u
.h2
.subsystem_vendor_id
));
87 TRACE(("PCI: primary_bus %02x, secondary_bus %02x, subordinate_bus %02x, "
88 "secondary_latency %02x\n", info
->u
.h2
.primary_bus
,
89 info
->u
.h2
.secondary_bus
, info
->u
.h2
.subordinate_bus
,
90 info
->u
.h2
.secondary_latency
));
91 TRACE(("PCI: bridge_control %04x, secondary_status %04x\n",
92 info
->u
.h2
.bridge_control
, info
->u
.h2
.secondary_status
));
93 TRACE(("PCI: memory_base_upper32 %08" B_PRIx32
", memory_base %08"
94 B_PRIx32
"\n", info
->u
.h2
.memory_base_upper32
, info
->u
.h2
.memory_base
));
95 TRACE(("PCI: memory_limit_upper32 %08" B_PRIx32
", memory_limit %08"
96 B_PRIx32
"\n", info
->u
.h2
.memory_limit_upper32
, info
->u
.h2
.memory_limit
));
97 TRACE(("PCI: io_base_upper32 %08" B_PRIx32
", io_base %08" B_PRIx32
"\n",
98 info
->u
.h2
.io_base_upper32
, info
->u
.h2
.io_base
));
99 TRACE(("PCI: io_limit_upper32 %08" B_PRIx32
", io_limit %08" B_PRIx32
"\n",
100 info
->u
.h2
.io_limit_upper32
, info
->u
.h2
.io_limit
));
105 print_generic_info(const pci_info
*info
, bool verbose
)
107 TRACE(("PCI: ROM base host %08" B_PRIx32
", pci %08" B_PRIx32
", size "
108 "%08" B_PRIx32
"\n", info
->u
.h0
.rom_base
, info
->u
.h0
.rom_base_pci
,
109 info
->u
.h0
.rom_size
));
110 TRACE(("PCI: cardbus_CIS %08" B_PRIx32
", subsystem_id %04x, "
111 "subsystem_vendor_id %04x\n", info
->u
.h0
.cardbus_cis
,
112 info
->u
.h0
.subsystem_id
, info
->u
.h0
.subsystem_vendor_id
));
113 TRACE(("PCI: interrupt_line %02x, interrupt_pin %02x, min_grant %02x, "
114 "max_latency %02x\n", info
->u
.h0
.interrupt_line
, info
->u
.h0
.interrupt_pin
,
115 info
->u
.h0
.min_grant
, info
->u
.h0
.max_latency
));
116 for (int i
= 0; i
< 6; i
++)
117 TRACE(("PCI: base reg %d: host %08" B_PRIx32
", pci %08" B_PRIx32
", "
118 "size %08" B_PRIx32
", flags %02x\n", i
, info
->u
.h0
.base_registers
[i
],
119 info
->u
.h0
.base_registers_pci
[i
], info
->u
.h0
.base_register_sizes
[i
],
120 info
->u
.h0
.base_register_flags
[i
]));
125 print_capabilities(const pci_info
*info
)
132 TRACE(("PCI: Capabilities: "));
134 status
= pci_read_config(info
->bus
, info
->device
, info
->function
, PCI_status
, 2);
135 if (!(status
& PCI_status_capabilities
)) {
136 TRACE(("(not supported)\n"));
140 switch (info
->header_type
& PCI_header_type_mask
) {
141 case PCI_header_type_generic
:
142 case PCI_header_type_PCI_to_PCI_bridge
:
143 cap_ptr
= pci_read_config(info
->bus
, info
->device
, info
->function
, PCI_capabilities_ptr
, 1);
145 case PCI_header_type_cardbus
:
146 cap_ptr
= pci_read_config(info
->bus
, info
->device
, info
->function
, PCI_capabilities_ptr_2
, 1);
149 TRACE(("(unknown header type)\n"));
155 TRACE(("(empty list)\n"));
159 for (i
= 0; i
< 48; i
++) {
161 cap_id
= pci_read_config(info
->bus
, info
->device
, info
->function
, cap_ptr
, 1);
162 cap_ptr
= pci_read_config(info
->bus
, info
->device
, info
->function
, cap_ptr
+ 1, 1);
167 name
= get_capability_name(cap_id
);
171 TRACE(("0x%02x", cap_id
));
181 print_extended_capabilities(const pci_info
*info
)
183 if (pci_find_capability(info
->bus
, info
->device
, info
->function
,
184 PCI_cap_id_pcie
, NULL
) != B_OK
)
187 uint16 capPointer
= PCI_extended_capability
;
188 uint32 capability
= pci_read_config(info
->bus
, info
->device
,
189 info
->function
, capPointer
, 4);
190 TRACE(("PCI: Extended capabilities: "));
191 if (capability
== 0 || capability
== 0xffffffff) {
192 TRACE(("(empty list)\n"));
196 for (int i
= 0; i
< 48; i
++) {
200 const char *name
= get_extended_capability_name(
201 PCI_extcap_id(capability
));
205 TRACE(("0x%04" B_PRIx32
, PCI_extcap_id(capability
)));
208 capPointer
= PCI_extcap_next_ptr(capability
) & ~3;
209 if (capPointer
< PCI_extended_capability
)
211 capability
= pci_read_config(info
->bus
, info
->device
, info
->function
,
220 print_info_basic(const pci_info
*info
, bool verbose
)
225 __pci_resolve_virtual_bus(info
->bus
, &domain
, &bus
);
227 TRACE(("PCI: [dom %d, bus %2d] bus %3d, device %2d, function %2d: vendor %04x, device %04x, revision %02x\n",
228 domain
, bus
, info
->bus
/* virtual bus*/,
229 info
->device
, info
->function
, info
->vendor_id
, info
->device_id
, info
->revision
));
230 TRACE(("PCI: class_base %02x, class_function %02x, class_api %02x\n",
231 info
->class_base
, info
->class_sub
, info
->class_api
));
235 const char *venShort
;
237 get_vendor_info(info
->vendor_id
, &venShort
, &venFull
);
238 if (!venShort
&& !venFull
) {
239 TRACE(("PCI: vendor %04x: Unknown\n", info
->vendor_id
));
240 } else if (venShort
&& venFull
) {
241 TRACE(("PCI: vendor %04x: %s - %s\n", info
->vendor_id
, venShort
, venFull
));
243 TRACE(("PCI: vendor %04x: %s\n", info
->vendor_id
, venShort
? venShort
: venFull
));
245 const char *devShort
;
247 get_device_info(info
->vendor_id
, info
->device_id
, info
->u
.h0
.subsystem_vendor_id
, info
->u
.h0
.subsystem_id
,
248 &devShort
, &devFull
);
249 if (!devShort
&& !devFull
) {
250 TRACE(("PCI: device %04x: Unknown\n", info
->device_id
));
251 } else if (devShort
&& devFull
) {
252 TRACE(("PCI: device %04x: %s (%s)\n", info
->device_id
, devShort
, devFull
));
254 TRACE(("PCI: device %04x: %s\n", info
->device_id
, devShort
? devShort
: devFull
));
257 get_class_info(info
->class_base
, info
->class_sub
, info
->class_api
, classInfo
, sizeof(classInfo
));
258 TRACE(("PCI: info: %s\n", classInfo
));
261 TRACE(("PCI: line_size %02x, latency %02x, header_type %02x, BIST %02x\n",
262 info
->line_size
, info
->latency
, info
->header_type
, info
->bist
));
264 switch (info
->header_type
& PCI_header_type_mask
) {
265 case PCI_header_type_generic
:
266 print_generic_info(info
, verbose
);
268 case PCI_header_type_PCI_to_PCI_bridge
:
269 print_pci2pci_bridge_info(info
, verbose
);
271 case PCI_header_type_cardbus
:
272 print_pci2cardbus_bridge_info(info
, verbose
);
275 TRACE(("PCI: unknown header type\n"));
278 print_capabilities(info
);
279 print_extended_capabilities(info
);
287 for (long index
= 0; B_OK
== pci_get_nth_pci_info(index
, &info
); index
++) {
288 print_info_basic(&info
, PCI_VERBOSE
);
294 get_capability_name(uint8 cap_id
)
297 case PCI_cap_id_reserved
:
305 case PCI_cap_id_slotid
:
309 case PCI_cap_id_chswp
:
310 return "CompactPCIHotSwap";
311 case PCI_cap_id_pcix
:
314 return "HyperTransport";
315 case PCI_cap_id_vendspec
:
317 case PCI_cap_id_debugport
:
319 case PCI_cap_id_cpci_rsrcctl
:
320 return "cpci_rsrcctl";
321 case PCI_cap_id_hotplug
:
323 case PCI_cap_id_subvendor
:
325 case PCI_cap_id_agp8x
:
327 case PCI_cap_id_secure_dev
:
328 return "Secure Device";
329 case PCI_cap_id_pcie
:
331 case PCI_cap_id_msix
:
333 case PCI_cap_id_sata
:
335 case PCI_cap_id_pciaf
:
336 return "AdvancedFeatures";
344 get_extended_capability_name(uint16 cap_id
)
347 case PCI_extcap_id_aer
:
348 return "Advanced Error Reporting";
349 case PCI_extcap_id_vc
:
350 return "Virtual Channel";
351 case PCI_extcap_id_serial
:
352 return "Serial Number";
353 case PCI_extcap_id_power_budget
:
354 return "Power Budgeting";
355 case PCI_extcap_id_rcl_decl
:
356 return "Root Complex Link Declaration";
357 case PCI_extcap_id_rcil_ctl
:
358 return "Root Complex Internal Link Control";
359 case PCI_extcap_id_rcec_assoc
:
360 return "Root Complex Event Collector Association";
361 case PCI_extcap_id_mfvc
:
362 return "MultiFunction Virtual Channel";
363 case PCI_extcap_id_vc2
:
364 return "Virtual Channel 2";
365 case PCI_extcap_id_rcrb_header
:
366 return "RCRB Header";
367 case PCI_extcap_id_vendor
:
368 return "Vendor Unique";
369 case PCI_extcap_id_acs
:
370 return "Access Control Services";
371 case PCI_extcap_id_ari
:
372 return "Alternative Routing Id Interpretation";
373 case PCI_extcap_id_ats
:
374 return "Address Translation Services";
375 case PCI_extcap_id_srio_virtual
:
376 return "Single Root I/O Virtualization";
377 case PCI_extcap_id_mrio_virtual
:
378 return "Multiple Root I/O Virtual";
379 case PCI_extcap_id_multicast
:
381 case PCI_extcap_id_page_request
:
382 return "Page Request";
383 case PCI_extcap_id_amd
:
384 return "AMD Reserved";
385 case PCI_extcap_id_resizable_bar
:
386 return "Resizable Bar";
387 case PCI_extcap_id_dyn_power_alloc
:
388 return "Dynamic Power Allocation";
389 case PCI_extcap_id_tph_requester
:
390 return "TPH Requester";
391 case PCI_extcap_id_latency_tolerance
:
392 return "Latency Tolerance Reporting";
393 case PCI_extcap_id_2ndpcie
:
394 return "Secondary PCIe";
395 case PCI_extcap_id_pmux
:
396 return "Protocol Multiplexing";
397 case PCI_extcap_id_pasid
:
398 return "Process Address Space Id";
399 case PCI_extcap_id_ln_requester
:
400 return "LN Requester";
401 case PCI_extcap_id_dpc
:
402 return "Downstream Porto Containment";
403 case PCI_extcap_id_l1pm
:
404 return "L1 Power Management Substates";