[BACK]Return to pci_machdep.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / x86 / pci

Annotation of src/sys/arch/x86/pci/pci_machdep.c, Revision 1.53.4.3

1.53.4.3! mrg         1: /*     $NetBSD: pci_machdep.c,v 1.53.4.2 2012/03/04 00:46:16 mrg Exp $ */
1.1       fvdl        2:
                      3: /*-
                      4:  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
                      5:  * All rights reserved.
                      6:  *
                      7:  * This code is derived from software contributed to The NetBSD Foundation
                      8:  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
                      9:  * NASA Ames Research Center.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     21:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     22:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     23:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     24:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     25:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     26:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     27:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     28:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     29:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     30:  * POSSIBILITY OF SUCH DAMAGE.
                     31:  */
                     32:
                     33: /*
                     34:  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
                     35:  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
                     36:  *
                     37:  * Redistribution and use in source and binary forms, with or without
                     38:  * modification, are permitted provided that the following conditions
                     39:  * are met:
                     40:  * 1. Redistributions of source code must retain the above copyright
                     41:  *    notice, this list of conditions and the following disclaimer.
                     42:  * 2. Redistributions in binary form must reproduce the above copyright
                     43:  *    notice, this list of conditions and the following disclaimer in the
                     44:  *    documentation and/or other materials provided with the distribution.
                     45:  * 3. All advertising materials mentioning features or use of this software
                     46:  *    must display the following acknowledgement:
                     47:  *     This product includes software developed by Charles M. Hannum.
                     48:  * 4. The name of the author may not be used to endorse or promote products
                     49:  *    derived from this software without specific prior written permission.
                     50:  *
                     51:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
                     52:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
                     53:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
                     54:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
                     55:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
                     56:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
                     57:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
                     58:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
                     59:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
                     60:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     61:  */
                     62:
                     63: /*
                     64:  * Machine-specific functions for PCI autoconfiguration.
                     65:  *
                     66:  * On PCs, there are two methods of generating PCI configuration cycles.
                     67:  * We try to detect the appropriate mechanism for this machine and set
                     68:  * up a few function pointers to access the correct method directly.
                     69:  *
                     70:  * The configuration method can be hard-coded in the config file by
                     71:  * using `options PCI_CONF_MODE=N', where `N' is the configuration mode
1.53.4.3! mrg        72:  * as defined section 3.6.4.1, `Generating Configuration Cycles'.
1.1       fvdl       73:  */
                     74:
                     75: #include <sys/cdefs.h>
1.53.4.3! mrg        76: __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.53.4.2 2012/03/04 00:46:16 mrg Exp $");
1.1       fvdl       77:
                     78: #include <sys/types.h>
                     79: #include <sys/param.h>
                     80: #include <sys/time.h>
                     81: #include <sys/systm.h>
                     82: #include <sys/errno.h>
                     83: #include <sys/device.h>
1.29      ad         84: #include <sys/bus.h>
1.42      dyoung     85: #include <sys/cpu.h>
1.43      dyoung     86: #include <sys/kmem.h>
1.1       fvdl       87:
                     88: #include <uvm/uvm_extern.h>
                     89:
1.10      yamt       90: #include <machine/bus_private.h>
1.1       fvdl       91:
                     92: #include <machine/pio.h>
1.30      ad         93: #include <machine/lock.h>
1.1       fvdl       94:
1.3       fvdl       95: #include <dev/isa/isareg.h>
1.1       fvdl       96: #include <dev/isa/isavar.h>
                     97: #include <dev/pci/pcivar.h>
                     98: #include <dev/pci/pcireg.h>
1.43      dyoung     99: #include <dev/pci/pccbbreg.h>
1.1       fvdl      100: #include <dev/pci/pcidevs.h>
1.52      dyoung    101: #include <dev/pci/genfb_pcivar.h>
                    102:
                    103: #include <dev/wsfb/genfbvar.h>
                    104: #include <arch/x86/include/genfb_machdep.h>
                    105: #include <dev/ic/vgareg.h>
1.1       fvdl      106:
1.37      jmcneill  107: #include "acpica.h"
1.52      dyoung    108: #include "genfb.h"
                    109: #include "isa.h"
                    110: #include "opt_acpi.h"
                    111: #include "opt_ddb.h"
1.14      bouyer    112: #include "opt_mpbios.h"
1.52      dyoung    113: #include "opt_vga.h"
                    114: #include "pci.h"
                    115: #include "wsdisplay.h"
                    116:
                    117: #ifdef DDB
                    118: #include <machine/db_machdep.h>
                    119: #include <ddb/db_sym.h>
                    120: #include <ddb/db_extern.h>
                    121: #endif
                    122:
                    123: #ifdef VGA_POST
                    124: #include <x86/vga_post.h>
                    125: #endif
                    126:
                    127: #include <machine/autoconf.h>
                    128: #include <machine/bootinfo.h>
1.14      bouyer    129:
                    130: #ifdef MPBIOS
                    131: #include <machine/mpbiosvar.h>
                    132: #endif
                    133:
1.37      jmcneill  134: #if NACPICA > 0
1.14      bouyer    135: #include <machine/mpacpi.h>
                    136: #endif
                    137:
1.16      christos  138: #include <machine/mpconfig.h>
                    139:
1.1       fvdl      140: #include "opt_pci_conf_mode.h"
                    141:
1.38      dyoung    142: #ifdef PCI_CONF_MODE
                    143: #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
                    144: static int pci_mode = PCI_CONF_MODE;
                    145: #else
                    146: #error Invalid PCI configuration mode.
                    147: #endif
                    148: #else
                    149: static int pci_mode = -1;
                    150: #endif
1.1       fvdl      151:
1.42      dyoung    152: struct pci_conf_lock {
                    153:        uint32_t cl_cpuno;      /* 0: unlocked
                    154:                                 * 1 + n: locked by CPU n (0 <= n)
                    155:                                 */
                    156:        uint32_t cl_sel;        /* the address that's being read. */
                    157: };
                    158:
                    159: static void pci_conf_unlock(struct pci_conf_lock *);
                    160: static uint32_t pci_conf_selector(pcitag_t, int);
                    161: static unsigned int pci_conf_port(pcitag_t, int);
                    162: static void pci_conf_select(uint32_t);
                    163: static void pci_conf_lock(struct pci_conf_lock *, uint32_t);
1.11      sekiya    164: static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *);
                    165: struct pci_bridge_hook_arg {
1.53.4.3! mrg       166:        void (*func)(pci_chipset_tag_t, pcitag_t, void *);
        !           167:        void *arg;
        !           168: };
1.11      sekiya    169:
1.1       fvdl      170: #define        PCI_MODE1_ENABLE        0x80000000UL
                    171: #define        PCI_MODE1_ADDRESS_REG   0x0cf8
                    172: #define        PCI_MODE1_DATA_REG      0x0cfc
                    173:
                    174: #define        PCI_MODE2_ENABLE_REG    0x0cf8
                    175: #define        PCI_MODE2_FORWARD_REG   0x0cfa
                    176:
1.53.4.3! mrg       177: #define _m1tag(b, d, f) \
        !           178:        (PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8))
1.1       fvdl      179: #define _qe(bus, dev, fcn, vend, prod) \
1.53.4.3! mrg       180:        {_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
        !           181: struct {
        !           182:        uint32_t tag;
1.1       fvdl      183:        pcireg_t id;
                    184: } pcim1_quirk_tbl[] = {
                    185:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
                    186:        /* XXX Triflex2 not tested */
                    187:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
                    188:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
                    189:        /* Triton needed for Connectix Virtual PC */
                    190:        _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
                    191:        /* Connectix Virtual PC 5 has a 440BX */
                    192:        _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
1.15      soren     193:        /* Parallels Desktop for Mac */
                    194:        _qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO),
                    195:        _qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS),
1.36      drochner  196:        /* SIS 740 */
                    197:        _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_740),
1.12      christos  198:        /* SIS 741 */
                    199:        _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741),
1.53.4.1  mrg       200:        /* VIA Technologies VX900 */
1.53.4.3! mrg       201:        _qe(0, 0, 0, PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VX900_HB),
        !           202:        {0, 0xffffffff} /* patchable */
1.1       fvdl      203: };
1.53.4.3! mrg       204: #undef _m1tag
        !           205: #undef _id
1.1       fvdl      206: #undef _qe
                    207:
                    208: /*
                    209:  * PCI doesn't have any special needs; just use the generic versions
                    210:  * of these functions.
                    211:  */
                    212: struct x86_bus_dma_tag pci_bus_dma_tag = {
1.46      christos  213:        ._tag_needs_free        = 0,
1.3       fvdl      214: #if defined(_LP64) || defined(PAE)
1.46      christos  215:        ._bounce_thresh         = PCI32_DMA_BOUNCE_THRESHOLD,
                    216:        ._bounce_alloc_lo       = ISA_DMA_BOUNCE_THRESHOLD,
                    217:        ._bounce_alloc_hi       = PCI32_DMA_BOUNCE_THRESHOLD,
1.3       fvdl      218: #else
1.46      christos  219:        ._bounce_thresh         = 0,
                    220:        ._bounce_alloc_lo       = 0,
                    221:        ._bounce_alloc_hi       = 0,
                    222: #endif
                    223:        ._may_bounce            = NULL,
1.1       fvdl      224: };
1.5       fvdl      225:
                    226: #ifdef _LP64
                    227: struct x86_bus_dma_tag pci_bus_dma64_tag = {
1.46      christos  228:        ._tag_needs_free        = 0,
                    229:        ._bounce_thresh         = 0,
                    230:        ._bounce_alloc_lo       = 0,
                    231:        ._bounce_alloc_hi       = 0,
                    232:        ._may_bounce            = NULL,
1.5       fvdl      233: };
                    234: #endif
1.1       fvdl      235:
1.42      dyoung    236: static struct pci_conf_lock cl0 = {
                    237:          .cl_cpuno = 0UL
                    238:        , .cl_sel = 0UL
                    239: };
                    240:
                    241: static struct pci_conf_lock * const cl = &cl0;
                    242:
1.52      dyoung    243: #if NGENFB > 0 && NACPICA > 0 && defined(VGA_POST)
                    244: extern int acpi_md_vbios_reset;
                    245: extern int acpi_md_vesa_modenum;
                    246: #endif
                    247:
                    248: static struct genfb_colormap_callback gfb_cb;
                    249: static struct genfb_pmf_callback pmf_cb;
                    250: static struct genfb_mode_callback mode_cb;
                    251: #ifdef VGA_POST
                    252: static struct vga_post *vga_posth = NULL;
                    253: #endif
                    254:
1.42      dyoung    255: static void
                    256: pci_conf_lock(struct pci_conf_lock *ocl, uint32_t sel)
                    257: {
                    258:        uint32_t cpuno;
                    259:
                    260:        KASSERT(sel != 0);
                    261:
                    262:        kpreempt_disable();
                    263:        cpuno = cpu_number() + 1;
                    264:        /* If the kernel enters pci_conf_lock() through an interrupt
                    265:         * handler, then the CPU may already hold the lock.
                    266:         *
                    267:         * If the CPU does not already hold the lock, spin until
                    268:         * we can acquire it.
                    269:         */
                    270:        if (cpuno == cl->cl_cpuno) {
                    271:                ocl->cl_cpuno = cpuno;
                    272:        } else {
1.44      dyoung    273:                u_int spins;
                    274:
1.42      dyoung    275:                ocl->cl_cpuno = 0;
1.44      dyoung    276:
                    277:                spins = SPINLOCK_BACKOFF_MIN;
                    278:                while (atomic_cas_32(&cl->cl_cpuno, 0, cpuno) != 0) {
                    279:                        SPINLOCK_BACKOFF(spins);
                    280: #ifdef LOCKDEBUG
                    281:                        if (SPINLOCK_SPINOUT(spins)) {
                    282:                                panic("%s: cpu %" PRId32
                    283:                                    " spun out waiting for cpu %" PRId32,
                    284:                                    __func__, cpuno, cl->cl_cpuno);
                    285:                        }
                    286: #endif /* LOCKDEBUG */
                    287:                }
1.42      dyoung    288:        }
                    289:
                    290:        /* Only one CPU can be here, so an interlocked atomic_swap(3)
                    291:         * is not necessary.
                    292:         *
                    293:         * Evaluating atomic_cas_32_ni()'s argument, cl->cl_sel,
                    294:         * and applying atomic_cas_32_ni() is not an atomic operation,
                    295:         * however, any interrupt that, in the middle of the
                    296:         * operation, modifies cl->cl_sel, will also restore
                    297:         * cl->cl_sel.  So cl->cl_sel will have the same value when
                    298:         * we apply atomic_cas_32_ni() as when we evaluated it,
                    299:         * before.
                    300:         */
                    301:        ocl->cl_sel = atomic_cas_32_ni(&cl->cl_sel, cl->cl_sel, sel);
                    302:        pci_conf_select(sel);
                    303: }
                    304:
                    305: static void
                    306: pci_conf_unlock(struct pci_conf_lock *ocl)
                    307: {
                    308:        uint32_t sel;
                    309:
                    310:        sel = atomic_cas_32_ni(&cl->cl_sel, cl->cl_sel, ocl->cl_sel);
                    311:        pci_conf_select(ocl->cl_sel);
                    312:        if (ocl->cl_cpuno != cl->cl_cpuno)
                    313:                atomic_cas_32(&cl->cl_cpuno, cl->cl_cpuno, ocl->cl_cpuno);
                    314:        kpreempt_enable();
                    315: }
                    316:
1.39      dyoung    317: static uint32_t
                    318: pci_conf_selector(pcitag_t tag, int reg)
                    319: {
                    320:        static const pcitag_t mode2_mask = {
                    321:                .mode2 = {
                    322:                          .enable = 0xff
                    323:                        , .forward = 0xff
                    324:                }
                    325:        };
                    326:
                    327:        switch (pci_mode) {
                    328:        case 1:
                    329:                return tag.mode1 | reg;
                    330:        case 2:
                    331:                return tag.mode1 & mode2_mask.mode1;
                    332:        default:
                    333:                panic("%s: mode not configured", __func__);
                    334:        }
                    335: }
                    336:
                    337: static unsigned int
                    338: pci_conf_port(pcitag_t tag, int reg)
                    339: {
                    340:        switch (pci_mode) {
                    341:        case 1:
                    342:                return PCI_MODE1_DATA_REG;
                    343:        case 2:
                    344:                return tag.mode2.port | reg;
                    345:        default:
                    346:                panic("%s: mode not configured", __func__);
                    347:        }
                    348: }
                    349:
                    350: static void
1.42      dyoung    351: pci_conf_select(uint32_t sel)
1.39      dyoung    352: {
                    353:        pcitag_t tag;
                    354:
                    355:        switch (pci_mode) {
                    356:        case 1:
1.42      dyoung    357:                outl(PCI_MODE1_ADDRESS_REG, sel);
1.39      dyoung    358:                return;
                    359:        case 2:
1.42      dyoung    360:                tag.mode1 = sel;
1.39      dyoung    361:                outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
                    362:                if (tag.mode2.enable != 0)
                    363:                        outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
                    364:                return;
                    365:        default:
                    366:                panic("%s: mode not configured", __func__);
                    367:        }
                    368: }
                    369:
1.1       fvdl      370: void
1.32      dyoung    371: pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
1.1       fvdl      372: {
                    373:
                    374:        if (pba->pba_bus == 0)
1.26      mjf       375:                aprint_normal(": configuration mode %d", pci_mode);
1.4       fvdl      376: #ifdef MPBIOS
                    377:        mpbios_pci_attach_hook(parent, self, pba);
                    378: #endif
1.37      jmcneill  379: #if NACPICA > 0
1.4       fvdl      380:        mpacpi_pci_attach_hook(parent, self, pba);
                    381: #endif
1.1       fvdl      382: }
                    383:
                    384: int
1.18      christos  385: pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
1.1       fvdl      386: {
                    387:        /*
                    388:         * Bus number is irrelevant.  If Configuration Mechanism 2 is in
                    389:         * use, can only have devices 0-15 on any bus.  If Configuration
                    390:         * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal'
                    391:         * range).
                    392:         */
                    393:        if (pci_mode == 2)
                    394:                return (16);
                    395:        else
                    396:                return (32);
                    397: }
                    398:
                    399: pcitag_t
1.18      christos  400: pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
1.1       fvdl      401: {
1.47      dyoung    402:        pci_chipset_tag_t ipc;
1.1       fvdl      403:        pcitag_t tag;
                    404:
1.47      dyoung    405:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    406:                if ((ipc->pc_present & PCI_OVERRIDE_MAKE_TAG) == 0)
                    407:                        continue;
                    408:                return (*ipc->pc_ov->ov_make_tag)(ipc->pc_ctx,
                    409:                    pc, bus, device, function);
1.41      dyoung    410:        }
1.40      dyoung    411:
1.1       fvdl      412:        switch (pci_mode) {
                    413:        case 1:
1.38      dyoung    414:                if (bus >= 256 || device >= 32 || function >= 8)
1.39      dyoung    415:                        panic("%s: bad request", __func__);
1.38      dyoung    416:
                    417:                tag.mode1 = PCI_MODE1_ENABLE |
                    418:                            (bus << 16) | (device << 11) | (function << 8);
                    419:                return tag;
1.1       fvdl      420:        case 2:
1.38      dyoung    421:                if (bus >= 256 || device >= 16 || function >= 8)
1.39      dyoung    422:                        panic("%s: bad request", __func__);
1.38      dyoung    423:
                    424:                tag.mode2.port = 0xc000 | (device << 8);
                    425:                tag.mode2.enable = 0xf0 | (function << 1);
                    426:                tag.mode2.forward = bus;
                    427:                return tag;
1.1       fvdl      428:        default:
1.39      dyoung    429:                panic("%s: mode not configured", __func__);
1.1       fvdl      430:        }
                    431: }
                    432:
                    433: void
1.18      christos  434: pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag,
1.17      christos  435:     int *bp, int *dp, int *fp)
1.1       fvdl      436: {
1.47      dyoung    437:        pci_chipset_tag_t ipc;
1.1       fvdl      438:
1.47      dyoung    439:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    440:                if ((ipc->pc_present & PCI_OVERRIDE_DECOMPOSE_TAG) == 0)
                    441:                        continue;
                    442:                (*ipc->pc_ov->ov_decompose_tag)(ipc->pc_ctx,
                    443:                    pc, tag, bp, dp, fp);
                    444:                return;
1.40      dyoung    445:        }
                    446:
1.1       fvdl      447:        switch (pci_mode) {
                    448:        case 1:
1.38      dyoung    449:                if (bp != NULL)
                    450:                        *bp = (tag.mode1 >> 16) & 0xff;
                    451:                if (dp != NULL)
                    452:                        *dp = (tag.mode1 >> 11) & 0x1f;
                    453:                if (fp != NULL)
                    454:                        *fp = (tag.mode1 >> 8) & 0x7;
                    455:                return;
1.1       fvdl      456:        case 2:
1.38      dyoung    457:                if (bp != NULL)
                    458:                        *bp = tag.mode2.forward & 0xff;
                    459:                if (dp != NULL)
                    460:                        *dp = (tag.mode2.port >> 8) & 0xf;
                    461:                if (fp != NULL)
                    462:                        *fp = (tag.mode2.enable >> 1) & 0x7;
                    463:                return;
1.1       fvdl      464:        default:
1.39      dyoung    465:                panic("%s: mode not configured", __func__);
1.1       fvdl      466:        }
                    467: }
                    468:
                    469: pcireg_t
1.43      dyoung    470: pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
1.1       fvdl      471: {
1.47      dyoung    472:        pci_chipset_tag_t ipc;
1.1       fvdl      473:        pcireg_t data;
1.42      dyoung    474:        struct pci_conf_lock ocl;
1.1       fvdl      475:
1.31      dyoung    476:        KASSERT((reg & 0x3) == 0);
1.40      dyoung    477:
1.47      dyoung    478:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    479:                if ((ipc->pc_present & PCI_OVERRIDE_CONF_READ) == 0)
                    480:                        continue;
                    481:                return (*ipc->pc_ov->ov_conf_read)(ipc->pc_ctx, pc, tag, reg);
1.41      dyoung    482:        }
1.40      dyoung    483:
1.42      dyoung    484:        pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
1.39      dyoung    485:        data = inl(pci_conf_port(tag, reg));
1.42      dyoung    486:        pci_conf_unlock(&ocl);
1.39      dyoung    487:        return data;
1.1       fvdl      488: }
                    489:
                    490: void
1.43      dyoung    491: pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
1.1       fvdl      492: {
1.47      dyoung    493:        pci_chipset_tag_t ipc;
1.42      dyoung    494:        struct pci_conf_lock ocl;
1.1       fvdl      495:
1.31      dyoung    496:        KASSERT((reg & 0x3) == 0);
1.40      dyoung    497:
1.47      dyoung    498:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    499:                if ((ipc->pc_present & PCI_OVERRIDE_CONF_WRITE) == 0)
                    500:                        continue;
                    501:                (*ipc->pc_ov->ov_conf_write)(ipc->pc_ctx, pc, tag, reg,
                    502:                    data);
                    503:                return;
1.40      dyoung    504:        }
                    505:
1.42      dyoung    506:        pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
1.39      dyoung    507:        outl(pci_conf_port(tag, reg), data);
1.42      dyoung    508:        pci_conf_unlock(&ocl);
1.38      dyoung    509: }
1.1       fvdl      510:
1.38      dyoung    511: void
                    512: pci_mode_set(int mode)
                    513: {
                    514:        KASSERT(pci_mode == -1 || pci_mode == mode);
1.1       fvdl      515:
1.38      dyoung    516:        pci_mode = mode;
1.1       fvdl      517: }
                    518:
                    519: int
1.33      cegger    520: pci_mode_detect(void)
1.1       fvdl      521: {
1.33      cegger    522:        uint32_t sav, val;
1.1       fvdl      523:        int i;
                    524:        pcireg_t idreg;
                    525:
                    526:        if (pci_mode != -1)
                    527:                return pci_mode;
                    528:
                    529:        /*
                    530:         * We try to divine which configuration mode the host bridge wants.
                    531:         */
                    532:
                    533:        sav = inl(PCI_MODE1_ADDRESS_REG);
                    534:
                    535:        pci_mode = 1; /* assume this for now */
                    536:        /*
                    537:         * catch some known buggy implementations of mode 1
                    538:         */
1.27      dyoung    539:        for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) {
1.1       fvdl      540:                pcitag_t t;
                    541:
1.53.4.3! mrg       542:                if (!pcim1_quirk_tbl[i].tag)
        !           543:                        break;
        !           544:                t.mode1 = pcim1_quirk_tbl[i].tag;
        !           545:                idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */
1.1       fvdl      546:                if (idreg == pcim1_quirk_tbl[i].id) {
                    547: #ifdef DEBUG
                    548:                        printf("known mode 1 PCI chipset (%08x)\n",
                    549:                               idreg);
                    550: #endif
                    551:                        return (pci_mode);
                    552:                }
                    553:        }
                    554:
                    555:        /*
                    556:         * Strong check for standard compliant mode 1:
                    557:         * 1. bit 31 ("enable") can be set
                    558:         * 2. byte/word access does not affect register
                    559:         */
                    560:        outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
                    561:        outb(PCI_MODE1_ADDRESS_REG + 3, 0);
                    562:        outw(PCI_MODE1_ADDRESS_REG + 2, 0);
                    563:        val = inl(PCI_MODE1_ADDRESS_REG);
                    564:        if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
                    565: #ifdef DEBUG
                    566:                printf("pci_mode_detect: mode 1 enable failed (%x)\n",
                    567:                       val);
                    568: #endif
                    569:                goto not1;
                    570:        }
                    571:        outl(PCI_MODE1_ADDRESS_REG, 0);
                    572:        val = inl(PCI_MODE1_ADDRESS_REG);
                    573:        if ((val & 0x80fffffc) != 0)
                    574:                goto not1;
                    575:        return (pci_mode);
                    576: not1:
                    577:        outl(PCI_MODE1_ADDRESS_REG, sav);
                    578:
                    579:        /*
                    580:         * This mode 2 check is quite weak (and known to give false
                    581:         * positives on some Compaq machines).
                    582:         * However, this doesn't matter, because this is the
                    583:         * last test, and simply no PCI devices will be found if
                    584:         * this happens.
                    585:         */
                    586:        outb(PCI_MODE2_ENABLE_REG, 0);
                    587:        outb(PCI_MODE2_FORWARD_REG, 0);
                    588:        if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
                    589:            inb(PCI_MODE2_FORWARD_REG) != 0)
                    590:                goto not2;
                    591:        return (pci_mode = 2);
                    592: not2:
                    593:
                    594:        return (pci_mode = 0);
                    595: }
                    596:
                    597: /*
                    598:  * Determine which flags should be passed to the primary PCI bus's
                    599:  * autoconfiguration node.  We use this to detect broken chipsets
                    600:  * which cannot safely use memory-mapped device access.
                    601:  */
                    602: int
1.35      cegger    603: pci_bus_flags(void)
1.1       fvdl      604: {
1.45      dyoung    605:        int rval = PCI_FLAGS_IO_OKAY | PCI_FLAGS_MEM_OKAY |
1.1       fvdl      606:            PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
                    607:        int device, maxndevs;
                    608:        pcitag_t tag;
                    609:        pcireg_t id;
                    610:
                    611:        maxndevs = pci_bus_maxdevs(NULL, 0);
                    612:
                    613:        for (device = 0; device < maxndevs; device++) {
                    614:                tag = pci_make_tag(NULL, 0, device, 0);
                    615:                id = pci_conf_read(NULL, tag, PCI_ID_REG);
                    616:
                    617:                /* Invalid vendor ID value? */
                    618:                if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    619:                        continue;
                    620:                /* XXX Not invalid, but we've done this ~forever. */
                    621:                if (PCI_VENDOR(id) == 0)
                    622:                        continue;
                    623:
                    624:                switch (PCI_VENDOR(id)) {
                    625:                case PCI_VENDOR_SIS:
                    626:                        switch (PCI_PRODUCT(id)) {
                    627:                        case PCI_PRODUCT_SIS_85C496:
                    628:                                goto disable_mem;
                    629:                        }
                    630:                        break;
                    631:                }
                    632:        }
                    633:
                    634:        return (rval);
                    635:
                    636:  disable_mem:
                    637:        printf("Warning: broken PCI-Host bridge detected; "
                    638:            "disabling memory-mapped access\n");
1.45      dyoung    639:        rval &= ~(PCI_FLAGS_MEM_OKAY|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY|
1.1       fvdl      640:            PCI_FLAGS_MWI_OKAY);
                    641:        return (rval);
                    642: }
1.11      sekiya    643:
                    644: void
                    645: pci_device_foreach(pci_chipset_tag_t pc, int maxbus,
                    646:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
                    647: {
                    648:        pci_device_foreach_min(pc, 0, maxbus, func, context);
                    649: }
                    650:
                    651: void
                    652: pci_device_foreach_min(pci_chipset_tag_t pc, int minbus, int maxbus,
                    653:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
                    654: {
                    655:        const struct pci_quirkdata *qd;
                    656:        int bus, device, function, maxdevs, nfuncs;
                    657:        pcireg_t id, bhlcr;
                    658:        pcitag_t tag;
                    659:
                    660:        for (bus = minbus; bus <= maxbus; bus++) {
                    661:                maxdevs = pci_bus_maxdevs(pc, bus);
                    662:                for (device = 0; device < maxdevs; device++) {
                    663:                        tag = pci_make_tag(pc, bus, device, 0);
                    664:                        id = pci_conf_read(pc, tag, PCI_ID_REG);
                    665:
                    666:                        /* Invalid vendor ID value? */
                    667:                        if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    668:                                continue;
                    669:                        /* XXX Not invalid, but we've done this ~forever. */
                    670:                        if (PCI_VENDOR(id) == 0)
                    671:                                continue;
                    672:
                    673:                        qd = pci_lookup_quirkdata(PCI_VENDOR(id),
                    674:                                PCI_PRODUCT(id));
                    675:
                    676:                        bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
                    677:                        if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
                    678:                             (qd != NULL &&
1.53.4.3! mrg       679:                             (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
1.11      sekiya    680:                                nfuncs = 8;
                    681:                        else
                    682:                                nfuncs = 1;
                    683:
                    684:                        for (function = 0; function < nfuncs; function++) {
                    685:                                tag = pci_make_tag(pc, bus, device, function);
                    686:                                id = pci_conf_read(pc, tag, PCI_ID_REG);
                    687:
                    688:                                /* Invalid vendor ID value? */
                    689:                                if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    690:                                        continue;
                    691:                                /*
                    692:                                 * XXX Not invalid, but we've done this
                    693:                                 * ~forever.
                    694:                                 */
                    695:                                if (PCI_VENDOR(id) == 0)
                    696:                                        continue;
                    697:                                (*func)(pc, tag, context);
                    698:                        }
                    699:                }
                    700:        }
                    701: }
                    702:
                    703: void
                    704: pci_bridge_foreach(pci_chipset_tag_t pc, int minbus, int maxbus,
                    705:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *ctx)
                    706: {
                    707:        struct pci_bridge_hook_arg bridge_hook;
                    708:
                    709:        bridge_hook.func = func;
1.53.4.3! mrg       710:        bridge_hook.arg = ctx;
1.11      sekiya    711:
                    712:        pci_device_foreach_min(pc, minbus, maxbus, pci_bridge_hook,
1.53.4.3! mrg       713:                &bridge_hook);
1.11      sekiya    714: }
                    715:
                    716: static void
                    717: pci_bridge_hook(pci_chipset_tag_t pc, pcitag_t tag, void *ctx)
                    718: {
                    719:        struct pci_bridge_hook_arg *bridge_hook = (void *)ctx;
                    720:        pcireg_t reg;
                    721:
                    722:        reg = pci_conf_read(pc, tag, PCI_CLASS_REG);
                    723:        if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE &&
1.53.4.3! mrg       724:             (PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI ||
1.11      sekiya    725:                PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_CARDBUS)) {
                    726:                (*bridge_hook->func)(pc, tag, bridge_hook->arg);
                    727:        }
                    728: }
1.43      dyoung    729:
                    730: static const void *
                    731: bit_to_function_pointer(const struct pci_overrides *ov, uint64_t bit)
                    732: {
                    733:        switch (bit) {
                    734:        case PCI_OVERRIDE_CONF_READ:
                    735:                return ov->ov_conf_read;
                    736:        case PCI_OVERRIDE_CONF_WRITE:
                    737:                return ov->ov_conf_write;
                    738:        case PCI_OVERRIDE_INTR_MAP:
                    739:                return ov->ov_intr_map;
                    740:        case PCI_OVERRIDE_INTR_STRING:
                    741:                return ov->ov_intr_string;
                    742:        case PCI_OVERRIDE_INTR_EVCNT:
                    743:                return ov->ov_intr_evcnt;
                    744:        case PCI_OVERRIDE_INTR_ESTABLISH:
                    745:                return ov->ov_intr_establish;
                    746:        case PCI_OVERRIDE_INTR_DISESTABLISH:
                    747:                return ov->ov_intr_disestablish;
                    748:        case PCI_OVERRIDE_MAKE_TAG:
                    749:                return ov->ov_make_tag;
                    750:        case PCI_OVERRIDE_DECOMPOSE_TAG:
                    751:                return ov->ov_decompose_tag;
                    752:        default:
                    753:                return NULL;
                    754:        }
                    755: }
                    756:
                    757: void
                    758: pci_chipset_tag_destroy(pci_chipset_tag_t pc)
                    759: {
                    760:        kmem_free(pc, sizeof(struct pci_chipset_tag));
                    761: }
                    762:
                    763: int
                    764: pci_chipset_tag_create(pci_chipset_tag_t opc, const uint64_t present,
                    765:     const struct pci_overrides *ov, void *ctx, pci_chipset_tag_t *pcp)
                    766: {
                    767:        uint64_t bit, bits, nbits;
                    768:        pci_chipset_tag_t pc;
                    769:        const void *fp;
                    770:
                    771:        if (ov == NULL || present == 0)
                    772:                return EINVAL;
                    773:
                    774:        pc = kmem_alloc(sizeof(struct pci_chipset_tag), KM_SLEEP);
                    775:
                    776:        if (pc == NULL)
                    777:                return ENOMEM;
                    778:
                    779:        pc->pc_super = opc;
                    780:
                    781:        for (bits = present; bits != 0; bits = nbits) {
                    782:                nbits = bits & (bits - 1);
                    783:                bit = nbits ^ bits;
                    784:                if ((fp = bit_to_function_pointer(ov, bit)) == NULL) {
1.51      dyoung    785: #ifdef DEBUG
1.43      dyoung    786:                        printf("%s: missing bit %" PRIx64 "\n", __func__, bit);
1.51      dyoung    787: #endif
1.43      dyoung    788:                        goto einval;
                    789:                }
                    790:        }
                    791:
                    792:        pc->pc_ov = ov;
                    793:        pc->pc_present = present;
                    794:        pc->pc_ctx = ctx;
                    795:
                    796:        *pcp = pc;
                    797:
                    798:        return 0;
                    799: einval:
                    800:        kmem_free(pc, sizeof(struct pci_chipset_tag));
                    801:        return EINVAL;
                    802: }
1.52      dyoung    803:
                    804: static void
                    805: x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b)
                    806: {
                    807:        outb(0x3c0 + VGA_DAC_ADDRW, index);
                    808:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)r >> 2);
                    809:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)g >> 2);
                    810:        outb(0x3c0 + VGA_DAC_PALETTE, (uint8_t)b >> 2);
                    811: }
                    812:
                    813: static bool
                    814: x86_genfb_setmode(struct genfb_softc *sc, int newmode)
                    815: {
                    816: #if NGENFB > 0
                    817:        static int curmode = WSDISPLAYIO_MODE_EMUL;
                    818:
                    819:        switch (newmode) {
                    820:        case WSDISPLAYIO_MODE_EMUL:
                    821:                x86_genfb_mtrr_init(sc->sc_fboffset,
                    822:                    sc->sc_height * sc->sc_stride);
                    823: #if NACPICA > 0 && defined(VGA_POST)
                    824:                if (curmode != newmode) {
                    825:                        if (vga_posth != NULL && acpi_md_vesa_modenum != 0) {
                    826:                                vga_post_set_vbe(vga_posth,
                    827:                                    acpi_md_vesa_modenum);
                    828:                        }
                    829:                }
                    830: #endif
                    831:                break;
                    832:        }
                    833:
                    834:        curmode = newmode;
                    835: #endif
                    836:        return true;
                    837: }
                    838:
                    839: static bool
                    840: x86_genfb_suspend(device_t dev, const pmf_qual_t *qual)
                    841: {
                    842:        return true;
                    843: }
                    844:
                    845: static bool
                    846: x86_genfb_resume(device_t dev, const pmf_qual_t *qual)
                    847: {
                    848: #if NGENFB > 0
                    849:        struct pci_genfb_softc *psc = device_private(dev);
                    850:
                    851: #if NACPICA > 0 && defined(VGA_POST)
                    852:        if (vga_posth != NULL && acpi_md_vbios_reset == 2) {
                    853:                vga_post_call(vga_posth);
                    854:                if (acpi_md_vesa_modenum != 0)
                    855:                        vga_post_set_vbe(vga_posth, acpi_md_vesa_modenum);
                    856:        }
                    857: #endif
                    858:        genfb_restore_palette(&psc->sc_gen);
                    859: #endif
                    860:
                    861:        return true;
                    862: }
                    863:
                    864: device_t
                    865: device_pci_register(device_t dev, void *aux)
                    866: {
                    867:        static bool found_console = false;
                    868:
                    869:        device_pci_props_register(dev, aux);
                    870:
                    871:        /*
                    872:         * Handle network interfaces here, the attachment information is
                    873:         * not available driver-independently later.
                    874:         *
                    875:         * For disks, there is nothing useful available at attach time.
                    876:         */
                    877:        if (device_class(dev) == DV_IFNET) {
                    878:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
                    879:                if (bin == NULL)
                    880:                        return NULL;
                    881:
                    882:                /*
                    883:                 * We don't check the driver name against the device name
                    884:                 * passed by the boot ROM.  The ROM should stay usable if
                    885:                 * the driver becomes obsolete.  The physical attachment
                    886:                 * information (checked below) must be sufficient to
1.53.4.3! mrg       887:                 * idenfity the device.
1.52      dyoung    888:                 */
                    889:                if (bin->bus == BI_BUS_PCI &&
                    890:                    device_is_a(device_parent(dev), "pci")) {
                    891:                        struct pci_attach_args *paa = aux;
                    892:                        int b, d, f;
                    893:
                    894:                        /*
                    895:                         * Calculate BIOS representation of:
                    896:                         *
                    897:                         *      <bus,device,function>
                    898:                         *
                    899:                         * and compare.
                    900:                         */
                    901:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
                    902:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
                    903:                                return dev;
                    904:                }
                    905:        }
                    906:        if (device_parent(dev) && device_is_a(device_parent(dev), "pci") &&
                    907:            found_console == false) {
                    908:                struct btinfo_framebuffer *fbinfo;
                    909:                struct pci_attach_args *pa = aux;
                    910:                prop_dictionary_t dict;
                    911:
                    912:                if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) {
                    913: #if NWSDISPLAY > 0 && NGENFB > 0
                    914:                        extern struct vcons_screen x86_genfb_console_screen;
                    915:                        struct rasops_info *ri;
                    916:
                    917:                        ri = &x86_genfb_console_screen.scr_ri;
                    918: #endif
                    919:
                    920:                        fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
                    921:                        dict = device_properties(dev);
                    922:                        /*
                    923:                         * framebuffer drivers other than genfb can work
                    924:                         * without the address property
                    925:                         */
                    926:                        if (fbinfo != NULL) {
                    927:                                if (fbinfo->physaddr != 0) {
                    928:                                prop_dictionary_set_uint32(dict, "width",
                    929:                                    fbinfo->width);
                    930:                                prop_dictionary_set_uint32(dict, "height",
                    931:                                    fbinfo->height);
                    932:                                prop_dictionary_set_uint8(dict, "depth",
                    933:                                    fbinfo->depth);
                    934:                                prop_dictionary_set_uint16(dict, "linebytes",
                    935:                                    fbinfo->stride);
                    936:
                    937:                                prop_dictionary_set_uint64(dict, "address",
                    938:                                    fbinfo->physaddr);
                    939: #if NWSDISPLAY > 0 && NGENFB > 0
                    940:                                if (ri->ri_bits != NULL) {
                    941:                                        prop_dictionary_set_uint64(dict,
                    942:                                            "virtual_address",
                    943:                                            (vaddr_t)ri->ri_bits);
                    944:                                }
                    945: #endif
                    946:                                }
                    947: #if notyet
                    948:                                prop_dictionary_set_bool(dict, "splash",
                    949:                                    fbinfo->flags & BI_FB_SPLASH ?
                    950:                                     true : false);
                    951: #endif
                    952:                                if (fbinfo->depth == 8) {
                    953:                                        gfb_cb.gcc_cookie = NULL;
1.53.4.3! mrg       954:                                        gfb_cb.gcc_set_mapreg =
1.52      dyoung    955:                                            x86_genfb_set_mapreg;
                    956:                                        prop_dictionary_set_uint64(dict,
                    957:                                            "cmap_callback",
                    958:                                            (uint64_t)(uintptr_t)&gfb_cb);
                    959:                                }
                    960:                                if (fbinfo->physaddr != 0) {
                    961:                                        mode_cb.gmc_setmode = x86_genfb_setmode;
                    962:                                        prop_dictionary_set_uint64(dict,
                    963:                                            "mode_callback",
                    964:                                            (uint64_t)(uintptr_t)&mode_cb);
                    965:                                }
                    966:
                    967: #if NWSDISPLAY > 0 && NGENFB > 0
                    968:                                if (device_is_a(dev, "genfb")) {
                    969:                                        x86_genfb_set_console_dev(dev);
                    970: #ifdef DDB
                    971:                                        db_trap_callback =
                    972:                                            x86_genfb_ddb_trap_callback;
                    973: #endif
                    974:                                }
                    975: #endif
                    976:                        }
                    977:                        prop_dictionary_set_bool(dict, "is_console", true);
                    978:                        prop_dictionary_set_bool(dict, "clear-screen", false);
                    979: #if NWSDISPLAY > 0 && NGENFB > 0
                    980:                        prop_dictionary_set_uint16(dict, "cursor-row",
                    981:                            x86_genfb_console_screen.scr_ri.ri_crow);
                    982: #endif
                    983: #if notyet
                    984:                        prop_dictionary_set_bool(dict, "splash",
                    985:                            fbinfo->flags & BI_FB_SPLASH ? true : false);
                    986: #endif
                    987:                        pmf_cb.gpc_suspend = x86_genfb_suspend;
                    988:                        pmf_cb.gpc_resume = x86_genfb_resume;
                    989:                        prop_dictionary_set_uint64(dict,
                    990:                            "pmf_callback", (uint64_t)(uintptr_t)&pmf_cb);
                    991: #ifdef VGA_POST
                    992:                        vga_posth = vga_post_init(pa->pa_bus, pa->pa_device,
                    993:                            pa->pa_function);
                    994: #endif
                    995:                        found_console = true;
                    996:                        return NULL;
                    997:                }
                    998:        }
                    999:        return NULL;
                   1000: }

CVSweb <webmaster@jp.NetBSD.org>