[BACK]Return to pci_subr.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / dev / pci

Annotation of src/sys/dev/pci/pci_subr.c, Revision 1.32.8.1

1.32.8.1! wrstuden    1: /*     $NetBSD: pci_subr.c,v 1.33 1999/12/15 12:27:26 kleink Exp $     */
1.3       cgd         2:
1.1       mycroft     3: /*
1.22      thorpej     4:  * Copyright (c) 1997 Zubin D. Dittia.  All rights reserved.
1.26      cgd         5:  * Copyright (c) 1995, 1996, 1998
                      6:  *     Christopher G. Demetriou.  All rights reserved.
1.30      mycroft     7:  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
1.1       mycroft     8:  *
                      9:  * Redistribution and use in source and binary forms, with or without
                     10:  * modification, are permitted provided that the following conditions
                     11:  * are met:
                     12:  * 1. Redistributions of source code must retain the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer.
                     14:  * 2. Redistributions in binary form must reproduce the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer in the
                     16:  *    documentation and/or other materials provided with the distribution.
                     17:  * 3. All advertising materials mentioning features or use of this software
                     18:  *    must display the following acknowledgement:
1.30      mycroft    19:  *     This product includes software developed by Charles M. Hannum.
1.1       mycroft    20:  * 4. The name of the author may not be used to endorse or promote products
                     21:  *    derived from this software without specific prior written permission.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     25:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     26:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     27:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     28:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     29:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     30:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     31:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     32:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: /*
1.10      cgd        36:  * PCI autoconfiguration support functions.
1.1       mycroft    37:  */
1.21      enami      38:
                     39: #include "opt_pciverbose.h"
1.1       mycroft    40:
                     41: #include <sys/param.h>
1.10      cgd        42: #include <sys/systm.h>
1.1       mycroft    43: #include <sys/device.h>
                     44:
1.24      thorpej    45: #include <machine/intr.h>
                     46:
1.10      cgd        47: #include <dev/pci/pcireg.h>
1.7       cgd        48: #include <dev/pci/pcivar.h>
1.10      cgd        49: #ifdef PCIVERBOSE
                     50: #include <dev/pci/pcidevs.h>
                     51: #endif
                     52:
1.26      cgd        53: static void pci_conf_print_common __P((pci_chipset_tag_t, pcitag_t,
                     54:     const pcireg_t *regs));
1.27      cgd        55: static void pci_conf_print_bar __P((pci_chipset_tag_t, pcitag_t,
1.28      cgd        56:     const pcireg_t *regs, int, const char *));
                     57: static void pci_conf_print_regs __P((const pcireg_t *regs, int first,
                     58:     int pastlast));
1.27      cgd        59: static void pci_conf_print_type0 __P((pci_chipset_tag_t, pcitag_t,
                     60:     const pcireg_t *regs));
1.26      cgd        61: static void pci_conf_print_type1 __P((pci_chipset_tag_t, pcitag_t,
                     62:     const pcireg_t *regs));
1.27      cgd        63: static void pci_conf_print_type2 __P((pci_chipset_tag_t, pcitag_t,
                     64:     const pcireg_t *regs));
1.26      cgd        65:
1.10      cgd        66: /*
                     67:  * Descriptions of known PCI classes and subclasses.
                     68:  *
                     69:  * Subclasses are described in the same way as classes, but have a
                     70:  * NULL subclass pointer.
                     71:  */
                     72: struct pci_class {
                     73:        char            *name;
                     74:        int             val;            /* as wide as pci_{,sub}class_t */
                     75:        struct pci_class *subclasses;
                     76: };
                     77:
                     78: struct pci_class pci_subclass_prehistoric[] = {
                     79:        { "miscellaneous",      PCI_SUBCLASS_PREHISTORIC_MISC,          },
                     80:        { "VGA",                PCI_SUBCLASS_PREHISTORIC_VGA,           },
                     81:        { 0 }
                     82: };
                     83:
                     84: struct pci_class pci_subclass_mass_storage[] = {
                     85:        { "SCSI",               PCI_SUBCLASS_MASS_STORAGE_SCSI,         },
                     86:        { "IDE",                PCI_SUBCLASS_MASS_STORAGE_IDE,          },
                     87:        { "floppy",             PCI_SUBCLASS_MASS_STORAGE_FLOPPY,       },
                     88:        { "IPI",                PCI_SUBCLASS_MASS_STORAGE_IPI,          },
1.20      cgd        89:        { "RAID",               PCI_SUBCLASS_MASS_STORAGE_RAID,         },
1.10      cgd        90:        { "miscellaneous",      PCI_SUBCLASS_MASS_STORAGE_MISC,         },
                     91:        { 0 },
                     92: };
                     93:
                     94: struct pci_class pci_subclass_network[] = {
                     95:        { "ethernet",           PCI_SUBCLASS_NETWORK_ETHERNET,          },
                     96:        { "token ring",         PCI_SUBCLASS_NETWORK_TOKENRING,         },
                     97:        { "FDDI",               PCI_SUBCLASS_NETWORK_FDDI,              },
1.20      cgd        98:        { "ATM",                PCI_SUBCLASS_NETWORK_ATM,               },
1.32      cgd        99:        { "ISDN",               PCI_SUBCLASS_NETWORK_ISDN,              },
1.10      cgd       100:        { "miscellaneous",      PCI_SUBCLASS_NETWORK_MISC,              },
                    101:        { 0 },
                    102: };
                    103:
                    104: struct pci_class pci_subclass_display[] = {
                    105:        { "VGA",                PCI_SUBCLASS_DISPLAY_VGA,               },
                    106:        { "XGA",                PCI_SUBCLASS_DISPLAY_XGA,               },
1.32      cgd       107:        { "3D",                 PCI_SUBCLASS_DISPLAY_3D,                },
1.10      cgd       108:        { "miscellaneous",      PCI_SUBCLASS_DISPLAY_MISC,              },
                    109:        { 0 },
                    110: };
                    111:
                    112: struct pci_class pci_subclass_multimedia[] = {
                    113:        { "video",              PCI_SUBCLASS_MULTIMEDIA_VIDEO,          },
                    114:        { "audio",              PCI_SUBCLASS_MULTIMEDIA_AUDIO,          },
1.32      cgd       115:        { "telephony",          PCI_SUBCLASS_MULTIMEDIA_TELEPHONY,      },
1.10      cgd       116:        { "miscellaneous",      PCI_SUBCLASS_MULTIMEDIA_MISC,           },
                    117:        { 0 },
                    118: };
                    119:
                    120: struct pci_class pci_subclass_memory[] = {
                    121:        { "RAM",                PCI_SUBCLASS_MEMORY_RAM,                },
                    122:        { "flash",              PCI_SUBCLASS_MEMORY_FLASH,              },
                    123:        { "miscellaneous",      PCI_SUBCLASS_MEMORY_MISC,               },
                    124:        { 0 },
                    125: };
                    126:
                    127: struct pci_class pci_subclass_bridge[] = {
                    128:        { "host",               PCI_SUBCLASS_BRIDGE_HOST,               },
                    129:        { "ISA",                PCI_SUBCLASS_BRIDGE_ISA,                },
                    130:        { "EISA",               PCI_SUBCLASS_BRIDGE_EISA,               },
                    131:        { "MicroChannel",       PCI_SUBCLASS_BRIDGE_MC,                 },
                    132:        { "PCI",                PCI_SUBCLASS_BRIDGE_PCI,                },
                    133:        { "PCMCIA",             PCI_SUBCLASS_BRIDGE_PCMCIA,             },
1.20      cgd       134:        { "NuBus",              PCI_SUBCLASS_BRIDGE_NUBUS,              },
                    135:        { "CardBus",            PCI_SUBCLASS_BRIDGE_CARDBUS,            },
1.32      cgd       136:        { "RACEway",            PCI_SUBCLASS_BRIDGE_RACEWAY,            },
1.10      cgd       137:        { "miscellaneous",      PCI_SUBCLASS_BRIDGE_MISC,               },
                    138:        { 0 },
                    139: };
                    140:
1.20      cgd       141: struct pci_class pci_subclass_communications[] = {
                    142:        { "serial",             PCI_SUBCLASS_COMMUNICATIONS_SERIAL,     },
                    143:        { "parallel",           PCI_SUBCLASS_COMMUNICATIONS_PARALLEL,   },
1.32      cgd       144:        { "multi-port serial",  PCI_SUBCLASS_COMMUNICATIONS_MPSERIAL,   },
                    145:        { "modem",              PCI_SUBCLASS_COMMUNICATIONS_MODEM,      },
1.20      cgd       146:        { "miscellaneous",      PCI_SUBCLASS_COMMUNICATIONS_MISC,       },
                    147:        { 0 },
                    148: };
                    149:
                    150: struct pci_class pci_subclass_system[] = {
                    151:        { "8259 PIC",           PCI_SUBCLASS_SYSTEM_PIC,                },
                    152:        { "8237 DMA",           PCI_SUBCLASS_SYSTEM_DMA,                },
                    153:        { "8254 timer",         PCI_SUBCLASS_SYSTEM_TIMER,              },
                    154:        { "RTC",                PCI_SUBCLASS_SYSTEM_RTC,                },
1.32      cgd       155:        { "PCI Hot-Plug",       PCI_SUBCLASS_SYSTEM_RTC,                },
1.20      cgd       156:        { "miscellaneous",      PCI_SUBCLASS_SYSTEM_MISC,               },
                    157:        { 0 },
                    158: };
                    159:
                    160: struct pci_class pci_subclass_input[] = {
                    161:        { "keyboard",           PCI_SUBCLASS_INPUT_KEYBOARD,            },
                    162:        { "digitizer",          PCI_SUBCLASS_INPUT_DIGITIZER,           },
                    163:        { "mouse",              PCI_SUBCLASS_INPUT_MOUSE,               },
1.32      cgd       164:        { "scanner",            PCI_SUBCLASS_INPUT_SCANNER,             },
                    165:        { "game port",          PCI_SUBCLASS_INPUT_GAMEPORT,            },
1.20      cgd       166:        { "miscellaneous",      PCI_SUBCLASS_INPUT_MISC,                },
                    167:        { 0 },
                    168: };
                    169:
                    170: struct pci_class pci_subclass_dock[] = {
                    171:        { "generic",            PCI_SUBCLASS_DOCK_GENERIC,              },
                    172:        { "miscellaneous",      PCI_SUBCLASS_DOCK_MISC,                 },
                    173:        { 0 },
                    174: };
                    175:
                    176: struct pci_class pci_subclass_processor[] = {
                    177:        { "386",                PCI_SUBCLASS_PROCESSOR_386,             },
                    178:        { "486",                PCI_SUBCLASS_PROCESSOR_486,             },
                    179:        { "Pentium",            PCI_SUBCLASS_PROCESSOR_PENTIUM,         },
                    180:        { "Alpha",              PCI_SUBCLASS_PROCESSOR_ALPHA,           },
                    181:        { "PowerPC",            PCI_SUBCLASS_PROCESSOR_POWERPC,         },
1.32      cgd       182:        { "MIPS",               PCI_SUBCLASS_PROCESSOR_MIPS,            },
1.20      cgd       183:        { "Co-processor",       PCI_SUBCLASS_PROCESSOR_COPROC,          },
                    184:        { 0 },
                    185: };
                    186:
                    187: struct pci_class pci_subclass_serialbus[] = {
                    188:        { "Firewire",           PCI_SUBCLASS_SERIALBUS_FIREWIRE,        },
                    189:        { "ACCESS.bus",         PCI_SUBCLASS_SERIALBUS_ACCESS,          },
                    190:        { "SSA",                PCI_SUBCLASS_SERIALBUS_SSA,             },
                    191:        { "USB",                PCI_SUBCLASS_SERIALBUS_USB,             },
1.32      cgd       192:        /* XXX Fiber Channel/_FIBRECHANNEL */
1.20      cgd       193:        { "Fiber Channel",      PCI_SUBCLASS_SERIALBUS_FIBER,           },
1.32      cgd       194:        { "SMBus",              PCI_SUBCLASS_SERIALBUS_SMBUS,           },
                    195:        { 0 },
                    196: };
                    197:
                    198: struct pci_class pci_subclass_wireless[] = {
                    199:        { "iRDA",               PCI_SUBCLASS_WIRELESS_IRDA,             },
                    200:        { "Consumer IR",        PCI_SUBCLASS_WIRELESS_CONSUMERIR,       },
                    201:        { "RF",                 PCI_SUBCLASS_WIRELESS_RF,               },
                    202:        { "miscellaneous",      PCI_SUBCLASS_WIRELESS_MISC,             },
                    203:        { 0 },
                    204: };
                    205:
                    206: struct pci_class pci_subclass_i2o[] = {
                    207:        { "1.0",                PCI_SUBCLASS_I2O_10,                    },
                    208:        { 0 },
                    209: };
                    210:
                    211: struct pci_class pci_subclass_satcom[] = {
                    212:        { "TV",                 PCI_SUBCLASS_SATCOM_TV,                 },
                    213:        { "audio",              PCI_SUBCLASS_SATCOM_AUDIO,              },
                    214:        { "voice",              PCI_SUBCLASS_SATCOM_VOICE,              },
                    215:        { "data",               PCI_SUBCLASS_SATCOM_DATA,               },
                    216:        { 0 },
                    217: };
                    218:
                    219: struct pci_class pci_subclass_crypto[] = {
                    220:        { "network/computing",  PCI_SUBCLASS_CRYPTO_NETCOMP,            },
                    221:        { "entertainment",      PCI_SUBCLASS_CRYPTO_ENTERTAINMENT,      },
                    222:        { "miscellaneous",      PCI_SUBCLASS_CRYPTO_MISC,               },
                    223:        { 0 },
                    224: };
                    225:
                    226: struct pci_class pci_subclass_dasp[] = {
                    227:        { "DPIO",               PCI_SUBCLASS_DASP_DPIO,                 },
                    228:        { "miscellaneous",      PCI_SUBCLASS_DASP_MISC,                 },
1.20      cgd       229:        { 0 },
                    230: };
                    231:
1.10      cgd       232: struct pci_class pci_class[] = {
                    233:        { "prehistoric",        PCI_CLASS_PREHISTORIC,
                    234:            pci_subclass_prehistoric,                           },
                    235:        { "mass storage",       PCI_CLASS_MASS_STORAGE,
                    236:            pci_subclass_mass_storage,                          },
                    237:        { "network",            PCI_CLASS_NETWORK,
                    238:            pci_subclass_network,                               },
                    239:        { "display",            PCI_CLASS_DISPLAY,
1.11      cgd       240:            pci_subclass_display,                               },
1.10      cgd       241:        { "multimedia",         PCI_CLASS_MULTIMEDIA,
                    242:            pci_subclass_multimedia,                            },
                    243:        { "memory",             PCI_CLASS_MEMORY,
                    244:            pci_subclass_memory,                                },
                    245:        { "bridge",             PCI_CLASS_BRIDGE,
                    246:            pci_subclass_bridge,                                },
1.20      cgd       247:        { "communications",     PCI_CLASS_COMMUNICATIONS,
                    248:            pci_subclass_communications,                        },
                    249:        { "system",             PCI_CLASS_SYSTEM,
                    250:            pci_subclass_system,                                },
                    251:        { "input",              PCI_CLASS_INPUT,
                    252:            pci_subclass_input,                                 },
                    253:        { "dock",               PCI_CLASS_DOCK,
                    254:            pci_subclass_dock,                                  },
                    255:        { "processor",          PCI_CLASS_PROCESSOR,
                    256:            pci_subclass_processor,                             },
                    257:        { "serial bus",         PCI_CLASS_SERIALBUS,
                    258:            pci_subclass_serialbus,                             },
1.32      cgd       259:        { "wireless",           PCI_CLASS_WIRELESS,
                    260:            pci_subclass_wireless,                              },
                    261:        { "I2O",                PCI_CLASS_I2O,
                    262:            pci_subclass_i2o,                                   },
                    263:        { "satellite comm",     PCI_CLASS_SATCOM,
                    264:            pci_subclass_satcom,                                },
                    265:        { "crypto",             PCI_CLASS_CRYPTO,
                    266:            pci_subclass_crypto,                                },
                    267:        { "DASP",               PCI_CLASS_DASP,
                    268:            pci_subclass_dasp,                                  },
1.10      cgd       269:        { "undefined",          PCI_CLASS_UNDEFINED,
                    270:            0,                                                  },
                    271:        { 0 },
                    272: };
                    273:
                    274: #ifdef PCIVERBOSE
                    275: /*
                    276:  * Descriptions of of known vendors and devices ("products").
                    277:  */
                    278: struct pci_knowndev {
                    279:        pci_vendor_id_t         vendor;
                    280:        pci_product_id_t        product;
                    281:        int                     flags;
                    282:        char                    *vendorname, *productname;
                    283: };
1.13      cgd       284: #define        PCI_KNOWNDEV_NOPROD     0x01            /* match on vendor only */
1.10      cgd       285:
                    286: #include <dev/pci/pcidevs_data.h>
                    287: #endif /* PCIVERBOSE */
1.29      augustss  288:
                    289: char *
                    290: pci_findvendor(id_reg)
                    291:        pcireg_t id_reg;
                    292: {
                    293: #ifdef PCIVERBOSE
                    294:        pci_vendor_id_t vendor = PCI_VENDOR(id_reg);
                    295:        struct pci_knowndev *kdp;
                    296:
                    297:        kdp = pci_knowndevs;
                    298:         while (kdp->vendorname != NULL) {      /* all have vendor name */
                    299:                 if (kdp->vendor == vendor)
                    300:                         break;
                    301:                kdp++;
                    302:        }
                    303:         return (kdp->vendorname);
                    304: #else
                    305:        return (NULL);
                    306: #endif
                    307: }
1.10      cgd       308:
                    309: void
1.13      cgd       310: pci_devinfo(id_reg, class_reg, showclass, cp)
1.10      cgd       311:        pcireg_t id_reg, class_reg;
1.13      cgd       312:        int showclass;
1.10      cgd       313:        char *cp;
                    314: {
                    315:        pci_vendor_id_t vendor;
                    316:        pci_product_id_t product;
                    317:        pci_class_t class;
                    318:        pci_subclass_t subclass;
                    319:        pci_interface_t interface;
                    320:        pci_revision_t revision;
                    321:        char *vendor_namep, *product_namep;
                    322:        struct pci_class *classp, *subclassp;
                    323: #ifdef PCIVERBOSE
                    324:        struct pci_knowndev *kdp;
1.16      cgd       325:        const char *unmatched = "unknown ";
1.15      cgd       326: #else
1.16      cgd       327:        const char *unmatched = "";
1.10      cgd       328: #endif
                    329:
                    330:        vendor = PCI_VENDOR(id_reg);
                    331:        product = PCI_PRODUCT(id_reg);
                    332:
                    333:        class = PCI_CLASS(class_reg);
                    334:        subclass = PCI_SUBCLASS(class_reg);
                    335:        interface = PCI_INTERFACE(class_reg);
                    336:        revision = PCI_REVISION(class_reg);
                    337:
                    338: #ifdef PCIVERBOSE
                    339:        kdp = pci_knowndevs;
                    340:         while (kdp->vendorname != NULL) {      /* all have vendor name */
                    341:                 if (kdp->vendor == vendor && (kdp->product == product ||
                    342:                    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0))
                    343:                         break;
                    344:                kdp++;
                    345:        }
1.13      cgd       346:         if (kdp->vendorname == NULL)
1.10      cgd       347:                vendor_namep = product_namep = NULL;
1.13      cgd       348:        else {
1.10      cgd       349:                vendor_namep = kdp->vendorname;
                    350:                product_namep = (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0 ?
                    351:                    kdp->productname : NULL;
                    352:         }
                    353: #else /* PCIVERBOSE */
                    354:        vendor_namep = product_namep = NULL;
                    355: #endif /* PCIVERBOSE */
                    356:
                    357:        classp = pci_class;
                    358:        while (classp->name != NULL) {
                    359:                if (class == classp->val)
                    360:                        break;
                    361:                classp++;
                    362:        }
                    363:
                    364:        subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
                    365:        while (subclassp && subclassp->name != NULL) {
                    366:                if (subclass == subclassp->val)
                    367:                        break;
                    368:                subclassp++;
                    369:        }
                    370:
                    371:        if (vendor_namep == NULL)
1.19      christos  372:                cp += sprintf(cp, "%svendor 0x%04x product 0x%04x",
1.15      cgd       373:                    unmatched, vendor, product);
1.10      cgd       374:        else if (product_namep != NULL)
1.19      christos  375:                cp += sprintf(cp, "%s %s", vendor_namep, product_namep);
1.10      cgd       376:        else
1.20      cgd       377:                cp += sprintf(cp, "%s product 0x%04x",
1.10      cgd       378:                    vendor_namep, product);
1.13      cgd       379:        if (showclass) {
1.19      christos  380:                cp += sprintf(cp, " (");
1.13      cgd       381:                if (classp->name == NULL)
1.20      cgd       382:                        cp += sprintf(cp, "class 0x%02x, subclass 0x%02x",
1.13      cgd       383:                            class, subclass);
                    384:                else {
                    385:                        if (subclassp == NULL || subclassp->name == NULL)
1.20      cgd       386:                                cp += sprintf(cp,
                    387:                                    "%s subclass 0x%02x",
                    388:                                    classp->name, subclass);
1.13      cgd       389:                        else
1.20      cgd       390:                                cp += sprintf(cp, "%s %s",
                    391:                                    subclassp->name, classp->name);
1.13      cgd       392:                }
1.20      cgd       393:                if (interface != 0)
                    394:                        cp += sprintf(cp, ", interface 0x%02x", interface);
                    395:                if (revision != 0)
                    396:                        cp += sprintf(cp, ", revision 0x%02x", revision);
                    397:                cp += sprintf(cp, ")");
1.13      cgd       398:        }
1.22      thorpej   399: }
                    400:
                    401: /*
                    402:  * Print out most of the PCI configuration registers.  Typically used
                    403:  * in a device attach routine like this:
                    404:  *
                    405:  *     #ifdef MYDEV_DEBUG
                    406:  *             printf("%s: ", sc->sc_dev.dv_xname);
                    407:  *             pci_conf_print(pa->pa_pc, pa->pa_tag);
                    408:  *     #endif
                    409:  */
1.26      cgd       410:
                    411: #define        i2o(i)  ((i) * 4)
                    412: #define        o2i(o)  ((o) / 4)
1.27      cgd       413: #define        onoff(str, bit)                                                 \
                    414:        printf("      %s: %s\n", (str), (rval & (bit)) ? "on" : "off");
1.26      cgd       415:
                    416: static void
                    417: pci_conf_print_common(pc, tag, regs)
1.22      thorpej   418:        pci_chipset_tag_t pc;
                    419:        pcitag_t tag;
1.26      cgd       420:        const pcireg_t *regs;
1.22      thorpej   421: {
                    422: #ifdef PCIVERBOSE
                    423:        struct pci_knowndev *kdp;
                    424: #endif
                    425:        struct pci_class *classp, *subclassp;
1.26      cgd       426:        pcireg_t rval;
1.22      thorpej   427:
1.26      cgd       428:        rval = regs[o2i(PCI_ID_REG)];
1.22      thorpej   429: #ifndef PCIVERBOSE
1.26      cgd       430:        printf("    Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
                    431:        printf("    Device ID: 0x%04x\n", PCI_PRODUCT(rval));
1.22      thorpej   432: #else
                    433:        for (kdp = pci_knowndevs; kdp->vendorname != NULL; kdp++) {
                    434:                if (kdp->vendor == PCI_VENDOR(rval) &&
                    435:                    (kdp->product == PCI_PRODUCT(rval) ||
                    436:                    (kdp->flags & PCI_KNOWNDEV_NOPROD) != 0)) {
                    437:                        break;
                    438:                }
                    439:        }
                    440:        if (kdp->vendorname != NULL)
1.26      cgd       441:                printf("    Vendor Name: %s (0x%04x)\n", kdp->vendorname,
                    442:                    PCI_VENDOR(rval));
1.22      thorpej   443:        else
1.26      cgd       444:                printf("    Vendor ID: 0x%04x\n", PCI_VENDOR(rval));
1.22      thorpej   445:        if (kdp->productname != NULL && (kdp->flags & PCI_KNOWNDEV_NOPROD) == 0)
1.26      cgd       446:                printf("    Device Name: %s (0x%04x)\n", kdp->productname,
                    447:                    PCI_PRODUCT(rval));
1.22      thorpej   448:        else
1.26      cgd       449:                printf("    Device ID: 0x%04x\n", PCI_PRODUCT(rval));
1.22      thorpej   450: #endif /* PCIVERBOSE */
                    451:
1.26      cgd       452:        rval = regs[o2i(PCI_COMMAND_STATUS_REG)];
1.23      drochner  453:
1.26      cgd       454:        printf("    Command register: 0x%04x\n", rval & 0xffff);
                    455:        onoff("I/O space accesses", PCI_COMMAND_IO_ENABLE);
                    456:        onoff("Memory space accesses", PCI_COMMAND_MEM_ENABLE);
                    457:        onoff("Bus mastering", PCI_COMMAND_MASTER_ENABLE);
                    458:        onoff("Special cycles", PCI_COMMAND_SPECIAL_ENABLE);
                    459:        onoff("MWI transactions", PCI_COMMAND_INVALIDATE_ENABLE);
                    460:        onoff("Palette snooping", PCI_COMMAND_PALETTE_ENABLE);
                    461:        onoff("Parity error checking", PCI_COMMAND_PARITY_ENABLE);
                    462:        onoff("Address/data stepping", PCI_COMMAND_STEPPING_ENABLE);
                    463:        onoff("System error (SERR)", PCI_COMMAND_SERR_ENABLE);
                    464:        onoff("Fast back-to-back transactions", PCI_COMMAND_BACKTOBACK_ENABLE);
                    465:
                    466:        printf("    Status register: 0x%04x\n", (rval >> 16) & 0xffff);
1.32.8.1! wrstuden  467:        onoff("Capability List support", PCI_STATUS_CAPLIST_SUPPORT);
1.26      cgd       468:        onoff("66 MHz capable", PCI_STATUS_66MHZ_SUPPORT);
                    469:        onoff("User Definable Features (UDF) support", PCI_STATUS_UDF_SUPPORT);
                    470:        onoff("Fast back-to-back capable", PCI_STATUS_BACKTOBACK_SUPPORT);
                    471:        onoff("Data parity error detected", PCI_STATUS_PARITY_ERROR);
1.22      thorpej   472:
1.26      cgd       473:        printf("      DEVSEL timing: ");
1.22      thorpej   474:        switch (rval & PCI_STATUS_DEVSEL_MASK) {
                    475:        case PCI_STATUS_DEVSEL_FAST:
                    476:                printf("fast");
                    477:                break;
                    478:        case PCI_STATUS_DEVSEL_MEDIUM:
                    479:                printf("medium");
                    480:                break;
                    481:        case PCI_STATUS_DEVSEL_SLOW:
                    482:                printf("slow");
                    483:                break;
1.26      cgd       484:        default:
                    485:                printf("unknown/reserved");     /* XXX */
                    486:                break;
1.22      thorpej   487:        }
1.26      cgd       488:        printf(" (0x%x)\n", (rval & PCI_STATUS_DEVSEL_MASK) >> 25);
1.22      thorpej   489:
1.26      cgd       490:        onoff("Slave signaled Target Abort", PCI_STATUS_TARGET_TARGET_ABORT);
                    491:        onoff("Master received Target Abort", PCI_STATUS_MASTER_TARGET_ABORT);
                    492:        onoff("Master received Master Abort", PCI_STATUS_MASTER_ABORT);
                    493:        onoff("Asserted System Error (SERR)", PCI_STATUS_SPECIAL_ERROR);
                    494:        onoff("Parity error detected", PCI_STATUS_PARITY_DETECT);
1.22      thorpej   495:
1.26      cgd       496:        rval = regs[o2i(PCI_CLASS_REG)];
1.22      thorpej   497:        for (classp = pci_class; classp->name != NULL; classp++) {
                    498:                if (PCI_CLASS(rval) == classp->val)
                    499:                        break;
                    500:        }
                    501:        subclassp = (classp->name != NULL) ? classp->subclasses : NULL;
                    502:        while (subclassp && subclassp->name != NULL) {
                    503:                if (PCI_SUBCLASS(rval) == subclassp->val)
                    504:                        break;
                    505:                subclassp++;
                    506:        }
                    507:        if (classp->name != NULL) {
1.26      cgd       508:                printf("    Class Name: %s (0x%02x)\n", classp->name,
                    509:                    PCI_CLASS(rval));
1.22      thorpej   510:                if (subclassp != NULL && subclassp->name != NULL)
1.26      cgd       511:                        printf("    Subclass Name: %s (0x%02x)\n",
                    512:                            subclassp->name, PCI_SUBCLASS(rval));
1.22      thorpej   513:                else
1.26      cgd       514:                        printf("    Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
1.22      thorpej   515:        } else {
1.26      cgd       516:                printf("    Class ID: 0x%02x\n", PCI_CLASS(rval));
                    517:                printf("    Subclass ID: 0x%02x\n", PCI_SUBCLASS(rval));
1.22      thorpej   518:        }
1.26      cgd       519:        printf("    Interface: 0x%02x\n", PCI_INTERFACE(rval));
                    520:        printf("    Revision ID: 0x%02x\n", PCI_REVISION(rval));
1.22      thorpej   521:
1.26      cgd       522:        rval = regs[o2i(PCI_BHLC_REG)];
                    523:        printf("    BIST: 0x%02x\n", PCI_BIST(rval));
                    524:        printf("    Header Type: 0x%02x%s (0x%02x)\n", PCI_HDRTYPE_TYPE(rval),
                    525:            PCI_HDRTYPE_MULTIFN(rval) ? "+multifunction" : "",
                    526:            PCI_HDRTYPE(rval));
                    527:        printf("    Latency Timer: 0x%02x\n", PCI_LATTIMER(rval));
                    528:        printf("    Cache Line Size: 0x%02x\n", PCI_CACHELINE(rval));
                    529: }
1.22      thorpej   530:
1.26      cgd       531: static void
1.28      cgd       532: pci_conf_print_bar(pc, tag, regs, reg, name)
1.26      cgd       533:        pci_chipset_tag_t pc;
                    534:        pcitag_t tag;
                    535:        const pcireg_t *regs;
1.27      cgd       536:        int reg;
1.28      cgd       537:        const char *name;
1.26      cgd       538: {
1.27      cgd       539:        int s;
1.26      cgd       540:        pcireg_t mask, rval;
1.22      thorpej   541:
1.27      cgd       542:        /*
                    543:         * Section 6.2.5.1, `Address Maps', tells us that:
                    544:         *
                    545:         * 1) The builtin software should have already mapped the
                    546:         * device in a reasonable way.
                    547:         *
                    548:         * 2) A device which wants 2^n bytes of memory will hardwire
                    549:         * the bottom n bits of the address to 0.  As recommended,
                    550:         * we write all 1s and see what we get back.
                    551:         */
                    552:        rval = regs[o2i(reg)];
                    553:        if (rval != 0) {
1.24      thorpej   554:                /*
1.27      cgd       555:                 * The following sequence seems to make some devices
                    556:                 * (e.g. host bus bridges, which don't normally
                    557:                 * have their space mapped) very unhappy, to
                    558:                 * the point of crashing the system.
1.24      thorpej   559:                 *
1.27      cgd       560:                 * Therefore, if the mapping register is zero to
                    561:                 * start out with, don't bother trying.
1.24      thorpej   562:                 */
1.27      cgd       563:                s = splhigh();
                    564:                pci_conf_write(pc, tag, reg, 0xffffffff);
                    565:                mask = pci_conf_read(pc, tag, reg);
                    566:                pci_conf_write(pc, tag, reg, rval);
                    567:                splx(s);
                    568:        } else
                    569:                mask = 0;
                    570:
1.28      cgd       571:        printf("    Base address register at 0x%02x", reg);
                    572:        if (name)
                    573:                printf(" (%s)", name);
                    574:        printf("\n      ");
1.27      cgd       575:        if (rval == 0) {
                    576:                printf("not implemented(?)\n");
1.28      cgd       577:                return;
                    578:        }
                    579:        printf("type: ");
                    580:        if (PCI_MAPREG_TYPE(rval) == PCI_MAPREG_TYPE_MEM) {
1.27      cgd       581:                const char *type, *cache;
                    582:
                    583:                switch (PCI_MAPREG_MEM_TYPE(rval)) {
                    584:                case PCI_MAPREG_MEM_TYPE_32BIT:
                    585:                        type = "32-bit";
                    586:                        break;
                    587:                case PCI_MAPREG_MEM_TYPE_32BIT_1M:
                    588:                        type = "32-bit-1M";
                    589:                        break;
                    590:                case PCI_MAPREG_MEM_TYPE_64BIT:
                    591:                        type = "64-bit";
                    592:                        break;
                    593:                default:
                    594:                        type = "unknown (XXX)";
                    595:                        break;
1.22      thorpej   596:                }
1.27      cgd       597:                if (PCI_MAPREG_MEM_CACHEABLE(rval))
                    598:                        cache = "";
                    599:                else
                    600:                        cache = "non";
                    601:                printf("%s %scacheable memory\n", type, cache);
1.28      cgd       602:                printf("      base: 0x%08x, size: 0x%08x\n",
1.27      cgd       603:                    PCI_MAPREG_MEM_ADDR(rval),
                    604:                    PCI_MAPREG_MEM_SIZE(mask));
                    605:        } else {
                    606:                printf("i/o\n");
1.28      cgd       607:                printf("      base: 0x%08x, size: 0x%08x\n",
1.27      cgd       608:                    PCI_MAPREG_IO_ADDR(rval),
                    609:                    PCI_MAPREG_IO_SIZE(mask));
1.22      thorpej   610:        }
1.27      cgd       611: }
1.28      cgd       612:
                    613: static void
                    614: pci_conf_print_regs(regs, first, pastlast)
                    615:        const pcireg_t *regs;
                    616:        int first, pastlast;
                    617: {
                    618:        int off, needaddr, neednl;
                    619:
                    620:        needaddr = 1;
                    621:        neednl = 0;
                    622:        for (off = first; off < pastlast; off += 4) {
                    623:                if ((off % 16) == 0 || needaddr) {
                    624:                        printf("    0x%02x:", off);
                    625:                        needaddr = 0;
                    626:                }
                    627:                printf(" 0x%08x", regs[o2i(off)]);
                    628:                neednl = 1;
                    629:                if ((off % 16) == 12) {
                    630:                        printf("\n");
                    631:                        neednl = 0;
                    632:                }
                    633:        }
                    634:        if (neednl)
                    635:                printf("\n");
                    636: }
                    637:
1.27      cgd       638: static void
                    639: pci_conf_print_type0(pc, tag, regs)
                    640:        pci_chipset_tag_t pc;
                    641:        pcitag_t tag;
                    642:        const pcireg_t *regs;
                    643: {
                    644:        int off;
                    645:        pcireg_t rval;
                    646:
                    647:        for (off = PCI_MAPREG_START; off < PCI_MAPREG_END; off += 4)
1.28      cgd       648:                pci_conf_print_bar(pc, tag, regs, off, NULL);
1.22      thorpej   649:
1.26      cgd       650:        printf("    Cardbus CIS Pointer: 0x%08x\n", regs[o2i(0x28)]);
1.22      thorpej   651:
1.31      drochner  652:        rval = regs[o2i(PCI_SUBSYS_ID_REG)];
1.26      cgd       653:        printf("    Subsystem vendor ID: 0x%04x\n", PCI_VENDOR(rval));
                    654:        printf("    Subsystem ID: 0x%04x\n", PCI_PRODUCT(rval));
                    655:
                    656:        /* XXX */
                    657:        printf("    Expansion ROM Base Address: 0x%08x\n", regs[o2i(0x30)]);
1.32.8.1! wrstuden  658:
        !           659:        if (regs[o2i(PCI_COMMAND_STATUS_REG)] & PCI_STATUS_CAPLIST_SUPPORT)
        !           660:                printf("    Capability list pointer: 0x%02x\n",
        !           661:                    PCI_CAPLIST_PTR(regs[o2i(PCI_CAPLISTPTR_REG)]));
        !           662:        else
        !           663:                printf("    Reserved @ 0x34: 0x%08x\n", regs[o2i(0x34)]);
        !           664:
1.26      cgd       665:        printf("    Reserved @ 0x38: 0x%08x\n", regs[o2i(0x38)]);
                    666:
                    667:        rval = regs[o2i(PCI_INTERRUPT_REG)];
                    668:        printf("    Maximum Latency: 0x%02x\n", (rval >> 24) & 0xff);
                    669:        printf("    Minimum Grant: 0x%02x\n", (rval >> 16) & 0xff);
1.27      cgd       670:        printf("    Interrupt pin: 0x%02x ", PCI_INTERRUPT_PIN(rval));
1.22      thorpej   671:        switch (PCI_INTERRUPT_PIN(rval)) {
                    672:        case PCI_INTERRUPT_PIN_NONE:
1.27      cgd       673:                printf("(none)");
1.22      thorpej   674:                break;
                    675:        case PCI_INTERRUPT_PIN_A:
1.27      cgd       676:                printf("(pin A)");
1.22      thorpej   677:                break;
                    678:        case PCI_INTERRUPT_PIN_B:
1.27      cgd       679:                printf("(pin B)");
1.22      thorpej   680:                break;
                    681:        case PCI_INTERRUPT_PIN_C:
1.27      cgd       682:                printf("(pin C)");
1.22      thorpej   683:                break;
                    684:        case PCI_INTERRUPT_PIN_D:
1.27      cgd       685:                printf("(pin D)");
                    686:                break;
                    687:        default:
                    688:                printf("(???)");
1.22      thorpej   689:                break;
                    690:        }
                    691:        printf("\n");
1.26      cgd       692:        printf("    Interrupt line: 0x%02x\n", PCI_INTERRUPT_LINE(rval));
1.32.8.1! wrstuden  693:
        !           694:        if (regs[o2i(PCI_COMMAND_STATUS_REG)] & PCI_STATUS_CAPLIST_SUPPORT) {
        !           695:                for (off = PCI_CAPLIST_PTR(regs[o2i(PCI_CAPLISTPTR_REG)]);
        !           696:                     off != 0;
        !           697:                     off = PCI_CAPLIST_NEXT(regs[o2i(off)])) {
        !           698:                        rval = regs[o2i(off)];
        !           699:                        printf("    Capability register at 0x%02x\n", off);
        !           700:
        !           701:                        printf("      type: 0x%02x (", PCI_CAPLIST_CAP(rval));
        !           702:                        switch (PCI_CAPLIST_CAP(rval)) {
        !           703:                        case PCI_CAP_PWRMGMT:
        !           704:                                printf("Power Management, rev. %d.0",
        !           705:                                    (rval >> 0) & 0x07); /* XXX not clear */
        !           706:                                break;
        !           707:                        case PCI_CAP_AGP:
        !           708:                                printf("AGP, rev. %d.%d",
        !           709:                                    (rval >> 24) & 0x0f,
        !           710:                                    (rval >> 20) & 0x0f);
        !           711:                                break;
        !           712:                        case PCI_CAP_VPD:
        !           713:                                printf("VPD");
        !           714:                                break;
        !           715:                        case PCI_CAP_SLOTID:
        !           716:                                printf("SlotID");
        !           717:                                break;
        !           718:                        case PCI_CAP_MBI:
        !           719:                                printf("MBI");
        !           720:                                break;
        !           721:                        case PCI_CAP_HOTSWAP:
        !           722:                                printf("Hot-swapping");
        !           723:                                break;
        !           724:                        default:
        !           725:                                printf("unknown/reserved");
        !           726:                        }
        !           727:                        printf(")\n");
        !           728:                }
        !           729:        }
1.26      cgd       730: }
                    731:
1.27      cgd       732: static void
                    733: pci_conf_print_type1(pc, tag, regs)
                    734:        pci_chipset_tag_t pc;
                    735:        pcitag_t tag;
                    736:        const pcireg_t *regs;
                    737: {
                    738:        int off;
                    739:        pcireg_t rval;
                    740:
                    741:        /*
                    742:         * XXX these need to be printed in more detail, need to be
                    743:         * XXX checked against specs/docs, etc.
                    744:         *
                    745:         * This layout was cribbed from the TI PCI2030 PCI-to-PCI
                    746:         * Bridge chip documentation, and may not be correct with
                    747:         * respect to various standards. (XXX)
                    748:         */
                    749:
                    750:        for (off = 0x10; off < 0x18; off += 4)
1.28      cgd       751:                pci_conf_print_bar(pc, tag, regs, off, NULL);
1.27      cgd       752:
                    753:        printf("    Primary bus number: 0x%02x\n",
                    754:            (regs[o2i(0x18)] >> 0) & 0xff);
                    755:        printf("    Secondary bus number: 0x%02x\n",
                    756:            (regs[o2i(0x18)] >> 8) & 0xff);
                    757:        printf("    Subordinate bus number: 0x%02x\n",
                    758:            (regs[o2i(0x18)] >> 16) & 0xff);
                    759:        printf("    Secondary bus latency timer: 0x%02x\n",
                    760:            (regs[o2i(0x18)] >> 24) & 0xff);
                    761:
                    762:        rval = (regs[o2i(0x1c)] >> 16) & 0xffff;
                    763:        printf("    Secondary status register: 0x%04x\n", rval); /* XXX bits */
                    764:        onoff("66 MHz capable", 0x0020);
                    765:        onoff("User Definable Features (UDF) support", 0x0040);
                    766:        onoff("Fast back-to-back capable", 0x0080);
                    767:        onoff("Data parity error detected", 0x0100);
                    768:
                    769:        printf("      DEVSEL timing: ");
                    770:        switch (rval & 0x0600) {
                    771:        case 0x0000:
                    772:                printf("fast");
                    773:                break;
                    774:        case 0x0200:
                    775:                printf("medium");
                    776:                break;
                    777:        case 0x0400:
                    778:                printf("slow");
                    779:                break;
                    780:        default:
                    781:                printf("unknown/reserved");     /* XXX */
                    782:                break;
                    783:        }
                    784:        printf(" (0x%x)\n", (rval & 0x0600) >> 9);
                    785:
                    786:        onoff("Signaled Target Abort", 0x0800);
                    787:        onoff("Received Target Abort", 0x1000);
                    788:        onoff("Received Master Abort", 0x2000);
                    789:        onoff("System Error", 0x4000);
                    790:        onoff("Parity Error", 0x8000);
                    791:
                    792:        /* XXX Print more prettily */
                    793:        printf("    I/O region:\n");
                    794:        printf("      base register:  0x%02x\n", (regs[o2i(0x1c)] >> 0) & 0xff);
                    795:        printf("      limit register: 0x%02x\n", (regs[o2i(0x1c)] >> 8) & 0xff);
                    796:        printf("      base upper 16 bits register:  0x%04x\n",
                    797:            (regs[o2i(0x30)] >> 0) & 0xffff);
                    798:        printf("      limit upper 16 bits register: 0x%04x\n",
                    799:            (regs[o2i(0x30)] >> 16) & 0xffff);
                    800:
                    801:        /* XXX Print more prettily */
                    802:        printf("    Memory region:\n");
                    803:        printf("      base register:  0x%04x\n",
                    804:            (regs[o2i(0x20)] >> 0) & 0xffff);
                    805:        printf("      limit register: 0x%04x\n",
                    806:            (regs[o2i(0x20)] >> 16) & 0xffff);
                    807:
                    808:        /* XXX Print more prettily */
                    809:        printf("    Prefetchable memory region:\n");
                    810:        printf("      base register:  0x%04x\n",
                    811:            (regs[o2i(0x24)] >> 0) & 0xffff);
                    812:        printf("      limit register: 0x%04x\n",
                    813:            (regs[o2i(0x24)] >> 16) & 0xffff);
                    814:        printf("      base upper 32 bits register:  0x%08x\n", regs[o2i(0x28)]);
                    815:        printf("      limit upper 32 bits register: 0x%08x\n", regs[o2i(0x2c)]);
                    816:
                    817:        printf("    Reserved @ 0x34: 0x%08x\n", regs[o2i(0x34)]);
                    818:        /* XXX */
                    819:        printf("    Expansion ROM Base Address: 0x%08x\n", regs[o2i(0x38)]);
                    820:
                    821:        printf("    Interrupt line: 0x%02x\n",
                    822:            (regs[o2i(0x3c)] >> 0) & 0xff);
                    823:        printf("    Interrupt pin: 0x%02x ",
                    824:            (regs[o2i(0x3c)] >> 8) & 0xff);
                    825:        switch ((regs[o2i(0x3c)] >> 8) & 0xff) {
                    826:        case PCI_INTERRUPT_PIN_NONE:
                    827:                printf("(none)");
                    828:                break;
                    829:        case PCI_INTERRUPT_PIN_A:
                    830:                printf("(pin A)");
                    831:                break;
                    832:        case PCI_INTERRUPT_PIN_B:
                    833:                printf("(pin B)");
                    834:                break;
                    835:        case PCI_INTERRUPT_PIN_C:
                    836:                printf("(pin C)");
                    837:                break;
                    838:        case PCI_INTERRUPT_PIN_D:
                    839:                printf("(pin D)");
                    840:                break;
                    841:        default:
                    842:                printf("(???)");
                    843:                break;
                    844:        }
                    845:        printf("\n");
                    846:        rval = (regs[o2i(0x3c)] >> 16) & 0xffff;
                    847:        printf("    Bridge control register: 0x%04x\n", rval); /* XXX bits */
                    848:        onoff("Parity error response", 0x0001);
                    849:        onoff("Secondary SERR forwarding", 0x0002);
                    850:        onoff("ISA enable", 0x0004);
                    851:        onoff("VGA enable", 0x0008);
                    852:        onoff("Master abort reporting", 0x0020);
                    853:        onoff("Secondary bus reset", 0x0040);
                    854:        onoff("Fast back-to-back capable", 0x0080);
                    855: }
                    856:
                    857: static void
                    858: pci_conf_print_type2(pc, tag, regs)
                    859:        pci_chipset_tag_t pc;
                    860:        pcitag_t tag;
                    861:        const pcireg_t *regs;
                    862: {
                    863:        pcireg_t rval;
                    864:
                    865:        /*
                    866:         * XXX these need to be printed in more detail, need to be
                    867:         * XXX checked against specs/docs, etc.
                    868:         *
                    869:         * This layout was cribbed from the TI PCI1130 PCI-to-CardBus
                    870:         * controller chip documentation, and may not be correct with
                    871:         * respect to various standards. (XXX)
                    872:         */
                    873:
1.28      cgd       874:        pci_conf_print_bar(pc, tag, regs, 0x10,
                    875:            "CardBus socket/ExCA registers");
1.27      cgd       876:
                    877:        printf("    Reserved @ 0x14: 0x%04x\n",
                    878:            (regs[o2i(0x14)] >> 0) & 0xffff);
                    879:        rval = (regs[o2i(0x14)] >> 16) & 0xffff;
                    880:        printf("    Secondary status register: 0x%04x\n", rval);
                    881:        onoff("66 MHz capable", 0x0020);
                    882:        onoff("User Definable Features (UDF) support", 0x0040);
                    883:        onoff("Fast back-to-back capable", 0x0080);
                    884:        onoff("Data parity error detection", 0x0100);
                    885:
                    886:        printf("      DEVSEL timing: ");
                    887:        switch (rval & 0x0600) {
                    888:        case 0x0000:
                    889:                printf("fast");
                    890:                break;
                    891:        case 0x0200:
                    892:                printf("medium");
                    893:                break;
                    894:        case 0x0400:
                    895:                printf("slow");
                    896:                break;
                    897:        default:
                    898:                printf("unknown/reserved");     /* XXX */
                    899:                break;
                    900:        }
                    901:        printf(" (0x%x)\n", (rval & 0x0600) >> 9);
                    902:        onoff("PCI target aborts terminate CardBus bus master transactions",
                    903:            0x0800);
                    904:        onoff("CardBus target aborts terminate PCI bus master transactions",
                    905:            0x1000);
                    906:        onoff("Bus initiator aborts terminate initiator transactions",
                    907:            0x2000);
                    908:        onoff("System error", 0x4000);
                    909:        onoff("Parity error", 0x8000);
                    910:
                    911:        printf("    PCI bus number: 0x%02x\n",
                    912:            (regs[o2i(0x18)] >> 0) & 0xff);
                    913:        printf("    CardBus bus number: 0x%02x\n",
                    914:            (regs[o2i(0x18)] >> 8) & 0xff);
                    915:        printf("    Subordinate bus number: 0x%02x\n",
                    916:            (regs[o2i(0x18)] >> 16) & 0xff);
                    917:        printf("    CardBus latency timer: 0x%02x\n",
                    918:            (regs[o2i(0x18)] >> 24) & 0xff);
                    919:
                    920:        /* XXX Print more prettily */
                    921:        printf("    CardBus memory region 0:\n");
                    922:        printf("      base register:  0x%08x\n", regs[o2i(0x1c)]);
                    923:        printf("      limit register: 0x%08x\n", regs[o2i(0x20)]);
                    924:        printf("    CardBus memory region 1:\n");
                    925:        printf("      base register:  0x%08x\n", regs[o2i(0x24)]);
                    926:        printf("      limit register: 0x%08x\n", regs[o2i(0x28)]);
                    927:        printf("    CardBus I/O region 0:\n");
                    928:        printf("      base register:  0x%08x\n", regs[o2i(0x2c)]);
                    929:        printf("      limit register: 0x%08x\n", regs[o2i(0x30)]);
                    930:        printf("    CardBus I/O region 1:\n");
                    931:        printf("      base register:  0x%08x\n", regs[o2i(0x34)]);
                    932:        printf("      limit register: 0x%08x\n", regs[o2i(0x38)]);
                    933:
                    934:        printf("    Interrupt line: 0x%02x\n",
                    935:            (regs[o2i(0x3c)] >> 0) & 0xff);
                    936:        printf("    Interrupt pin: 0x%02x ",
                    937:            (regs[o2i(0x3c)] >> 8) & 0xff);
                    938:        switch ((regs[o2i(0x3c)] >> 8) & 0xff) {
                    939:        case PCI_INTERRUPT_PIN_NONE:
                    940:                printf("(none)");
                    941:                break;
                    942:        case PCI_INTERRUPT_PIN_A:
                    943:                printf("(pin A)");
                    944:                break;
                    945:        case PCI_INTERRUPT_PIN_B:
                    946:                printf("(pin B)");
                    947:                break;
                    948:        case PCI_INTERRUPT_PIN_C:
                    949:                printf("(pin C)");
                    950:                break;
                    951:        case PCI_INTERRUPT_PIN_D:
                    952:                printf("(pin D)");
                    953:                break;
                    954:        default:
                    955:                printf("(???)");
                    956:                break;
                    957:        }
                    958:        printf("\n");
                    959:        rval = (regs[o2i(0x3c)] >> 16) & 0xffff;
                    960:        printf("    Bridge control register: 0x%04x\n", rval);
                    961:        onoff("Parity error response", 0x0001);
                    962:        onoff("CardBus SERR forwarding", 0x0002);
                    963:        onoff("ISA enable", 0x0004);
                    964:        onoff("VGA enable", 0x0008);
                    965:        onoff("CardBus master abort reporting", 0x0020);
                    966:        onoff("CardBus reset", 0x0040);
                    967:        onoff("Functional interrupts routed by ExCA registers", 0x0080);
                    968:        onoff("Memory window 0 prefetchable", 0x0100);
                    969:        onoff("Memory window 1 prefetchable", 0x0200);
                    970:        onoff("Write posting enable", 0x0400);
1.28      cgd       971:
                    972:        rval = regs[o2i(0x40)];
                    973:        printf("    Subsystem vendor ID: 0x%04x\n", PCI_VENDOR(rval));
                    974:        printf("    Subsystem ID: 0x%04x\n", PCI_PRODUCT(rval));
                    975:
                    976:        pci_conf_print_bar(pc, tag, regs, 0x44, "legacy-mode registers");
1.27      cgd       977: }
                    978:
1.26      cgd       979: void
                    980: pci_conf_print(pc, tag, printfn)
                    981:        pci_chipset_tag_t pc;
                    982:        pcitag_t tag;
                    983:        void (*printfn)(pci_chipset_tag_t, pcitag_t, const pcireg_t *);
                    984: {
                    985:        pcireg_t regs[o2i(256)];
1.28      cgd       986:        int off, endoff, hdrtype;
1.27      cgd       987:        const char *typename;
1.26      cgd       988:        void (*typeprintfn)(pci_chipset_tag_t, pcitag_t, const pcireg_t *);
                    989:
                    990:        printf("PCI configuration registers:\n");
                    991:
                    992:        for (off = 0; off < 256; off += 4)
                    993:                regs[o2i(off)] = pci_conf_read(pc, tag, off);
                    994:
                    995:        /* common header */
                    996:        printf("  Common header:\n");
1.28      cgd       997:        pci_conf_print_regs(regs, 0, 16);
                    998:
1.26      cgd       999:        printf("\n");
                   1000:        pci_conf_print_common(pc, tag, regs);
                   1001:        printf("\n");
                   1002:
                   1003:        /* type-dependent header */
                   1004:        hdrtype = PCI_HDRTYPE_TYPE(regs[o2i(PCI_BHLC_REG)]);
                   1005:        switch (hdrtype) {              /* XXX make a table, eventually */
                   1006:        case 0:
1.27      cgd      1007:                /* Standard device header */
                   1008:                typename = "\"normal\" device";
                   1009:                typeprintfn = &pci_conf_print_type0;
1.28      cgd      1010:                endoff = 64;
1.27      cgd      1011:                break;
                   1012:        case 1:
                   1013:                /* PCI-PCI bridge header */
                   1014:                typename = "PCI-PCI bridge";
1.26      cgd      1015:                typeprintfn = &pci_conf_print_type1;
1.28      cgd      1016:                endoff = 64;
1.26      cgd      1017:                break;
1.27      cgd      1018:        case 2:
                   1019:                /* PCI-CardBus bridge header */
                   1020:                typename = "PCI-CardBus bridge";
                   1021:                typeprintfn = &pci_conf_print_type2;
1.28      cgd      1022:                endoff = 72;
1.27      cgd      1023:                break;
1.26      cgd      1024:        default:
1.27      cgd      1025:                typename = NULL;
1.26      cgd      1026:                typeprintfn = 0;
1.28      cgd      1027:                endoff = 64;
                   1028:                break;
1.26      cgd      1029:        }
1.27      cgd      1030:        printf("  Type %d ", hdrtype);
                   1031:        if (typename != NULL)
                   1032:                printf("(%s) ", typename);
                   1033:        printf("header:\n");
1.28      cgd      1034:        pci_conf_print_regs(regs, 16, endoff);
1.27      cgd      1035:        printf("\n");
1.26      cgd      1036:        if (typeprintfn)
                   1037:                (*typeprintfn)(pc, tag, regs);
                   1038:        else
                   1039:                printf("    Don't know how to pretty-print type %d header.\n",
                   1040:                    hdrtype);
                   1041:        printf("\n");
                   1042:
                   1043:        /* device-dependent header */
                   1044:        printf("  Device-dependent header:\n");
1.28      cgd      1045:        pci_conf_print_regs(regs, endoff, 256);
1.26      cgd      1046:        printf("\n");
                   1047:        if (printfn)
                   1048:                (*printfn)(pc, tag, regs);
                   1049:        else
                   1050:                printf("    Don't know how to pretty-print device-dependent header.\n");
                   1051:        printf("\n");
1.1       mycroft  1052: }

CVSweb <webmaster@jp.NetBSD.org>