Home | History | Annotate | Line # | Download | only in pci
pci_subr.c revision 1.24
      1 /*	$NetBSD: pci_subr.c,v 1.24 1998/05/03 19:41:33 thorpej Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
      5  * Copyright (c) 1995, 1996 Christopher G. Demetriou.  All rights reserved.
      6  * Copyright (c) 1994 Charles Hannum.  All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *	This product includes software developed by Charles Hannum.
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /*
     35  * PCI autoconfiguration support functions.
     36  */
     37 
     38 #include "opt_pciverbose.h"
     39 
     40 #include <sys/param.h>
     41 #include <sys/systm.h>
     42 #include <sys/device.h>
     43 
     44 #include <machine/intr.h>
     45 
     46 #include <dev/pci/pcireg.h>
     47 #include <dev/pci/pcivar.h>
     48 #ifdef PCIVERBOSE
     49 #include <dev/pci/pcidevs.h>
     50 #endif
     51 
     52 /*
     53  * Descriptions of known PCI classes and subclasses.
     54  *
     55  * Subclasses are described in the same way as classes, but have a
     56  * NULL subclass pointer.
     57  */
     58 struct pci_class {
     59 	char		*name;
     60 	int		val;		/* as wide as pci_{,sub}class_t */
     61 	struct pci_class *subclasses;
     62 };
     63 
     64 struct pci_class pci_subclass_prehistoric[] = {
     65 	{ "miscellaneous",	PCI_SUBCLASS_PREHISTORIC_MISC,		},
     66 	{ "VGA",		PCI_SUBCLASS_PREHISTORIC_VGA,		},
     67 	{ 0 }
     68 };
     69 
     70 struct pci_class pci_subclass_mass_storage[] = {
     71 	{ "SCSI",		PCI_SUBCLASS_MASS_STORAGE_SCSI,		},
     72 	{ "IDE",		PCI_SUBCLASS_MASS_STORAGE_IDE,		},
     73 	{ "floppy",		PCI_SUBCLASS_MASS_STORAGE_FLOPPY,	},
     74 	{ "IPI",		PCI_SUBCLASS_MASS_STORAGE_IPI,		},
     75 	{ "RAID",		PCI_SUBCLASS_MASS_STORAGE_RAID,		},
     76 	{ "miscellaneous",	PCI_SUBCLASS_MASS_STORAGE_MISC,		},
     77 	{ 0 },
     78 };
     79 
     80 struct pci_class pci_subclass_network[] = {
     81 	{ "ethernet",		PCI_SUBCLASS_NETWORK_ETHERNET,		},
     82 	{ "token ring",		PCI_SUBCLASS_NETWORK_TOKENRING,		},
     83 	{ "FDDI",		PCI_SUBCLASS_NETWORK_FDDI,		},
     84 	{ "ATM",		PCI_SUBCLASS_NETWORK_ATM,		},
     85 	{ "miscellaneous",	PCI_SUBCLASS_NETWORK_MISC,		},
     86 	{ 0 },
     87 };
     88 
     89 struct pci_class pci_subclass_display[] = {
     90 	{ "VGA",		PCI_SUBCLASS_DISPLAY_VGA,		},
     91 	{ "XGA",		PCI_SUBCLASS_DISPLAY_XGA,		},
     92 	{ "miscellaneous",	PCI_SUBCLASS_DISPLAY_MISC,		},
     93 	{ 0 },
     94 };
     95 
     96 struct pci_class pci_subclass_multimedia[] = {
     97 	{ "video",		PCI_SUBCLASS_MULTIMEDIA_VIDEO,		},
     98 	{ "audio",		PCI_SUBCLASS_MULTIMEDIA_AUDIO,		},
     99 	{ "miscellaneous",	PCI_SUBCLASS_MULTIMEDIA_MISC,		},
    100 	{ 0 },
    101 };
    102 
    103 struct pci_class pci_subclass_memory[] = {
    104 	{ "RAM",		PCI_SUBCLASS_MEMORY_RAM,		},
    105 	{ "flash",		PCI_SUBCLASS_MEMORY_FLASH,		},
    106 	{ "miscellaneous",	PCI_SUBCLASS_MEMORY_MISC,		},
    107 	{ 0 },
    108 };
    109 
    110 struct pci_class pci_subclass_bridge[] = {
    111 	{ "host",		PCI_SUBCLASS_BRIDGE_HOST,		},
    112 	{ "ISA",		PCI_SUBCLASS_BRIDGE_ISA,		},
    113 	{ "EISA",		PCI_SUBCLASS_BRIDGE_EISA,		},
    114 	{ "MicroChannel",	PCI_SUBCLASS_BRIDGE_MC,			},
    115 	{ "PCI",		PCI_SUBCLASS_BRIDGE_PCI,		},
    116 	{ "PCMCIA",		PCI_SUBCLASS_BRIDGE_PCMCIA,		},
    117 	{ "NuBus",		PCI_SUBCLASS_BRIDGE_NUBUS,		},
    118 	{ "CardBus",		PCI_SUBCLASS_BRIDGE_CARDBUS,		},
    119 	{ "miscellaneous",	PCI_SUBCLASS_BRIDGE_MISC,		},
    120 	{ 0 },
    121 };
    122 
    123 struct pci_class pci_subclass_communications[] = {
    124 	{ "serial",		PCI_SUBCLASS_COMMUNICATIONS_SERIAL,	},
    125 	{ "parallel",		PCI_SUBCLASS_COMMUNICATIONS_PARALLEL,	},
    126 	{ "miscellaneous",	PCI_SUBCLASS_COMMUNICATIONS_MISC,	},
    127 	{ 0 },
    128 };
    129 
    130 struct pci_class pci_subclass_system[] = {
    131 	{ "8259 PIC",		PCI_SUBCLASS_SYSTEM_PIC,		},
    132 	{ "8237 DMA",		PCI_SUBCLASS_SYSTEM_DMA,		},
    133 	{ "8254 timer",		PCI_SUBCLASS_SYSTEM_TIMER,		},
    134 	{ "RTC",		PCI_SUBCLASS_SYSTEM_RTC,		},
    135 	{ "miscellaneous",	PCI_SUBCLASS_SYSTEM_MISC,		},
    136 	{ 0 },
    137 };
    138 
    139 struct pci_class pci_subclass_input[] = {
    140 	{ "keyboard",		PCI_SUBCLASS_INPUT_KEYBOARD,		},
    141 	{ "digitizer",		PCI_SUBCLASS_INPUT_DIGITIZER,		},
    142 	{ "mouse",		PCI_SUBCLASS_INPUT_MOUSE,		},
    143 	{ "miscellaneous",	PCI_SUBCLASS_INPUT_MISC,		},
    144 	{ 0 },
    145 };
    146 
    147 struct pci_class pci_subclass_dock[] = {
    148 	{ "generic",		PCI_SUBCLASS_DOCK_GENERIC,		},
    149 	{ "miscellaneous",	PCI_SUBCLASS_DOCK_MISC,			},
    150 	{ 0 },
    151 };
    152 
    153 struct pci_class pci_subclass_processor[] = {
    154 	{ "386",		PCI_SUBCLASS_PROCESSOR_386,		},
    155 	{ "486",		PCI_SUBCLASS_PROCESSOR_486,		},
    156 	{ "Pentium",		PCI_SUBCLASS_PROCESSOR_PENTIUM,		},
    157 	{ "Alpha",		PCI_SUBCLASS_PROCESSOR_ALPHA,		},
    158 	{ "PowerPC",		PCI_SUBCLASS_PROCESSOR_POWERPC,		},
    159 	{ "Co-processor",	PCI_SUBCLASS_PROCESSOR_COPROC,		},
    160 	{ 0 },
    161 };
    162 
    163 struct pci_class pci_subclass_serialbus[] = {
    164 	{ "Firewire",		PCI_SUBCLASS_SERIALBUS_FIREWIRE,	},
    165 	{ "ACCESS.bus",		PCI_SUBCLASS_SERIALBUS_ACCESS,		},
    166 	{ "SSA",		PCI_SUBCLASS_SERIALBUS_SSA,		},
    167 	{ "USB",		PCI_SUBCLASS_SERIALBUS_USB,		},
    168 	{ "Fiber Channel",	PCI_SUBCLASS_SERIALBUS_FIBER,		},
    169 	{ 0 },
    170 };
    171 
    172 struct pci_class pci_class[] = {
    173 	{ "prehistoric",	PCI_CLASS_PREHISTORIC,
    174 	    pci_subclass_prehistoric,				},
    175 	{ "mass storage",	PCI_CLASS_MASS_STORAGE,
    176 	    pci_subclass_mass_storage,				},
    177 	{ "network",		PCI_CLASS_NETWORK,
    178 	    pci_subclass_network,				},
    179 	{ "display",		PCI_CLASS_DISPLAY,
    180 	    pci_subclass_display,				},
    181 	{ "multimedia",		PCI_CLASS_MULTIMEDIA,
    182 	    pci_subclass_multimedia,				},
    183 	{ "memory",		PCI_CLASS_MEMORY,
    184 	    pci_subclass_memory,				},
    185 	{ "bridge",		PCI_CLASS_BRIDGE,
    186 	    pci_subclass_bridge,				},
    187 	{ "communications",	PCI_CLASS_COMMUNICATIONS,
    188 	    pci_subclass_communications,			},
    189 	{ "system",		PCI_CLASS_SYSTEM,
    190 	    pci_subclass_system,				},
    191 	{ "input",		PCI_CLASS_INPUT,
    192 	    pci_subclass_input,					},
    193 	{ "dock",		PCI_CLASS_DOCK,
    194 	    pci_subclass_dock,					},
    195 	{ "processor",		PCI_CLASS_PROCESSOR,
    196 	    pci_subclass_processor,				},
    197 	{ "serial bus",		PCI_CLASS_SERIALBUS,
    198 	    pci_subclass_serialbus,				},
    199 	{ "undefined",		PCI_CLASS_UNDEFINED,
    200 	    0,							},
    201 	{ 0 },
    202 };
    203 
    204 #ifdef PCIVERBOSE
    205 /*
    206  * Descriptions of of known vendors and devices ("products").
    207  */
    208 struct pci_knowndev {
    209 	pci_vendor_id_t		vendor;
    210 	pci_product_id_t	product;
    211 	int			flags;
    212 	char			*vendorname, *productname;
    213 };
    214 #define	PCI_KNOWNDEV_NOPROD	0x01		/* match on vendor only */
    215 
    216 #include <dev/pci/pcidevs_data.h>
    217 #endif /* PCIVERBOSE */
    218 
    219 void
    220 pci_devinfo(id_reg, class_reg, showclass, cp)
    221 	pcireg_t id_reg, class_reg;
    222 	int showclass;
    223 	char *cp;
    224 {
    225 	pci_vendor_id_t vendor;
    226 	pci_product_id_t product;
    227 	pci_class_t class;
    228 	pci_subclass_t subclass;
    229 	pci_interface_t interface;
    230 	pci_revision_t revision;
    231 	char *vendor_namep, *product_namep;
    232 	struct pci_class *classp, *subclassp;
    233 #ifdef PCIVERBOSE
    234 	struct pci_knowndev *kdp;
    235 	const char *unmatched = "unknown ";
    236 #else
    237 	const char *unmatched = "";
    238 #endif
    239 
    240 	vendor = PCI_VENDOR(id_reg);
    241 	product = PCI_PRODUCT(id_reg);
    242 
    243 	class = PCI_CLASS(class_reg);
    244 	subclass = PCI_SUBCLASS(class_reg);
    245 	interface = PCI_INTERFACE(class_reg);
    246 	revision = PCI_REVISION(class_reg);
    247 
    248 #ifdef PCIVERBOSE
    249 	kdp = pci_knowndevs;
    250         while (kdp->vendorname != NULL) {	/* all have vendor name */
    251                 if (kdp->vendor == vendor && (kdp->product == product ||
    252 		    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0))
    253                         break;
    254 		kdp++;
    255 	}
    256         if (kdp->vendorname == NULL)
    257 		vendor_namep = product_namep = NULL;
    258 	else {
    259 		vendor_namep = kdp->vendorname;
    260 		product_namep = (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0 ?
    261 		    kdp->productname : NULL;
    262         }
    263 #else /* PCIVERBOSE */
    264 	vendor_namep = product_namep = NULL;
    265 #endif /* PCIVERBOSE */
    266 
    267 	classp = pci_class;
    268 	while (classp->name != NULL) {
    269 		if (class == classp->val)
    270 			break;
    271 		classp++;
    272 	}
    273 
    274 	subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
    275 	while (subclassp && subclassp->name != NULL) {
    276 		if (subclass == subclassp->val)
    277 			break;
    278 		subclassp++;
    279 	}
    280 
    281 	if (vendor_namep == NULL)
    282 		cp += sprintf(cp, "%svendor 0x%04x product 0x%04x",
    283 		    unmatched, vendor, product);
    284 	else if (product_namep != NULL)
    285 		cp += sprintf(cp, "%s %s", vendor_namep, product_namep);
    286 	else
    287 		cp += sprintf(cp, "%s product 0x%04x",
    288 		    vendor_namep, product);
    289 	if (showclass) {
    290 		cp += sprintf(cp, " (");
    291 		if (classp->name == NULL)
    292 			cp += sprintf(cp, "class 0x%02x, subclass 0x%02x",
    293 			    class, subclass);
    294 		else {
    295 			if (subclassp == NULL || subclassp->name == NULL)
    296 				cp += sprintf(cp,
    297 				    "%s subclass 0x%02x",
    298 				    classp->name, subclass);
    299 			else
    300 				cp += sprintf(cp, "%s %s",
    301 				    subclassp->name, classp->name);
    302 		}
    303 		if (interface != 0)
    304 			cp += sprintf(cp, ", interface 0x%02x", interface);
    305 		if (revision != 0)
    306 			cp += sprintf(cp, ", revision 0x%02x", revision);
    307 		cp += sprintf(cp, ")");
    308 	}
    309 }
    310 
    311 /*
    312  * Print out most of the PCI configuration registers.  Typically used
    313  * in a device attach routine like this:
    314  *
    315  *	#ifdef MYDEV_DEBUG
    316  *		printf("%s: ", sc->sc_dev.dv_xname);
    317  *		pci_conf_print(pa->pa_pc, pa->pa_tag);
    318  *	#endif
    319  */
    320 void
    321 pci_conf_print(pc, tag)
    322 	pci_chipset_tag_t pc;
    323 	pcitag_t tag;
    324 {
    325 	pcireg_t rval, mask;
    326 	int reg, s;
    327 #ifdef PCIVERBOSE
    328 	struct pci_knowndev *kdp;
    329 	static const char on_str[] = "ON", off_str[] = "OFF";
    330 #endif
    331 	struct pci_class *classp, *subclassp;
    332 
    333 	printf("PCI configuration registers:\n");
    334 
    335 	rval = pci_conf_read(pc, tag, PCI_ID_REG);
    336 
    337 #ifndef PCIVERBOSE
    338 	printf("  Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
    339 	printf("  Device ID: 0x%04x\n", PCI_PRODUCT(rval));
    340 #else
    341 	for (kdp = pci_knowndevs; kdp->vendorname != NULL; kdp++) {
    342 		if (kdp->vendor == PCI_VENDOR(rval) &&
    343 		    (kdp->product == PCI_PRODUCT(rval) ||
    344 		    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0)) {
    345 			break;
    346 		}
    347 	}
    348 	if (kdp->vendorname != NULL)
    349 		printf("  Vendor Name: %s\n", kdp->vendorname);
    350 	else
    351 		printf("  Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
    352 
    353 	if (kdp->productname != NULL && (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0)
    354 		printf("  Device Name: %s\n", kdp->productname);
    355 	else
    356 		printf("  Device ID: 0x%04x\n", PCI_PRODUCT(rval));
    357 #endif /* PCIVERBOSE */
    358 
    359 	rval = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
    360 
    361 #ifndef PCIVERBOSE
    362 	printf("  Command/Status Register: 0x%08x\n", rval);
    363 #else
    364 
    365 #define	onoff(reg)	((rval & (reg)) ? on_str : off_str)
    366 	printf("  Command Register:\n");
    367 	printf("    I/O space accesses %s\n", onoff(PCI_COMMAND_IO_ENABLE));
    368 	printf("    Mem space accesses %s\n", onoff(PCI_COMMAND_MEM_ENABLE));
    369 	printf("    Bus mastering %s\n", onoff(PCI_COMMAND_MASTER_ENABLE));
    370 	printf("    Special cycles %s\n", onoff(PCI_COMMAND_SPECIAL_ENABLE));
    371 	printf("    MWI transactions %s\n",
    372 	    onoff(PCI_COMMAND_INVALIDATE_ENABLE));
    373 	printf("    Palette snooping %s\n", onoff(PCI_COMMAND_PALETTE_ENABLE));
    374 	printf("    Parity error checking %s\n",
    375 	    onoff(PCI_COMMAND_PARITY_ENABLE));
    376 	printf("    Address/Data stepping %s\n",
    377 	    onoff(PCI_COMMAND_STEPPING_ENABLE));
    378 	printf("    System Error (SERR) %s\n", onoff(PCI_COMMAND_SERR_ENABLE));
    379 	printf("    Fast back-to-back transactions %s\n",
    380 	    onoff(PCI_COMMAND_BACKTOBACK_ENABLE));
    381 	printf("  Status Register:\n");
    382 	printf("    66 MHz capable %s\n", onoff(PCI_STATUS_66MHZ_SUPPORT));
    383 	printf("    User Definable Features (UDF) support %s\n",
    384 	    onoff(PCI_STATUS_UDF_SUPPORT));
    385 	printf("    Fast back-to-back capable %s\n",
    386 	    onoff(PCI_STATUS_BACKTOBACK_SUPPORT));
    387 	printf("    Data parity error detected %s\n",
    388 	    onoff(PCI_STATUS_PARITY_ERROR));
    389 
    390 	printf("    DEVSEL timing ");
    391 	switch (rval & PCI_STATUS_DEVSEL_MASK) {
    392 	case PCI_STATUS_DEVSEL_FAST:
    393 		printf("fast");
    394 		break;
    395 	case PCI_STATUS_DEVSEL_MEDIUM:
    396 		printf("medium");
    397 		break;
    398 	case PCI_STATUS_DEVSEL_SLOW:
    399 		printf("slow");
    400 		break;
    401 	}
    402 	printf("\n");
    403 
    404 	printf("    Slave signaled Target Abort %s\n",
    405 	    onoff(PCI_STATUS_TARGET_TARGET_ABORT));
    406 	printf("    Master received Target Abort %s\n",
    407 	    onoff(PCI_STATUS_MASTER_TARGET_ABORT));
    408 	printf("    Master received Master Abort %s\n",
    409 	    onoff(PCI_STATUS_MASTER_ABORT));
    410 	printf("    Asserted System Error (SERR) %s\n",
    411 	    onoff(PCI_STATUS_SPECIAL_ERROR));
    412 	printf("    Parity error detected %s\n",
    413 	    onoff(PCI_STATUS_PARITY_DETECT));
    414 #endif /* PCIVERBOSE */
    415 
    416 	rval = pci_conf_read(pc, tag, PCI_CLASS_REG);
    417 
    418 	for (classp = pci_class; classp->name != NULL; classp++) {
    419 		if (PCI_CLASS(rval) == classp->val)
    420 			break;
    421 	}
    422 	subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
    423 	while (subclassp && subclassp->name != NULL) {
    424 		if (PCI_SUBCLASS(rval) == subclassp->val)
    425 			break;
    426 		subclassp++;
    427 	}
    428 	if (classp->name != NULL) {
    429 		printf("  Class Name: %s\n", classp->name);
    430 		if (subclassp != NULL && subclassp->name != NULL)
    431 			printf("  Subclass Name: %s\n", subclassp->name);
    432 		else
    433 			printf("  Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
    434 	} else {
    435 		printf("  Class ID: 0x%02x\n", PCI_CLASS(rval));
    436 		printf("  Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
    437 	}
    438 	printf("  Interface: 0x%02x\n", PCI_INTERFACE(rval));
    439 	printf("  Revision ID: 0x%02x\n", PCI_REVISION(rval));
    440 
    441 	rval = pci_conf_read(pc, tag, PCI_BHLC_REG);
    442 
    443 	printf("  BIST: 0x%02x\n", PCI_BIST(rval));
    444 	printf("  Header Type: 0x%02x\n", PCI_HDRTYPE(rval));
    445 	printf("  Latency Timer: 0x%02x\n", PCI_LATTIMER(rval));
    446 	printf("  Cache Line Size: 0x%02x\n", PCI_CACHELINE(rval));
    447 
    448 	for (reg = PCI_MAPREG_START; reg < PCI_MAPREG_END; reg += 4) {
    449 		/*
    450 		 * Section 6.2.5.1, `Address Maps', tells us that:
    451 		 *
    452 		 * 1) The builtin software should have already mapped the
    453 		 * device in a reasonable way.
    454 		 *
    455 		 * 2) A device which wants 2^n bytes of memory will hardwire
    456 		 * the bottom n bits of the address to 0.  As recommended,
    457 		 * we write all 1s and see what we get back.
    458 		 */
    459 		s = splhigh();
    460 		rval = pci_conf_read(pc, tag, reg);
    461 		pci_conf_write(pc, tag, reg, 0xffffffff);
    462 		mask = pci_conf_read(pc, tag, reg);
    463 		pci_conf_write(pc, tag, reg, rval);
    464 		splx(s);
    465 
    466 		printf("  Mapping register 0x%02x\n", reg);
    467 		if (PCI_MAPREG_TYPE(rval) == PCI_MAPREG_TYPE_MEM) {
    468 			printf("    Base Address: 0x%08x, size 0x%08x, "
    469 			    "type = mem", PCI_MAPREG_MEM_ADDR(rval),
    470 			    PCI_MAPREG_MEM_SIZE(mask));
    471 			switch (PCI_MAPREG_MEM_TYPE(rval)) {
    472 			case PCI_MAPREG_MEM_TYPE_32BIT:
    473 				printf(", 32-bit");
    474 				break;
    475 			case PCI_MAPREG_MEM_TYPE_32BIT_1M:
    476 				printf(", 32-bit-1M");
    477 				break;
    478 			case PCI_MAPREG_MEM_TYPE_64BIT:
    479 				printf(", 64-bit");
    480 				break;
    481 			}
    482 			if (PCI_MAPREG_MEM_CACHEABLE(rval))
    483 				printf(", cacheable");
    484 			else
    485 				printf(", not cacheable");
    486 			printf("\n");
    487 		} else {
    488 			printf("    Base Address: 0x%08x, size 0x%08x, "
    489 			    "type = i/o\n", PCI_MAPREG_IO_ADDR(rval),
    490 			    PCI_MAPREG_IO_SIZE(mask));
    491 		}
    492 	}
    493 
    494 	rval = pci_conf_read(pc, tag, PCI_INTERRUPT_REG);
    495 
    496 	printf("  Maximum Latency: 0x%08x\n", (rval >> 24) & 0xff);
    497 	printf("  Minimum Grant: 0x%08x\n", (rval >> 16) & 0xff);
    498 	printf("  Interrupt pin: 0x%08x", PCI_INTERRUPT_PIN(rval));
    499 	switch (PCI_INTERRUPT_PIN(rval)) {
    500 	case PCI_INTERRUPT_PIN_NONE:
    501 		printf(" (none)");
    502 		break;
    503 	case PCI_INTERRUPT_PIN_A:
    504 		printf(" (pin A)");
    505 		break;
    506 	case PCI_INTERRUPT_PIN_B:
    507 		printf(" (pin B)");
    508 		break;
    509 	case PCI_INTERRUPT_PIN_C:
    510 		printf(" (pin C)");
    511 		break;
    512 	case PCI_INTERRUPT_PIN_D:
    513 		printf(" (pin D)");
    514 		break;
    515 	}
    516 	printf("\n");
    517 	printf("  Interrupt line: 0x%08x\n", PCI_INTERRUPT_LINE(rval));
    518 }
    519