[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.76

1.76    ! nonaka      1: /*     $NetBSD: pci_machdep.c,v 1.75 2016/08/25 11:06:50 knakahara 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.55      jakllsch   72:  * as defined in section 3.6.4.1, `Generating Configuration Cycles'.
1.1       fvdl       73:  */
                     74:
                     75: #include <sys/cdefs.h>
1.76    ! nonaka     76: __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.75 2016/08/25 11:06:50 knakahara 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.64      msaitoh   113: #include "opt_puc.h"
1.52      dyoung    114: #include "opt_vga.h"
                    115: #include "pci.h"
                    116: #include "wsdisplay.h"
1.58      soren     117: #include "com.h"
1.52      dyoung    118:
                    119: #ifdef DDB
                    120: #include <machine/db_machdep.h>
                    121: #include <ddb/db_sym.h>
                    122: #include <ddb/db_extern.h>
                    123: #endif
                    124:
                    125: #ifdef VGA_POST
                    126: #include <x86/vga_post.h>
                    127: #endif
                    128:
1.70      knakahar  129: #include <x86/cpuvar.h>
                    130:
1.52      dyoung    131: #include <machine/autoconf.h>
                    132: #include <machine/bootinfo.h>
1.14      bouyer    133:
                    134: #ifdef MPBIOS
                    135: #include <machine/mpbiosvar.h>
                    136: #endif
                    137:
1.37      jmcneill  138: #if NACPICA > 0
1.14      bouyer    139: #include <machine/mpacpi.h>
1.71      msaitoh   140: #if !defined(NO_PCI_EXTENDED_CONFIG)
                    141: #include <dev/acpi/acpivar.h>
                    142: #include <dev/acpi/acpi_mcfg.h>
                    143: #endif
1.14      bouyer    144: #endif
                    145:
1.16      christos  146: #include <machine/mpconfig.h>
                    147:
1.58      soren     148: #if NCOM > 0
                    149: #include <dev/pci/puccn.h>
                    150: #endif
                    151:
1.1       fvdl      152: #include "opt_pci_conf_mode.h"
                    153:
1.38      dyoung    154: #ifdef PCI_CONF_MODE
                    155: #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2)
                    156: static int pci_mode = PCI_CONF_MODE;
                    157: #else
                    158: #error Invalid PCI configuration mode.
                    159: #endif
                    160: #else
                    161: static int pci_mode = -1;
                    162: #endif
1.1       fvdl      163:
1.42      dyoung    164: struct pci_conf_lock {
                    165:        uint32_t cl_cpuno;      /* 0: unlocked
                    166:                                 * 1 + n: locked by CPU n (0 <= n)
                    167:                                 */
                    168:        uint32_t cl_sel;        /* the address that's being read. */
                    169: };
                    170:
                    171: static void pci_conf_unlock(struct pci_conf_lock *);
                    172: static uint32_t pci_conf_selector(pcitag_t, int);
                    173: static unsigned int pci_conf_port(pcitag_t, int);
                    174: static void pci_conf_select(uint32_t);
                    175: static void pci_conf_lock(struct pci_conf_lock *, uint32_t);
1.11      sekiya    176: static void pci_bridge_hook(pci_chipset_tag_t, pcitag_t, void *);
                    177: struct pci_bridge_hook_arg {
1.55      jakllsch  178:        void (*func)(pci_chipset_tag_t, pcitag_t, void *);
                    179:        void *arg;
                    180: };
1.11      sekiya    181:
1.1       fvdl      182: #define        PCI_MODE1_ENABLE        0x80000000UL
                    183: #define        PCI_MODE1_ADDRESS_REG   0x0cf8
                    184: #define        PCI_MODE1_DATA_REG      0x0cfc
                    185:
                    186: #define        PCI_MODE2_ENABLE_REG    0x0cf8
                    187: #define        PCI_MODE2_FORWARD_REG   0x0cfa
                    188:
1.56      jakllsch  189: #define _tag(b, d, f) \
                    190:        {.mode1 = PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8)}
1.1       fvdl      191: #define _qe(bus, dev, fcn, vend, prod) \
1.56      jakllsch  192:        {_tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
                    193: const struct {
                    194:        pcitag_t tag;
1.1       fvdl      195:        pcireg_t id;
                    196: } pcim1_quirk_tbl[] = {
1.56      jakllsch  197:        _qe(0, 0, 0, PCI_VENDOR_INVALID, 0x0000), /* patchable */
1.1       fvdl      198:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1),
                    199:        /* XXX Triflex2 not tested */
                    200:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2),
                    201:        _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4),
                    202:        /* Triton needed for Connectix Virtual PC */
                    203:        _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
                    204:        /* Connectix Virtual PC 5 has a 440BX */
                    205:        _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
1.15      soren     206:        /* Parallels Desktop for Mac */
                    207:        _qe(0, 2, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_VIDEO),
                    208:        _qe(0, 3, 0, PCI_VENDOR_PARALLELS, PCI_PRODUCT_PARALLELS_TOOLS),
1.36      drochner  209:        /* SIS 740 */
                    210:        _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_740),
1.12      christos  211:        /* SIS 741 */
                    212:        _qe(0, 0, 0, PCI_VENDOR_SIS, PCI_PRODUCT_SIS_741),
1.54      tsutsui   213:        /* VIA Technologies VX900 */
1.56      jakllsch  214:        _qe(0, 0, 0, PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VX900_HB)
1.1       fvdl      215: };
1.56      jakllsch  216: #undef _tag
1.1       fvdl      217: #undef _qe
                    218:
1.70      knakahar  219: /* arch/xen does not support MSI/MSI-X yet. */
                    220: #ifdef __HAVE_PCI_MSI_MSIX
                    221: #define PCI_QUIRK_DISABLE_MSI  1 /* Neigher MSI nor MSI-X work */
                    222: #define PCI_QUIRK_DISABLE_MSIX 2 /* MSI-X does not work */
                    223: #define PCI_QUIRK_ENABLE_MSI_VM        3 /* Older chipset in VM where MSI and MSI-X works */
                    224:
                    225: #define _dme(vend, prod) \
                    226:        { PCI_QUIRK_DISABLE_MSI, PCI_ID_CODE(vend, prod) }
                    227: #define _dmxe(vend, prod) \
                    228:        { PCI_QUIRK_DISABLE_MSIX, PCI_ID_CODE(vend, prod) }
                    229: #define _emve(vend, prod) \
                    230:        { PCI_QUIRK_ENABLE_MSI_VM, PCI_ID_CODE(vend, prod) }
                    231: const struct {
                    232:        int type;
                    233:        pcireg_t id;
                    234: } pci_msi_quirk_tbl[] = {
                    235:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_PCMC),
                    236:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX),
                    237:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437MX),
                    238:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437VX),
                    239:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82439HX),
                    240:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82439TX),
                    241:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443GX),
                    242:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443GX_AGP),
                    243:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82440MX),
                    244:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82441FX),
                    245:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX),
                    246:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_AGP),
                    247:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP),
                    248:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443GX_NOAGP),
                    249:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443LX),
                    250:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443LX_AGP),
                    251:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810_MCH),
                    252:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82810E_MCH),
                    253:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82815_FULL_HUB),
                    254:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82820_MCH),
                    255:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82830MP_IO_1),
                    256:        _dme(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82840_HB),
                    257:        _dme(PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE_PCHB),
                    258:        _dme(PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_NFORCE2_PCHB),
                    259:        _dme(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_SC751_SC),
                    260:        _dme(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_SC761_SC),
                    261:        _dme(PCI_VENDOR_AMD, PCI_PRODUCT_AMD_SC762_NB),
                    262:
                    263:        _emve(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82441FX), /* QEMU */
                    264:        _emve(PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX), /* VMWare */
                    265: };
                    266: #undef _dme
                    267: #undef _dmxe
                    268: #undef _emve
                    269: #endif /* __HAVE_PCI_MSI_MSIX */
                    270:
1.1       fvdl      271: /*
                    272:  * PCI doesn't have any special needs; just use the generic versions
                    273:  * of these functions.
                    274:  */
                    275: struct x86_bus_dma_tag pci_bus_dma_tag = {
1.46      christos  276:        ._tag_needs_free        = 0,
1.3       fvdl      277: #if defined(_LP64) || defined(PAE)
1.46      christos  278:        ._bounce_thresh         = PCI32_DMA_BOUNCE_THRESHOLD,
                    279:        ._bounce_alloc_lo       = ISA_DMA_BOUNCE_THRESHOLD,
                    280:        ._bounce_alloc_hi       = PCI32_DMA_BOUNCE_THRESHOLD,
1.3       fvdl      281: #else
1.46      christos  282:        ._bounce_thresh         = 0,
                    283:        ._bounce_alloc_lo       = 0,
                    284:        ._bounce_alloc_hi       = 0,
                    285: #endif
                    286:        ._may_bounce            = NULL,
1.1       fvdl      287: };
1.5       fvdl      288:
                    289: #ifdef _LP64
                    290: struct x86_bus_dma_tag pci_bus_dma64_tag = {
1.46      christos  291:        ._tag_needs_free        = 0,
                    292:        ._bounce_thresh         = 0,
                    293:        ._bounce_alloc_lo       = 0,
                    294:        ._bounce_alloc_hi       = 0,
                    295:        ._may_bounce            = NULL,
1.5       fvdl      296: };
                    297: #endif
1.1       fvdl      298:
1.42      dyoung    299: static struct pci_conf_lock cl0 = {
                    300:          .cl_cpuno = 0UL
                    301:        , .cl_sel = 0UL
                    302: };
                    303:
                    304: static struct pci_conf_lock * const cl = &cl0;
                    305:
1.52      dyoung    306: #if NGENFB > 0 && NACPICA > 0 && defined(VGA_POST)
                    307: extern int acpi_md_vbios_reset;
                    308: extern int acpi_md_vesa_modenum;
                    309: #endif
                    310:
                    311: static struct genfb_colormap_callback gfb_cb;
                    312: static struct genfb_pmf_callback pmf_cb;
                    313: static struct genfb_mode_callback mode_cb;
                    314: #ifdef VGA_POST
                    315: static struct vga_post *vga_posth = NULL;
                    316: #endif
                    317:
1.42      dyoung    318: static void
                    319: pci_conf_lock(struct pci_conf_lock *ocl, uint32_t sel)
                    320: {
                    321:        uint32_t cpuno;
                    322:
                    323:        KASSERT(sel != 0);
                    324:
                    325:        kpreempt_disable();
                    326:        cpuno = cpu_number() + 1;
                    327:        /* If the kernel enters pci_conf_lock() through an interrupt
                    328:         * handler, then the CPU may already hold the lock.
                    329:         *
                    330:         * If the CPU does not already hold the lock, spin until
                    331:         * we can acquire it.
                    332:         */
                    333:        if (cpuno == cl->cl_cpuno) {
                    334:                ocl->cl_cpuno = cpuno;
                    335:        } else {
1.44      dyoung    336:                u_int spins;
                    337:
1.42      dyoung    338:                ocl->cl_cpuno = 0;
1.44      dyoung    339:
                    340:                spins = SPINLOCK_BACKOFF_MIN;
                    341:                while (atomic_cas_32(&cl->cl_cpuno, 0, cpuno) != 0) {
                    342:                        SPINLOCK_BACKOFF(spins);
                    343: #ifdef LOCKDEBUG
                    344:                        if (SPINLOCK_SPINOUT(spins)) {
                    345:                                panic("%s: cpu %" PRId32
                    346:                                    " spun out waiting for cpu %" PRId32,
                    347:                                    __func__, cpuno, cl->cl_cpuno);
                    348:                        }
                    349: #endif /* LOCKDEBUG */
                    350:                }
1.42      dyoung    351:        }
                    352:
                    353:        /* Only one CPU can be here, so an interlocked atomic_swap(3)
                    354:         * is not necessary.
                    355:         *
                    356:         * Evaluating atomic_cas_32_ni()'s argument, cl->cl_sel,
                    357:         * and applying atomic_cas_32_ni() is not an atomic operation,
                    358:         * however, any interrupt that, in the middle of the
                    359:         * operation, modifies cl->cl_sel, will also restore
                    360:         * cl->cl_sel.  So cl->cl_sel will have the same value when
                    361:         * we apply atomic_cas_32_ni() as when we evaluated it,
                    362:         * before.
                    363:         */
                    364:        ocl->cl_sel = atomic_cas_32_ni(&cl->cl_sel, cl->cl_sel, sel);
                    365:        pci_conf_select(sel);
                    366: }
                    367:
                    368: static void
                    369: pci_conf_unlock(struct pci_conf_lock *ocl)
                    370: {
1.62      christos  371:        atomic_cas_32_ni(&cl->cl_sel, cl->cl_sel, ocl->cl_sel);
1.42      dyoung    372:        pci_conf_select(ocl->cl_sel);
                    373:        if (ocl->cl_cpuno != cl->cl_cpuno)
                    374:                atomic_cas_32(&cl->cl_cpuno, cl->cl_cpuno, ocl->cl_cpuno);
                    375:        kpreempt_enable();
                    376: }
                    377:
1.39      dyoung    378: static uint32_t
                    379: pci_conf_selector(pcitag_t tag, int reg)
                    380: {
                    381:        static const pcitag_t mode2_mask = {
                    382:                .mode2 = {
                    383:                          .enable = 0xff
                    384:                        , .forward = 0xff
                    385:                }
                    386:        };
                    387:
                    388:        switch (pci_mode) {
                    389:        case 1:
                    390:                return tag.mode1 | reg;
                    391:        case 2:
                    392:                return tag.mode1 & mode2_mask.mode1;
                    393:        default:
1.69      christos  394:                panic("%s: mode %d not configured", __func__, pci_mode);
1.39      dyoung    395:        }
                    396: }
                    397:
                    398: static unsigned int
                    399: pci_conf_port(pcitag_t tag, int reg)
                    400: {
                    401:        switch (pci_mode) {
                    402:        case 1:
                    403:                return PCI_MODE1_DATA_REG;
                    404:        case 2:
                    405:                return tag.mode2.port | reg;
                    406:        default:
1.69      christos  407:                panic("%s: mode %d not configured", __func__, pci_mode);
1.39      dyoung    408:        }
                    409: }
                    410:
                    411: static void
1.42      dyoung    412: pci_conf_select(uint32_t sel)
1.39      dyoung    413: {
                    414:        pcitag_t tag;
                    415:
                    416:        switch (pci_mode) {
                    417:        case 1:
1.42      dyoung    418:                outl(PCI_MODE1_ADDRESS_REG, sel);
1.39      dyoung    419:                return;
                    420:        case 2:
1.42      dyoung    421:                tag.mode1 = sel;
1.39      dyoung    422:                outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
                    423:                if (tag.mode2.enable != 0)
                    424:                        outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
                    425:                return;
                    426:        default:
1.69      christos  427:                panic("%s: mode %d not configured", __func__, pci_mode);
1.39      dyoung    428:        }
                    429: }
                    430:
1.70      knakahar  431: #ifdef __HAVE_PCI_MSI_MSIX
                    432: static int
                    433: pci_has_msi_quirk(pcireg_t id, int type)
                    434: {
                    435:        int i;
                    436:
                    437:        for (i = 0; i < __arraycount(pci_msi_quirk_tbl); i++) {
                    438:                if (id == pci_msi_quirk_tbl[i].id &&
                    439:                    type == pci_msi_quirk_tbl[i].type)
                    440:                        return 1;
                    441:        }
                    442:
                    443:        return 0;
                    444: }
                    445: #endif
                    446:
1.1       fvdl      447: void
1.32      dyoung    448: pci_attach_hook(device_t parent, device_t self, struct pcibus_attach_args *pba)
1.1       fvdl      449: {
1.70      knakahar  450: #ifdef __HAVE_PCI_MSI_MSIX
                    451:        pci_chipset_tag_t pc = pba->pba_pc;
                    452:        pcitag_t tag;
                    453:        pcireg_t id, class;
                    454: #endif
1.1       fvdl      455:
                    456:        if (pba->pba_bus == 0)
1.26      mjf       457:                aprint_normal(": configuration mode %d", pci_mode);
1.4       fvdl      458: #ifdef MPBIOS
                    459:        mpbios_pci_attach_hook(parent, self, pba);
                    460: #endif
1.37      jmcneill  461: #if NACPICA > 0
1.4       fvdl      462:        mpacpi_pci_attach_hook(parent, self, pba);
                    463: #endif
1.73      jakllsch  464: #if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
                    465:        acpimcfg_map_bus(self, pba->pba_pc, pba->pba_bus);
                    466: #endif
1.70      knakahar  467:
                    468: #ifdef __HAVE_PCI_MSI_MSIX
                    469:        /*
                    470:         * In order to decide whether the system supports MSI we look
                    471:         * at the host bridge, which should be device 0 function 0 on
                    472:         * bus 0.  It is better to not enable MSI on systems that
                    473:         * support it than the other way around, so be conservative
                    474:         * here.  So we don't enable MSI if we don't find a host
                    475:         * bridge there.  We also deliberately don't enable MSI on
                    476:         * chipsets from low-end manifacturers like VIA and SiS.
                    477:         */
                    478:        tag = pci_make_tag(pc, 0, 0, 0);
                    479:        id = pci_conf_read(pc, tag, PCI_ID_REG);
                    480:        class = pci_conf_read(pc, tag, PCI_CLASS_REG);
                    481:
                    482:        if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
                    483:            PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST)
                    484:                return;
                    485:
                    486:        if (pci_has_msi_quirk(id, PCI_QUIRK_DISABLE_MSI)) {
                    487:                pba->pba_flags &= ~PCI_FLAGS_MSI_OKAY;
                    488:                pba->pba_flags &= ~PCI_FLAGS_MSIX_OKAY;
1.76    ! nonaka    489:                aprint_verbose("\n");
        !           490:                aprint_verbose_dev(self,
        !           491:                    "This pci host supports neither MSI nor MSI-X.");
1.70      knakahar  492:        } else if (pci_has_msi_quirk(id, PCI_QUIRK_DISABLE_MSIX)) {
                    493:                pba->pba_flags |= PCI_FLAGS_MSI_OKAY;
                    494:                pba->pba_flags &= ~PCI_FLAGS_MSIX_OKAY;
1.76    ! nonaka    495:                aprint_verbose("\n");
        !           496:                aprint_verbose_dev(self,
        !           497:                    "This pci host does not support MSI-X.");
1.70      knakahar  498:        } else {
                    499:                pba->pba_flags |= PCI_FLAGS_MSI_OKAY;
                    500:                pba->pba_flags |= PCI_FLAGS_MSIX_OKAY;
                    501:        }
                    502:
                    503:        /* VMware and KVM use old chipset, but they can use MSI/MSI-X */
                    504:        if (cpu_feature[1] & CPUID2_RAZ) {
                    505:                if (pci_has_msi_quirk(id, PCI_QUIRK_ENABLE_MSI_VM)) {
                    506:                        pba->pba_flags |= PCI_FLAGS_MSI_OKAY;
                    507:                        pba->pba_flags |= PCI_FLAGS_MSIX_OKAY;
                    508:                }
                    509:        }
                    510:
                    511:        /*
                    512:         * Don't enable MSI on a HyperTransport bus.  In order to
                    513:         * determine that bus 0 is a HyperTransport bus, we look at
                    514:         * device 24 function 0, which is the HyperTransport
                    515:         * host/primary interface integrated on most 64-bit AMD CPUs.
                    516:         * If that device has a HyperTransport capability, bus 0 must
                    517:         * be a HyperTransport bus and we disable MSI.
                    518:         */
1.74      jakllsch  519:        if (24 < pci_bus_maxdevs(pc, 0)) {
                    520:                tag = pci_make_tag(pc, 0, 24, 0);
                    521:                if (pci_get_capability(pc, tag, PCI_CAP_LDT, NULL, NULL)) {
                    522:                        pba->pba_flags &= ~PCI_FLAGS_MSI_OKAY;
                    523:                        pba->pba_flags &= ~PCI_FLAGS_MSIX_OKAY;
                    524:                }
1.70      knakahar  525:        }
                    526: #endif /* __HAVE_PCI_MSI_MSIX */
1.1       fvdl      527: }
                    528:
                    529: int
1.18      christos  530: pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
1.1       fvdl      531: {
                    532:        /*
                    533:         * Bus number is irrelevant.  If Configuration Mechanism 2 is in
                    534:         * use, can only have devices 0-15 on any bus.  If Configuration
                    535:         * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal'
                    536:         * range).
                    537:         */
                    538:        if (pci_mode == 2)
                    539:                return (16);
                    540:        else
                    541:                return (32);
                    542: }
                    543:
                    544: pcitag_t
1.18      christos  545: pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
1.1       fvdl      546: {
1.47      dyoung    547:        pci_chipset_tag_t ipc;
1.1       fvdl      548:        pcitag_t tag;
                    549:
1.47      dyoung    550:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    551:                if ((ipc->pc_present & PCI_OVERRIDE_MAKE_TAG) == 0)
                    552:                        continue;
                    553:                return (*ipc->pc_ov->ov_make_tag)(ipc->pc_ctx,
                    554:                    pc, bus, device, function);
1.41      dyoung    555:        }
1.40      dyoung    556:
1.1       fvdl      557:        switch (pci_mode) {
                    558:        case 1:
1.38      dyoung    559:                if (bus >= 256 || device >= 32 || function >= 8)
1.69      christos  560:                        panic("%s: bad request(%d, %d, %d)", __func__,
                    561:                            bus, device, function);
1.38      dyoung    562:
                    563:                tag.mode1 = PCI_MODE1_ENABLE |
                    564:                            (bus << 16) | (device << 11) | (function << 8);
                    565:                return tag;
1.1       fvdl      566:        case 2:
1.38      dyoung    567:                if (bus >= 256 || device >= 16 || function >= 8)
1.69      christos  568:                        panic("%s: bad request(%d, %d, %d)", __func__,
                    569:                            bus, device, function);
1.38      dyoung    570:
                    571:                tag.mode2.port = 0xc000 | (device << 8);
                    572:                tag.mode2.enable = 0xf0 | (function << 1);
                    573:                tag.mode2.forward = bus;
                    574:                return tag;
1.1       fvdl      575:        default:
1.69      christos  576:                panic("%s: mode %d not configured", __func__, pci_mode);
1.1       fvdl      577:        }
                    578: }
                    579:
                    580: void
1.18      christos  581: pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag,
1.17      christos  582:     int *bp, int *dp, int *fp)
1.1       fvdl      583: {
1.47      dyoung    584:        pci_chipset_tag_t ipc;
1.1       fvdl      585:
1.47      dyoung    586:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    587:                if ((ipc->pc_present & PCI_OVERRIDE_DECOMPOSE_TAG) == 0)
                    588:                        continue;
                    589:                (*ipc->pc_ov->ov_decompose_tag)(ipc->pc_ctx,
                    590:                    pc, tag, bp, dp, fp);
                    591:                return;
1.40      dyoung    592:        }
                    593:
1.1       fvdl      594:        switch (pci_mode) {
                    595:        case 1:
1.38      dyoung    596:                if (bp != NULL)
                    597:                        *bp = (tag.mode1 >> 16) & 0xff;
                    598:                if (dp != NULL)
                    599:                        *dp = (tag.mode1 >> 11) & 0x1f;
                    600:                if (fp != NULL)
                    601:                        *fp = (tag.mode1 >> 8) & 0x7;
                    602:                return;
1.1       fvdl      603:        case 2:
1.38      dyoung    604:                if (bp != NULL)
                    605:                        *bp = tag.mode2.forward & 0xff;
                    606:                if (dp != NULL)
                    607:                        *dp = (tag.mode2.port >> 8) & 0xf;
                    608:                if (fp != NULL)
                    609:                        *fp = (tag.mode2.enable >> 1) & 0x7;
                    610:                return;
1.1       fvdl      611:        default:
1.69      christos  612:                panic("%s: mode %d not configured", __func__, pci_mode);
1.1       fvdl      613:        }
                    614: }
                    615:
                    616: pcireg_t
1.43      dyoung    617: pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
1.1       fvdl      618: {
1.47      dyoung    619:        pci_chipset_tag_t ipc;
1.1       fvdl      620:        pcireg_t data;
1.42      dyoung    621:        struct pci_conf_lock ocl;
1.71      msaitoh   622:        int dev;
1.1       fvdl      623:
1.31      dyoung    624:        KASSERT((reg & 0x3) == 0);
1.40      dyoung    625:
1.47      dyoung    626:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    627:                if ((ipc->pc_present & PCI_OVERRIDE_CONF_READ) == 0)
                    628:                        continue;
                    629:                return (*ipc->pc_ov->ov_conf_read)(ipc->pc_ctx, pc, tag, reg);
1.41      dyoung    630:        }
1.40      dyoung    631:
1.71      msaitoh   632:        pci_decompose_tag(pc, tag, NULL, &dev, NULL);
                    633:        if (__predict_false(pci_mode == 2 && dev >= 16))
                    634:                return (pcireg_t) -1;
                    635:
                    636:        if (reg < 0)
                    637:                return (pcireg_t) -1;
                    638:        if (reg >= PCI_CONF_SIZE) {
                    639: #if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
                    640:                if (reg >= PCI_EXTCONF_SIZE)
                    641:                        return (pcireg_t) -1;
                    642:                acpimcfg_conf_read(pc, tag, reg, &data);
                    643:                return data;
                    644: #else
                    645:                return (pcireg_t) -1;
                    646: #endif
                    647:        }
                    648:
1.42      dyoung    649:        pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
1.39      dyoung    650:        data = inl(pci_conf_port(tag, reg));
1.42      dyoung    651:        pci_conf_unlock(&ocl);
1.39      dyoung    652:        return data;
1.1       fvdl      653: }
                    654:
                    655: void
1.43      dyoung    656: pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
1.1       fvdl      657: {
1.47      dyoung    658:        pci_chipset_tag_t ipc;
1.42      dyoung    659:        struct pci_conf_lock ocl;
1.71      msaitoh   660:        int dev;
1.1       fvdl      661:
1.31      dyoung    662:        KASSERT((reg & 0x3) == 0);
1.40      dyoung    663:
1.47      dyoung    664:        for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
                    665:                if ((ipc->pc_present & PCI_OVERRIDE_CONF_WRITE) == 0)
                    666:                        continue;
                    667:                (*ipc->pc_ov->ov_conf_write)(ipc->pc_ctx, pc, tag, reg,
                    668:                    data);
                    669:                return;
1.40      dyoung    670:        }
                    671:
1.71      msaitoh   672:        pci_decompose_tag(pc, tag, NULL, &dev, NULL);
                    673:        if (__predict_false(pci_mode == 2 && dev >= 16)) {
                    674:                return;
                    675:        }
                    676:
                    677:        if (reg < 0)
                    678:                return;
                    679:        if (reg >= PCI_CONF_SIZE) {
                    680: #if NACPICA > 0 && !defined(NO_PCI_EXTENDED_CONFIG)
                    681:                if (reg >= PCI_EXTCONF_SIZE)
                    682:                        return;
                    683:                acpimcfg_conf_write(pc, tag, reg, data);
                    684: #endif
                    685:                return;
                    686:        }
                    687:
1.42      dyoung    688:        pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
1.39      dyoung    689:        outl(pci_conf_port(tag, reg), data);
1.42      dyoung    690:        pci_conf_unlock(&ocl);
1.38      dyoung    691: }
1.1       fvdl      692:
1.38      dyoung    693: void
                    694: pci_mode_set(int mode)
                    695: {
                    696:        KASSERT(pci_mode == -1 || pci_mode == mode);
1.1       fvdl      697:
1.38      dyoung    698:        pci_mode = mode;
1.1       fvdl      699: }
                    700:
                    701: int
1.33      cegger    702: pci_mode_detect(void)
1.1       fvdl      703: {
1.33      cegger    704:        uint32_t sav, val;
1.1       fvdl      705:        int i;
                    706:        pcireg_t idreg;
1.61      gson      707:        extern char cpu_brand_string[];
1.1       fvdl      708:
                    709:        if (pci_mode != -1)
                    710:                return pci_mode;
                    711:
                    712:        /*
                    713:         * We try to divine which configuration mode the host bridge wants.
                    714:         */
                    715:
                    716:        sav = inl(PCI_MODE1_ADDRESS_REG);
                    717:
                    718:        pci_mode = 1; /* assume this for now */
                    719:        /*
                    720:         * catch some known buggy implementations of mode 1
                    721:         */
1.27      dyoung    722:        for (i = 0; i < __arraycount(pcim1_quirk_tbl); i++) {
1.1       fvdl      723:                pcitag_t t;
                    724:
1.56      jakllsch  725:                if (PCI_VENDOR(pcim1_quirk_tbl[i].id) == PCI_VENDOR_INVALID)
                    726:                        continue;
                    727:                t.mode1 = pcim1_quirk_tbl[i].tag.mode1;
                    728:                idreg = pci_conf_read(NULL, t, PCI_ID_REG); /* needs "pci_mode" */
1.1       fvdl      729:                if (idreg == pcim1_quirk_tbl[i].id) {
                    730: #ifdef DEBUG
1.67      christos  731:                        printf("%s: known mode 1 PCI chipset (%08x)\n",
                    732:                            __func__, idreg);
1.1       fvdl      733: #endif
                    734:                        return (pci_mode);
                    735:                }
                    736:        }
1.66      sborrill  737:
1.67      christos  738:        const char *reason, *system_vendor, *system_product;
                    739:        if (memcmp(cpu_brand_string, "QEMU", 4) == 0)
1.61      gson      740:                /* PR 45671, https://bugs.launchpad.net/qemu/+bug/897771 */
1.67      christos  741:                reason = "QEMU";
                    742:        else if ((system_vendor = pmf_get_platform("system-vendor")) != NULL &&
                    743:            strcmp(system_vendor, "Xen") == 0 &&
                    744:            (system_product = pmf_get_platform("system-product")) != NULL &&
                    745:            strcmp(system_product, "HVM domU") == 0)
                    746:                reason = "Xen";
                    747:        else
                    748:                reason = NULL;
                    749:
                    750:        if (reason) {
1.61      gson      751: #ifdef DEBUG
1.67      christos  752:                printf("%s: forcing PCI mode 1 for %s\n", __func__, reason);
1.61      gson      753: #endif
                    754:                return (pci_mode);
                    755:        }
1.1       fvdl      756:
                    757:        /*
                    758:         * Strong check for standard compliant mode 1:
                    759:         * 1. bit 31 ("enable") can be set
                    760:         * 2. byte/word access does not affect register
                    761:         */
                    762:        outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE);
                    763:        outb(PCI_MODE1_ADDRESS_REG + 3, 0);
                    764:        outw(PCI_MODE1_ADDRESS_REG + 2, 0);
                    765:        val = inl(PCI_MODE1_ADDRESS_REG);
                    766:        if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) {
                    767: #ifdef DEBUG
1.67      christos  768:                printf("%s: mode 1 enable failed (%x)\n", __func__, val);
1.1       fvdl      769: #endif
                    770:                goto not1;
                    771:        }
                    772:        outl(PCI_MODE1_ADDRESS_REG, 0);
                    773:        val = inl(PCI_MODE1_ADDRESS_REG);
                    774:        if ((val & 0x80fffffc) != 0)
                    775:                goto not1;
                    776:        return (pci_mode);
                    777: not1:
                    778:        outl(PCI_MODE1_ADDRESS_REG, sav);
                    779:
                    780:        /*
                    781:         * This mode 2 check is quite weak (and known to give false
                    782:         * positives on some Compaq machines).
                    783:         * However, this doesn't matter, because this is the
                    784:         * last test, and simply no PCI devices will be found if
                    785:         * this happens.
                    786:         */
                    787:        outb(PCI_MODE2_ENABLE_REG, 0);
                    788:        outb(PCI_MODE2_FORWARD_REG, 0);
                    789:        if (inb(PCI_MODE2_ENABLE_REG) != 0 ||
                    790:            inb(PCI_MODE2_FORWARD_REG) != 0)
                    791:                goto not2;
                    792:        return (pci_mode = 2);
                    793: not2:
                    794:
                    795:        return (pci_mode = 0);
                    796: }
                    797:
1.11      sekiya    798: void
                    799: pci_device_foreach(pci_chipset_tag_t pc, int maxbus,
                    800:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
                    801: {
                    802:        pci_device_foreach_min(pc, 0, maxbus, func, context);
                    803: }
                    804:
                    805: void
                    806: pci_device_foreach_min(pci_chipset_tag_t pc, int minbus, int maxbus,
                    807:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *context)
                    808: {
                    809:        const struct pci_quirkdata *qd;
                    810:        int bus, device, function, maxdevs, nfuncs;
                    811:        pcireg_t id, bhlcr;
                    812:        pcitag_t tag;
                    813:
                    814:        for (bus = minbus; bus <= maxbus; bus++) {
                    815:                maxdevs = pci_bus_maxdevs(pc, bus);
                    816:                for (device = 0; device < maxdevs; device++) {
                    817:                        tag = pci_make_tag(pc, bus, device, 0);
                    818:                        id = pci_conf_read(pc, tag, PCI_ID_REG);
                    819:
                    820:                        /* Invalid vendor ID value? */
                    821:                        if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    822:                                continue;
                    823:                        /* XXX Not invalid, but we've done this ~forever. */
                    824:                        if (PCI_VENDOR(id) == 0)
                    825:                                continue;
                    826:
                    827:                        qd = pci_lookup_quirkdata(PCI_VENDOR(id),
                    828:                                PCI_PRODUCT(id));
                    829:
                    830:                        bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG);
                    831:                        if (PCI_HDRTYPE_MULTIFN(bhlcr) ||
                    832:                             (qd != NULL &&
1.55      jakllsch  833:                             (qd->quirks & PCI_QUIRK_MULTIFUNCTION) != 0))
1.11      sekiya    834:                                nfuncs = 8;
                    835:                        else
                    836:                                nfuncs = 1;
                    837:
                    838:                        for (function = 0; function < nfuncs; function++) {
                    839:                                tag = pci_make_tag(pc, bus, device, function);
                    840:                                id = pci_conf_read(pc, tag, PCI_ID_REG);
                    841:
                    842:                                /* Invalid vendor ID value? */
                    843:                                if (PCI_VENDOR(id) == PCI_VENDOR_INVALID)
                    844:                                        continue;
                    845:                                /*
                    846:                                 * XXX Not invalid, but we've done this
                    847:                                 * ~forever.
                    848:                                 */
                    849:                                if (PCI_VENDOR(id) == 0)
                    850:                                        continue;
                    851:                                (*func)(pc, tag, context);
                    852:                        }
                    853:                }
                    854:        }
                    855: }
                    856:
                    857: void
                    858: pci_bridge_foreach(pci_chipset_tag_t pc, int minbus, int maxbus,
                    859:        void (*func)(pci_chipset_tag_t, pcitag_t, void *), void *ctx)
                    860: {
                    861:        struct pci_bridge_hook_arg bridge_hook;
                    862:
                    863:        bridge_hook.func = func;
1.55      jakllsch  864:        bridge_hook.arg = ctx;
1.11      sekiya    865:
                    866:        pci_device_foreach_min(pc, minbus, maxbus, pci_bridge_hook,
1.55      jakllsch  867:                &bridge_hook);
1.11      sekiya    868: }
                    869:
                    870: static void
                    871: pci_bridge_hook(pci_chipset_tag_t pc, pcitag_t tag, void *ctx)
                    872: {
                    873:        struct pci_bridge_hook_arg *bridge_hook = (void *)ctx;
                    874:        pcireg_t reg;
                    875:
                    876:        reg = pci_conf_read(pc, tag, PCI_CLASS_REG);
                    877:        if (PCI_CLASS(reg) == PCI_CLASS_BRIDGE &&
1.55      jakllsch  878:            (PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_PCI ||
1.11      sekiya    879:                PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_CARDBUS)) {
                    880:                (*bridge_hook->func)(pc, tag, bridge_hook->arg);
                    881:        }
                    882: }
1.43      dyoung    883:
                    884: static const void *
                    885: bit_to_function_pointer(const struct pci_overrides *ov, uint64_t bit)
                    886: {
                    887:        switch (bit) {
                    888:        case PCI_OVERRIDE_CONF_READ:
                    889:                return ov->ov_conf_read;
                    890:        case PCI_OVERRIDE_CONF_WRITE:
                    891:                return ov->ov_conf_write;
                    892:        case PCI_OVERRIDE_INTR_MAP:
                    893:                return ov->ov_intr_map;
                    894:        case PCI_OVERRIDE_INTR_STRING:
                    895:                return ov->ov_intr_string;
                    896:        case PCI_OVERRIDE_INTR_EVCNT:
                    897:                return ov->ov_intr_evcnt;
                    898:        case PCI_OVERRIDE_INTR_ESTABLISH:
                    899:                return ov->ov_intr_establish;
                    900:        case PCI_OVERRIDE_INTR_DISESTABLISH:
                    901:                return ov->ov_intr_disestablish;
                    902:        case PCI_OVERRIDE_MAKE_TAG:
                    903:                return ov->ov_make_tag;
                    904:        case PCI_OVERRIDE_DECOMPOSE_TAG:
                    905:                return ov->ov_decompose_tag;
                    906:        default:
                    907:                return NULL;
                    908:        }
                    909: }
                    910:
                    911: void
                    912: pci_chipset_tag_destroy(pci_chipset_tag_t pc)
                    913: {
                    914:        kmem_free(pc, sizeof(struct pci_chipset_tag));
                    915: }
                    916:
                    917: int
                    918: pci_chipset_tag_create(pci_chipset_tag_t opc, const uint64_t present,
                    919:     const struct pci_overrides *ov, void *ctx, pci_chipset_tag_t *pcp)
                    920: {
                    921:        uint64_t bit, bits, nbits;
                    922:        pci_chipset_tag_t pc;
                    923:        const void *fp;
                    924:
                    925:        if (ov == NULL || present == 0)
                    926:                return EINVAL;
                    927:
                    928:        pc = kmem_alloc(sizeof(struct pci_chipset_tag), KM_SLEEP);
                    929:
                    930:        if (pc == NULL)
                    931:                return ENOMEM;
                    932:
                    933:        pc->pc_super = opc;
                    934:
                    935:        for (bits = present; bits != 0; bits = nbits) {
                    936:                nbits = bits & (bits - 1);
                    937:                bit = nbits ^ bits;
                    938:                if ((fp = bit_to_function_pointer(ov, bit)) == NULL) {
1.51      dyoung    939: #ifdef DEBUG
1.43      dyoung    940:                        printf("%s: missing bit %" PRIx64 "\n", __func__, bit);
1.51      dyoung    941: #endif
1.43      dyoung    942:                        goto einval;
                    943:                }
                    944:        }
                    945:
                    946:        pc->pc_ov = ov;
                    947:        pc->pc_present = present;
                    948:        pc->pc_ctx = ctx;
                    949:
                    950:        *pcp = pc;
                    951:
                    952:        return 0;
                    953: einval:
                    954:        kmem_free(pc, sizeof(struct pci_chipset_tag));
                    955:        return EINVAL;
                    956: }
1.52      dyoung    957:
                    958: static void
                    959: x86_genfb_set_mapreg(void *opaque, int index, int r, int g, int b)
                    960: {
1.57      jakllsch  961:        outb(IO_VGA + VGA_DAC_ADDRW, index);
                    962:        outb(IO_VGA + VGA_DAC_PALETTE, (uint8_t)r >> 2);
                    963:        outb(IO_VGA + VGA_DAC_PALETTE, (uint8_t)g >> 2);
                    964:        outb(IO_VGA + VGA_DAC_PALETTE, (uint8_t)b >> 2);
1.52      dyoung    965: }
                    966:
                    967: static bool
                    968: x86_genfb_setmode(struct genfb_softc *sc, int newmode)
                    969: {
                    970: #if NGENFB > 0
1.68      christos  971: # if NACPICA > 0 && defined(VGA_POST)
1.52      dyoung    972:        static int curmode = WSDISPLAYIO_MODE_EMUL;
1.68      christos  973: # endif
1.52      dyoung    974:
                    975:        switch (newmode) {
                    976:        case WSDISPLAYIO_MODE_EMUL:
                    977:                x86_genfb_mtrr_init(sc->sc_fboffset,
                    978:                    sc->sc_height * sc->sc_stride);
1.68      christos  979: # if NACPICA > 0 && defined(VGA_POST)
1.52      dyoung    980:                if (curmode != newmode) {
                    981:                        if (vga_posth != NULL && acpi_md_vesa_modenum != 0) {
                    982:                                vga_post_set_vbe(vga_posth,
                    983:                                    acpi_md_vesa_modenum);
                    984:                        }
                    985:                }
1.68      christos  986: # endif
1.52      dyoung    987:                break;
                    988:        }
                    989:
1.68      christos  990: # if NACPICA > 0 && defined(VGA_POST)
1.52      dyoung    991:        curmode = newmode;
1.68      christos  992: # endif
1.52      dyoung    993: #endif
                    994:        return true;
                    995: }
                    996:
                    997: static bool
                    998: x86_genfb_suspend(device_t dev, const pmf_qual_t *qual)
                    999: {
                   1000:        return true;
                   1001: }
                   1002:
                   1003: static bool
                   1004: x86_genfb_resume(device_t dev, const pmf_qual_t *qual)
                   1005: {
                   1006: #if NGENFB > 0
                   1007:        struct pci_genfb_softc *psc = device_private(dev);
                   1008:
                   1009: #if NACPICA > 0 && defined(VGA_POST)
                   1010:        if (vga_posth != NULL && acpi_md_vbios_reset == 2) {
                   1011:                vga_post_call(vga_posth);
                   1012:                if (acpi_md_vesa_modenum != 0)
                   1013:                        vga_post_set_vbe(vga_posth, acpi_md_vesa_modenum);
                   1014:        }
                   1015: #endif
                   1016:        genfb_restore_palette(&psc->sc_gen);
                   1017: #endif
                   1018:
                   1019:        return true;
                   1020: }
                   1021:
                   1022: device_t
                   1023: device_pci_register(device_t dev, void *aux)
                   1024: {
                   1025:        static bool found_console = false;
                   1026:
                   1027:        device_pci_props_register(dev, aux);
                   1028:
                   1029:        /*
                   1030:         * Handle network interfaces here, the attachment information is
                   1031:         * not available driver-independently later.
                   1032:         *
                   1033:         * For disks, there is nothing useful available at attach time.
                   1034:         */
                   1035:        if (device_class(dev) == DV_IFNET) {
                   1036:                struct btinfo_netif *bin = lookup_bootinfo(BTINFO_NETIF);
                   1037:                if (bin == NULL)
                   1038:                        return NULL;
                   1039:
                   1040:                /*
                   1041:                 * We don't check the driver name against the device name
                   1042:                 * passed by the boot ROM.  The ROM should stay usable if
                   1043:                 * the driver becomes obsolete.  The physical attachment
                   1044:                 * information (checked below) must be sufficient to
1.55      jakllsch 1045:                 * identify the device.
1.52      dyoung   1046:                 */
                   1047:                if (bin->bus == BI_BUS_PCI &&
                   1048:                    device_is_a(device_parent(dev), "pci")) {
                   1049:                        struct pci_attach_args *paa = aux;
                   1050:                        int b, d, f;
                   1051:
                   1052:                        /*
                   1053:                         * Calculate BIOS representation of:
                   1054:                         *
                   1055:                         *      <bus,device,function>
                   1056:                         *
                   1057:                         * and compare.
                   1058:                         */
                   1059:                        pci_decompose_tag(paa->pa_pc, paa->pa_tag, &b, &d, &f);
                   1060:                        if (bin->addr.tag == ((b << 8) | (d << 3) | f))
                   1061:                                return dev;
                   1062:                }
                   1063:        }
                   1064:        if (device_parent(dev) && device_is_a(device_parent(dev), "pci") &&
                   1065:            found_console == false) {
                   1066:                struct btinfo_framebuffer *fbinfo;
                   1067:                struct pci_attach_args *pa = aux;
                   1068:                prop_dictionary_t dict;
                   1069:
                   1070:                if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY) {
                   1071: #if NWSDISPLAY > 0 && NGENFB > 0
                   1072:                        extern struct vcons_screen x86_genfb_console_screen;
                   1073:                        struct rasops_info *ri;
                   1074:
                   1075:                        ri = &x86_genfb_console_screen.scr_ri;
                   1076: #endif
                   1077:
                   1078:                        fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
                   1079:                        dict = device_properties(dev);
                   1080:                        /*
                   1081:                         * framebuffer drivers other than genfb can work
                   1082:                         * without the address property
                   1083:                         */
                   1084:                        if (fbinfo != NULL) {
                   1085:                                if (fbinfo->physaddr != 0) {
                   1086:                                prop_dictionary_set_uint32(dict, "width",
                   1087:                                    fbinfo->width);
                   1088:                                prop_dictionary_set_uint32(dict, "height",
                   1089:                                    fbinfo->height);
                   1090:                                prop_dictionary_set_uint8(dict, "depth",
                   1091:                                    fbinfo->depth);
                   1092:                                prop_dictionary_set_uint16(dict, "linebytes",
                   1093:                                    fbinfo->stride);
                   1094:
                   1095:                                prop_dictionary_set_uint64(dict, "address",
                   1096:                                    fbinfo->physaddr);
                   1097: #if NWSDISPLAY > 0 && NGENFB > 0
                   1098:                                if (ri->ri_bits != NULL) {
                   1099:                                        prop_dictionary_set_uint64(dict,
                   1100:                                            "virtual_address",
1.60      macallan 1101:                                            (vaddr_t)ri->ri_origbits);
1.52      dyoung   1102:                                }
                   1103: #endif
                   1104:                                }
                   1105: #if notyet
                   1106:                                prop_dictionary_set_bool(dict, "splash",
                   1107:                                    fbinfo->flags & BI_FB_SPLASH ?
                   1108:                                     true : false);
                   1109: #endif
                   1110:                                if (fbinfo->depth == 8) {
                   1111:                                        gfb_cb.gcc_cookie = NULL;
1.55      jakllsch 1112:                                        gfb_cb.gcc_set_mapreg =
1.52      dyoung   1113:                                            x86_genfb_set_mapreg;
                   1114:                                        prop_dictionary_set_uint64(dict,
                   1115:                                            "cmap_callback",
                   1116:                                            (uint64_t)(uintptr_t)&gfb_cb);
                   1117:                                }
                   1118:                                if (fbinfo->physaddr != 0) {
                   1119:                                        mode_cb.gmc_setmode = x86_genfb_setmode;
                   1120:                                        prop_dictionary_set_uint64(dict,
                   1121:                                            "mode_callback",
                   1122:                                            (uint64_t)(uintptr_t)&mode_cb);
                   1123:                                }
                   1124:
                   1125: #if NWSDISPLAY > 0 && NGENFB > 0
                   1126:                                if (device_is_a(dev, "genfb")) {
                   1127:                                        x86_genfb_set_console_dev(dev);
                   1128: #ifdef DDB
                   1129:                                        db_trap_callback =
                   1130:                                            x86_genfb_ddb_trap_callback;
                   1131: #endif
                   1132:                                }
                   1133: #endif
                   1134:                        }
1.65      jakllsch 1135: #if 1 && NWSDISPLAY > 0 && NGENFB > 0
                   1136:                        /* XXX */
                   1137:                        if (device_is_a(dev, "genfb")) {
                   1138:                                prop_dictionary_set_bool(dict, "is_console",
                   1139:                                    genfb_is_console());
                   1140:                        } else
                   1141: #endif
1.52      dyoung   1142:                        prop_dictionary_set_bool(dict, "is_console", true);
1.60      macallan 1143:
1.52      dyoung   1144:                        prop_dictionary_set_bool(dict, "clear-screen", false);
                   1145: #if NWSDISPLAY > 0 && NGENFB > 0
                   1146:                        prop_dictionary_set_uint16(dict, "cursor-row",
                   1147:                            x86_genfb_console_screen.scr_ri.ri_crow);
                   1148: #endif
                   1149: #if notyet
                   1150:                        prop_dictionary_set_bool(dict, "splash",
                   1151:                            fbinfo->flags & BI_FB_SPLASH ? true : false);
                   1152: #endif
                   1153:                        pmf_cb.gpc_suspend = x86_genfb_suspend;
                   1154:                        pmf_cb.gpc_resume = x86_genfb_resume;
                   1155:                        prop_dictionary_set_uint64(dict,
                   1156:                            "pmf_callback", (uint64_t)(uintptr_t)&pmf_cb);
                   1157: #ifdef VGA_POST
                   1158:                        vga_posth = vga_post_init(pa->pa_bus, pa->pa_device,
                   1159:                            pa->pa_function);
                   1160: #endif
                   1161:                        found_console = true;
                   1162:                        return NULL;
                   1163:                }
                   1164:        }
                   1165:        return NULL;
                   1166: }
1.58      soren    1167:
1.64      msaitoh  1168: #ifndef PUC_CNBUS
                   1169: #define PUC_CNBUS 0
                   1170: #endif
                   1171:
1.58      soren    1172: #if NCOM > 0
                   1173: int
1.64      msaitoh  1174: cpu_puc_cnprobe(struct consdev *cn, struct pci_attach_args *pa)
1.58      soren    1175: {
                   1176:        pci_mode_detect();
                   1177:        pa->pa_iot = x86_bus_space_io;
1.64      msaitoh  1178:        pa->pa_memt = x86_bus_space_mem;
1.58      soren    1179:        pa->pa_pc = 0;
1.64      msaitoh  1180:        pa->pa_tag = pci_make_tag(0, PUC_CNBUS, pci_bus_maxdevs(NULL, 0) - 1,
                   1181:                                  0);
                   1182:
1.58      soren    1183:        return 0;
                   1184: }
                   1185: #endif

CVSweb <webmaster@jp.NetBSD.org>