2 * Copyright (c) 1997 Zubin D. Dittia. All rights reserved.
3 * Copyright (c) 1995, 1996, 1998
4 * Christopher G. Demetriou. All rights reserved.
5 * Copyright (c) 1994 Charles M. Hannum. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by Charles M. Hannum.
18 * 4. The name of the author may not be used to endorse or promote products
19 * derived from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * PCI autoconfiguration support functions.
37 #include "lib_types.h"
38 #include "lib_string.h"
39 #include "lib_printf.h"
51 const char *pci_findvendor(pcireg_t id_reg
);
53 static void pci_conf_print_ids(pcireg_t rval
, const char *prefix
);
54 static int pci_conf_print_bar (pcitag_t
,
55 const pcireg_t
*, int, const char *, int, int);
58 * Descriptions of known PCI classes and subclasses.
60 * Subclasses are described in the same way as classes, but have a
61 * NULL subclass pointer.
65 int val
; /* as wide as pci_{,sub}class_t */
66 struct pci_class
*subclasses
;
69 struct pci_class pci_subclass_prehistoric
[] = {
70 { "miscellaneous", PCI_SUBCLASS_PREHISTORIC_MISC
, },
71 { "VGA", PCI_SUBCLASS_PREHISTORIC_VGA
, },
75 struct pci_class pci_subclass_mass_storage
[] = {
76 { "SCSI", PCI_SUBCLASS_MASS_STORAGE_SCSI
, },
77 { "IDE", PCI_SUBCLASS_MASS_STORAGE_IDE
, },
78 { "floppy", PCI_SUBCLASS_MASS_STORAGE_FLOPPY
, },
79 { "IPI", PCI_SUBCLASS_MASS_STORAGE_IPI
, },
80 { "RAID", PCI_SUBCLASS_MASS_STORAGE_RAID
, },
81 { "miscellaneous", PCI_SUBCLASS_MASS_STORAGE_MISC
, },
85 struct pci_class pci_subclass_network
[] = {
86 { "ethernet", PCI_SUBCLASS_NETWORK_ETHERNET
, },
87 { "token ring", PCI_SUBCLASS_NETWORK_TOKENRING
, },
88 { "FDDI", PCI_SUBCLASS_NETWORK_FDDI
, },
89 { "ATM", PCI_SUBCLASS_NETWORK_ATM
, },
90 { "ISDN", PCI_SUBCLASS_NETWORK_ISDN
, },
91 { "WorldFip", PCI_SUBCLASS_NETWORK_WORLDFIP
, },
92 { "PCMIG MultiComp", PCI_SUBCLASS_NETWORK_PCIMGMULTICOMP
, },
93 { "miscellaneous", PCI_SUBCLASS_NETWORK_MISC
, },
97 struct pci_class pci_subclass_display
[] = {
98 { "VGA", PCI_SUBCLASS_DISPLAY_VGA
, },
99 { "XGA", PCI_SUBCLASS_DISPLAY_XGA
, },
100 { "3D", PCI_SUBCLASS_DISPLAY_3D
, },
101 { "miscellaneous", PCI_SUBCLASS_DISPLAY_MISC
, },
105 struct pci_class pci_subclass_multimedia
[] = {
106 { "video", PCI_SUBCLASS_MULTIMEDIA_VIDEO
, },
107 { "audio", PCI_SUBCLASS_MULTIMEDIA_AUDIO
, },
108 { "telephony", PCI_SUBCLASS_MULTIMEDIA_TELEPHONY
, },
109 { "miscellaneous", PCI_SUBCLASS_MULTIMEDIA_MISC
, },
113 struct pci_class pci_subclass_memory
[] = {
114 { "RAM", PCI_SUBCLASS_MEMORY_RAM
, },
115 { "flash", PCI_SUBCLASS_MEMORY_FLASH
, },
116 { "miscellaneous", PCI_SUBCLASS_MEMORY_MISC
, },
120 struct pci_class pci_subclass_bridge
[] = {
121 { "host", PCI_SUBCLASS_BRIDGE_HOST
, },
122 { "ISA", PCI_SUBCLASS_BRIDGE_ISA
, },
123 { "EISA", PCI_SUBCLASS_BRIDGE_EISA
, },
124 { "MicroChannel", PCI_SUBCLASS_BRIDGE_MCA
, },
125 { "PCI", PCI_SUBCLASS_BRIDGE_PCI
, },
126 { "PCMCIA", PCI_SUBCLASS_BRIDGE_PCMCIA
, },
127 { "NuBus", PCI_SUBCLASS_BRIDGE_NUBUS
, },
128 { "CardBus", PCI_SUBCLASS_BRIDGE_CARDBUS
, },
129 { "RACEway", PCI_SUBCLASS_BRIDGE_RACEWAY
, },
130 { "Semi-transparent PCI", PCI_SUBCLASS_BRIDGE_STPCI
, },
131 { "InfiniBand", PCI_SUBCLASS_BRIDGE_INFINIBAND
, },
132 { "miscellaneous", PCI_SUBCLASS_BRIDGE_MISC
, },
136 struct pci_class pci_subclass_communications
[] = {
137 { "serial", PCI_SUBCLASS_COMMUNICATIONS_SERIAL
, },
138 { "parallel", PCI_SUBCLASS_COMMUNICATIONS_PARALLEL
, },
139 { "multi-port serial", PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL
, },
140 { "modem", PCI_SUBCLASS_COMMUNICATIONS_MODEM
, },
141 { "miscellaneous", PCI_SUBCLASS_COMMUNICATIONS_MISC
, },
145 struct pci_class pci_subclass_system
[] = {
146 { "8259 PIC", PCI_SUBCLASS_SYSTEM_PIC
, },
147 { "8237 DMA", PCI_SUBCLASS_SYSTEM_DMA
, },
148 { "8254 timer", PCI_SUBCLASS_SYSTEM_TIMER
, },
149 { "RTC", PCI_SUBCLASS_SYSTEM_RTC
, },
150 { "PCI Hot-Plug", PCI_SUBCLASS_SYSTEM_PCIHOTPLUG
, },
151 { "miscellaneous", PCI_SUBCLASS_SYSTEM_MISC
, },
155 struct pci_class pci_subclass_input
[] = {
156 { "keyboard", PCI_SUBCLASS_INPUT_KEYBOARD
, },
157 { "digitizer", PCI_SUBCLASS_INPUT_DIGITIZER
, },
158 { "mouse", PCI_SUBCLASS_INPUT_MOUSE
, },
159 { "scanner", PCI_SUBCLASS_INPUT_SCANNER
, },
160 { "game port", PCI_SUBCLASS_INPUT_GAMEPORT
, },
161 { "miscellaneous", PCI_SUBCLASS_INPUT_MISC
, },
165 struct pci_class pci_subclass_dock
[] = {
166 { "generic", PCI_SUBCLASS_DOCK_GENERIC
, },
167 { "miscellaneous", PCI_SUBCLASS_DOCK_MISC
, },
171 struct pci_class pci_subclass_processor
[] = {
172 { "386", PCI_SUBCLASS_PROCESSOR_386
, },
173 { "486", PCI_SUBCLASS_PROCESSOR_486
, },
174 { "Pentium", PCI_SUBCLASS_PROCESSOR_PENTIUM
, },
175 { "Alpha", PCI_SUBCLASS_PROCESSOR_ALPHA
, },
176 { "PowerPC", PCI_SUBCLASS_PROCESSOR_POWERPC
, },
177 { "MIPS", PCI_SUBCLASS_PROCESSOR_MIPS
, },
178 { "Co-processor", PCI_SUBCLASS_PROCESSOR_COPROC
, },
182 struct pci_class pci_subclass_serialbus
[] = {
183 { "Firewire", PCI_SUBCLASS_SERIALBUS_FIREWIRE
, },
184 { "ACCESS.bus", PCI_SUBCLASS_SERIALBUS_ACCESS
, },
185 { "SSA", PCI_SUBCLASS_SERIALBUS_SSA
, },
186 { "USB", PCI_SUBCLASS_SERIALBUS_USB
, },
187 { "Fiber Channel", PCI_SUBCLASS_SERIALBUS_FIBER
, },
188 { "SMBus", PCI_SUBCLASS_SERIALBUS_SMBUS
, },
189 { "InfiniBand", PCI_SUBCLASS_SERIALBUS_INFINIBAND
, },
190 { "IPMI", PCI_SUBCLASS_SERIALBUS_IPMI
, },
191 { "SERCOS", PCI_SUBCLASS_SERIALBUS_SERCOS
, },
192 { "CANbus", PCI_SUBCLASS_SERIALBUS_CANBUS
, },
196 struct pci_class pci_subclass_wireless
[] = {
197 { "iRDA", PCI_SUBCLASS_WIRELESS_IRDA
, },
198 { "Consumer IR", PCI_SUBCLASS_WIRELESS_CONSUMERIR
, },
199 { "RF", PCI_SUBCLASS_WIRELESS_RF
, },
200 { "miscellaneous", PCI_SUBCLASS_WIRELESS_MISC
, },
204 struct pci_class pci_subclass_i2o
[] = {
205 { "1.0", PCI_SUBCLASS_I2O_STANDARD
, },
209 struct pci_class pci_subclass_satcom
[] = {
210 { "TV", PCI_SUBCLASS_SATCOM_TV
, },
211 { "audio", PCI_SUBCLASS_SATCOM_AUDIO
, },
212 { "voice", PCI_SUBCLASS_SATCOM_VOICE
, },
213 { "data", PCI_SUBCLASS_SATCOM_DATA
, },
217 struct pci_class pci_subclass_crypto
[] = {
218 { "network/computing", PCI_SUBCLASS_CRYPTO_NETCOMP
, },
219 { "entertainment", PCI_SUBCLASS_CRYPTO_ENTERTAINMENT
, },
220 { "miscellaneous", PCI_SUBCLASS_CRYPTO_MISC
, },
224 struct pci_class pci_subclass_dasp
[] = {
225 { "DPIO", PCI_SUBCLASS_DASP_DPIO
, },
226 { "time and frequency", PCI_SUBCLASS_DASP_TIMERFREQ
, },
227 { "miscellaneous", PCI_SUBCLASS_DASP_MISC
, },
231 struct pci_class pci_class
[] = {
232 { "prehistoric", PCI_CLASS_PREHISTORIC
,
233 pci_subclass_prehistoric
, },
234 { "mass storage", PCI_CLASS_MASS_STORAGE
,
235 pci_subclass_mass_storage
, },
236 { "network", PCI_CLASS_NETWORK
,
237 pci_subclass_network
, },
238 { "display", PCI_CLASS_DISPLAY
,
239 pci_subclass_display
, },
240 { "multimedia", PCI_CLASS_MULTIMEDIA
,
241 pci_subclass_multimedia
, },
242 { "memory", PCI_CLASS_MEMORY
,
243 pci_subclass_memory
, },
244 { "bridge", PCI_CLASS_BRIDGE
,
245 pci_subclass_bridge
, },
246 { "communications", PCI_CLASS_COMMUNICATIONS
,
247 pci_subclass_communications
, },
248 { "system", PCI_CLASS_SYSTEM
,
249 pci_subclass_system
, },
250 { "input", PCI_CLASS_INPUT
,
251 pci_subclass_input
, },
252 { "dock", PCI_CLASS_DOCK
,
253 pci_subclass_dock
, },
254 { "processor", PCI_CLASS_PROCESSOR
,
255 pci_subclass_processor
, },
256 { "serial bus", PCI_CLASS_SERIALBUS
,
257 pci_subclass_serialbus
, },
258 { "wireless", PCI_CLASS_WIRELESS
,
259 pci_subclass_wireless
, },
260 { "I2O", PCI_CLASS_I2O
,
262 { "satellite comm", PCI_CLASS_SATCOM
,
263 pci_subclass_satcom
, },
264 { "crypto", PCI_CLASS_CRYPTO
,
265 pci_subclass_crypto
, },
266 { "DASP", PCI_CLASS_DASP
,
267 pci_subclass_dasp
, },
268 { "undefined", PCI_CLASS_UNDEFINED
,
275 * Descriptions of of known vendors and devices ("products").
279 struct pci_knowndev2
{
280 pci_vendor_id_t vendor
;
281 pci_product_id_t product
;
283 int vendorname
, productname
;
285 #define PCI_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
286 #include "pcidevs_data2.h"
289 pci_findvendor(pcireg_t id_reg
)
291 pci_vendor_id_t vendor
= PCI_VENDOR(id_reg
);
292 const struct pci_knowndev2
*kdp
;
295 while (kdp
->vendorname
!= PCI_STRING_NULL
) { /* all have vendor name */
296 if (kdp
->vendor
== vendor
)
300 if (kdp
->vendorname
== PCI_STRING_NULL
) return NULL
;
301 return PCI_STRING(kdp
->vendorname
);
305 pci_findvendor(pcireg_t id_reg
)
309 #endif /* PCIVERBOSE */
312 pci_devinfo(pcireg_t id_reg
, pcireg_t class_reg
, int showclass
, char *cp
)
314 pci_vendor_id_t vendor
;
315 pci_product_id_t product
;
317 pci_subclass_t subclass
;
318 pci_interface_t interface
;
319 pci_revision_t revision
;
320 const char *vendor_namep
, *product_namep
;
321 struct pci_class
*classp
, *subclassp
;
323 const struct pci_knowndev2
*kdp
;
324 const char *unmatched
= "unknown ";
326 const char *unmatched
= "";
329 vendor
= PCI_VENDOR(id_reg
);
330 product
= PCI_PRODUCT(id_reg
);
332 class = PCI_CLASS(class_reg
);
333 subclass
= PCI_SUBCLASS(class_reg
);
334 interface
= PCI_INTERFACE(class_reg
);
335 revision
= PCI_REVISION(class_reg
);
339 while (kdp
->vendorname
!= PCI_STRING_NULL
) { /* all have vendor name */
340 if (kdp
->vendor
== vendor
&& (kdp
->product
== product
||
341 (kdp
->flags
& PCI_KNOWNDEV_NOPROD
) != 0))
345 if (kdp
->vendorname
== PCI_STRING_NULL
)
346 vendor_namep
= product_namep
= NULL
;
348 vendor_namep
= PCI_STRING(kdp
->vendorname
);
349 product_namep
= ((kdp
->flags
& PCI_KNOWNDEV_NOPROD
) == 0 ?
350 PCI_STRING(kdp
->productname
) : NULL
);
352 #else /* PCIVERBOSE */
353 vendor_namep
= product_namep
= NULL
;
354 #endif /* PCIVERBOSE */
357 while (classp
->name
!= NULL
) {
358 if (class == classp
->val
)
363 subclassp
= (classp
->name
!= NULL
) ? classp
->subclasses
: NULL
;
364 while (subclassp
&& subclassp
->name
!= NULL
) {
365 if (subclass
== subclassp
->val
)
370 if (vendor_namep
== NULL
)
371 cp
+= sprintf(cp
, "%svendor 0x%04x product 0x%04x",
372 unmatched
, vendor
, product
);
373 else if (product_namep
!= NULL
)
374 cp
+= sprintf(cp
, "%s %s", vendor_namep
, product_namep
);
376 cp
+= sprintf(cp
, "%s product 0x%04x", vendor_namep
, product
);
378 cp
+= sprintf(cp
, " (");
379 if (classp
->name
== NULL
)
380 cp
+= sprintf(cp
, "class 0x%02x, subclass 0x%02x",
383 if (subclassp
== NULL
|| subclassp
->name
== NULL
)
384 cp
+= sprintf(cp
, "%s subclass 0x%02x",
385 classp
->name
, subclass
);
387 cp
+= sprintf(cp
, "%s %s", subclassp
->name
, classp
->name
);
390 cp
+= sprintf(cp
, ", interface 0x%02x", interface
);
392 cp
+= sprintf(cp
, ", rev 0x%02x", revision
);
393 cp
+= sprintf(cp
, ")");
399 * Support routines for printing out PCI configuration registers.
402 #define i2o(i) ((i) * 4)
403 #define o2i(o) ((o) / 4)
404 #define onoff(str, bit) \
406 printf(" %s: %s\n", (str), (rval & (bit)) ? "on" : "off"); \
411 pci_conf_print_ids(pcireg_t rval
, const char *prefix
)
413 const struct pci_knowndev2
*kdp
;
415 for (kdp
= pci_knowndevs
; kdp
->vendorname
!= PCI_STRING_NULL
; kdp
++) {
416 if (kdp
->vendor
== PCI_VENDOR(rval
) &&
417 (kdp
->product
== PCI_PRODUCT(rval
) ||
418 (kdp
->flags
& PCI_KNOWNDEV_NOPROD
) != 0)) {
422 if (kdp
->vendorname
!= PCI_STRING_NULL
)
423 printf("%sVendor Name: %s (0x%04x)\n", prefix
,
424 PCI_STRING(kdp
->vendorname
), PCI_VENDOR(rval
));
426 printf("%sVendor ID: 0x%04x\n", prefix
, PCI_VENDOR(rval
));
427 if (kdp
->productname
!= PCI_STRING_NULL
428 && (kdp
->flags
& PCI_KNOWNDEV_NOPROD
) == 0)
429 printf("%sDevice Name: %s (0x%04x)\n", prefix
,
430 PCI_STRING(kdp
->productname
), PCI_PRODUCT(rval
));
432 printf("%sDevice ID: 0x%04x\n", prefix
, PCI_PRODUCT(rval
));
436 pci_conf_print_ids(pcireg_t rval
, const char *prefix
)
438 printf("%sVendor ID: 0x%04x\n", prefix
, PCI_VENDOR(rval
));
439 printf("%sDevice ID: 0x%04x\n", prefix
, PCI_PRODUCT(rval
));
441 #endif /* PCIVERBOSE */
445 pcitag_t tag
, const pcireg_t
*regs
,
446 int reg
, const char *name
,
447 int sizebar
, int onlyimpl
)
451 pcireg_t mask64h
, rval64h
;
454 mask64h
= rval64h
= 0;
460 * Section 6.2.5.1, `Address Maps', tells us that:
462 * 1) The builtin software should have already mapped the
463 * device in a reasonable way.
465 * 2) A device which wants 2^n bytes of memory will hardwire
466 * the bottom n bits of the address to 0. As recommended,
467 * we write all 1s and see what we get back.
469 rval
= regs
[o2i(reg
)];
470 if (rval
!= 0 && sizebar
) {
474 * The following sequence seems to make some devices
475 * (e.g. host bus bridges, which don't normally
476 * have their space mapped) very unhappy, to
477 * the point of crashing the system.
479 * Therefore, if the mapping register is zero to
480 * start out with, don't bother trying.
483 cmdreg
= pci_conf_read(tag
, PCI_COMMAND_STATUS_REG
);
484 cmdreg
&= (PCI_COMMAND_MASK
<< PCI_COMMAND_SHIFT
); /* keep status */
485 pci_conf_write(tag
, PCI_COMMAND_STATUS_REG
,
486 cmdreg
& ~(PCI_COMMAND_IO_ENABLE
| PCI_COMMAND_MEM_ENABLE
));
488 pci_conf_write(tag
, reg
, 0xffffffff);
489 mask
= pci_conf_read(tag
, reg
);
490 pci_conf_write(tag
, reg
, rval
);
491 if (PCI_MAPREG_TYPE(rval
) == PCI_MAPREG_TYPE_MEM
&&
492 PCI_MAPREG_MEM_TYPE(rval
) == PCI_MAPREG_MEM_TYPE_64BIT
) {
493 rval64h
= regs
[o2i(reg
+ 4)];
494 pci_conf_write(tag
, reg
+ 4, 0xffffffff);
495 mask64h
= pci_conf_read(tag
, reg
+ 4);
496 pci_conf_write(tag
, reg
+ 4, rval64h
);
500 pci_conf_write(tag
, PCI_COMMAND_STATUS_REG
, cmdreg
);
504 if (rval
== 0 && onlyimpl
)
507 printf(" Base Address Register at 0x%02x", reg
);
509 printf(" (%s)", name
);
512 printf("not implemented(?)\n");
516 if (PCI_MAPREG_TYPE(rval
) == PCI_MAPREG_TYPE_MEM
) {
517 const char *type
, *prefetch
;
519 switch (PCI_MAPREG_MEM_TYPE(rval
)) {
520 case PCI_MAPREG_MEM_TYPE_32BIT
:
523 case PCI_MAPREG_MEM_TYPE_32BIT_1M
:
526 case PCI_MAPREG_MEM_TYPE_64BIT
:
530 type
= "unknown (XXX)";
533 if (PCI_MAPREG_MEM_PREFETCHABLE(rval
))
537 printf("%s %sprefetchable memory\n", type
, prefetch
);
538 switch (PCI_MAPREG_MEM_TYPE(rval
)) {
539 case PCI_MAPREG_MEM_TYPE_64BIT
:
540 printf(" base: 0x%016llx, ",
541 PCI_MAPREG_MEM64_ADDR(
542 ((((long long) rval64h
) << 32) | rval
)));
544 printf("size: 0x%016llx",
545 PCI_MAPREG_MEM64_SIZE(
546 ((((long long) mask64h
) << 32) | mask
)));
551 case PCI_MAPREG_MEM_TYPE_32BIT
:
552 case PCI_MAPREG_MEM_TYPE_32BIT_1M
:
554 printf(" base: 0x%08x, ", PCI_MAPREG_MEM_ADDR(rval
));
556 printf("size: 0x%08x", PCI_MAPREG_MEM_SIZE(mask
));
564 printf("%d-bit ", mask
& ~0x0000ffff ? 32 : 16);
566 printf(" base: 0x%08x, ", PCI_MAPREG_IO_ADDR(rval
));
568 printf("size: 0x%08x", PCI_MAPREG_IO_SIZE(mask
));
578 /* Summary printing: Display device ID, status, memory map only. */
580 #define on(str, bit) \
581 do { if (rval & (bit)) printf(" %s: on\n", (str)); } while (0)
584 pci_conf_print(pcitag_t tag
)
586 pcireg_t regs
[o2i(256)];
589 uint32_t base
, limit
;
592 if (!pci_probe_tag(tag
)) {
593 printf("no device\n");
597 for (off
= 0; off
< 256; off
+= 4)
598 regs
[o2i(off
)] = pci_conf_read(tag
, off
);
600 rval
= regs
[o2i(PCI_ID_REG
)];
601 pci_conf_print_ids(rval
, " ");
603 rval
= regs
[o2i(PCI_COMMAND_STATUS_REG
)];
605 printf(" Command: 0x%04x\n", rval
& 0xffff);
606 on("I/O space accesses", PCI_COMMAND_IO_ENABLE
);
607 on("Memory space accesses", PCI_COMMAND_MEM_ENABLE
);
608 on("Bus mastering", PCI_COMMAND_MASTER_ENABLE
);
610 printf(" Status: 0x%04x\n", PCI_STATUS(rval
));
611 on("Slave signaled Target Abort", PCI_STATUS_TARGET_TARGET_ABORT
);
612 on("Master received Target Abort", PCI_STATUS_MASTER_TARGET_ABORT
);
613 on("Master received Master Abort", PCI_STATUS_MASTER_ABORT
);
614 on("Asserted System Error (SERR)", PCI_STATUS_SYSTEM_ERROR
);
615 on("Parity error detected", PCI_STATUS_PARITY_DETECT
);
617 switch (PCI_HDRTYPE_TYPE(regs
[o2i(PCI_BHLC_REG
)])) {
619 /* Standard device header */
620 printf(" Type 0 (normal) header:\n");
622 /* sizing host BARs is often bad news */
624 if (PCI_CLASS(regs
[o2i(PCI_CLASS_REG
)]) == PCI_CLASS_BRIDGE
&&
625 PCI_SUBCLASS(regs
[o2i(PCI_CLASS_REG
)]) == PCI_SUBCLASS_BRIDGE_HOST
)
627 for (off
= PCI_MAPREG_START
; off
< PCI_MAPREG_END
; off
+= width
)
628 width
= pci_conf_print_bar(tag
, regs
, off
, NULL
, sizebars
, 1);
630 rval
= regs
[o2i(PCI_BPARAM_INTERRUPT_REG
)];
631 printf(" Interrupt Line: 0x%02x\n", PCI_INTERRUPT_LINE(rval
));
635 /* PCI-PCI bridge header */
636 printf(" Type 1 (PCI-PCI bridge) header:\n");
638 rval
= regs
[o2i(PPB_BUSINFO_REG
)];
640 printf(" Primary: %d,", PPB_BUSINFO_PRIMARY(rval
));
641 printf(" Secondary: %d,", PPB_BUSINFO_SECONDARY(rval
));
642 printf(" Subordinate: %d\n", PPB_BUSINFO_SUBORD(rval
));
644 rval
= regs
[o2i(PPB_IO_STATUS_REG
)];
645 printf(" Secondary Status: 0x%04x\n", PPB_SECSTATUS(rval
));
646 on(" Data parity error detected", PCI_STATUS_PARITY_ERROR
);
647 on(" Signaled Target Abort", PCI_STATUS_TARGET_TARGET_ABORT
);
648 on(" Received Target Abort", PCI_STATUS_MASTER_TARGET_ABORT
);
649 on(" Received Master Abort", PCI_STATUS_MASTER_ABORT
);
650 on(" System Error", PCI_STATUS_SYSTEM_ERROR
);
651 on(" Parity Error", PCI_STATUS_PARITY_DETECT
);
653 rval
= regs
[o2i(PPB_IO_STATUS_REG
)];
654 base
= PPB_IO_BASE(rval
);
655 limit
= PPB_IO_LIMIT(rval
);
656 if (base
!= 0 || limit
!= 0) {
657 printf(" I/O Range:\n");
659 if ((base
& 0xf) != 0 || (limit
& 0xf) != 0) {
660 base
= ((base
& 0xf0) << 8) | 0x000;
661 limit
= ((limit
& 0xf0) << 8) | 0xfff;
662 rval
= regs
[o2i(PPB_IO_UPPER_REG
)];
663 base
|= PPB_BASE(rval
) << 16;
664 limit
|= PPB_LIMIT(rval
) << 16;
665 printf(" base: 0x%08x, limit: 0x%08x\n", base
, limit
);
667 base
= (base
<< 8) | 0x000;
668 limit
= (limit
<< 8) | 0xfff;
669 printf(" base: 0x%04x, limit: 0x%04x\n", base
, limit
);
673 base
= PPB_BASE(regs
[o2i(PPB_MEM_REG
)]) & 0xfff0;
674 limit
= PPB_LIMIT(regs
[o2i(PPB_MEM_REG
)]) & 0xfff0;
675 printf(" Memory Range:\n");
676 base
= (base
<< 16) | 0x00000;
677 limit
= (limit
<< 16) | 0xfffff;
678 printf(" base: 0x%08x, limit: 0x%08x\n", base
, limit
);
680 base
= PPB_BASE(regs
[o2i(PPB_PREFMEM_REG
)]) & 0xffff;
681 limit
= PPB_LIMIT(regs
[o2i(PPB_PREFMEM_REG
)]) & 0xffff;
682 if (base
!= 0 || limit
!= 0
683 || regs
[o2i(PPB_PREFMEM_BASE_UPPER_REG
)] != 0
684 || regs
[o2i(PPB_PREFMEM_LIMIT_UPPER_REG
)] != 0) {
685 printf(" Prefetchable Memory Range:\n");
686 if ((base
& 0xf) != 0 || (limit
& 0xf) != 0) {
687 base
= ((base
& 0xfff0) << 16) | 0x00000;
688 limit
= ((limit
& 0xfff0) << 16) | 0xfffff;
689 printf(" base: 0x%08x%08x, limit: 0x%08x%08x\n",
690 regs
[o2i(PPB_PREFMEM_BASE_UPPER_REG
)], base
,
691 regs
[o2i(PPB_PREFMEM_LIMIT_UPPER_REG
)], limit
);
693 base
= (base
<< 16) | 0x00000;
694 limit
= (limit
<< 16) | 0xfffff;
695 printf(" base: 0x%08x, limit: 0x%08x\n", base
, limit
);
699 if (regs
[o2i(PPB_MAPREG_ROM
)] != 0)
700 printf(" Expansion ROM Base Address: 0x%08x\n",
701 regs
[o2i(PPB_MAPREG_ROM
)]);