LCOV - code coverage report
Current view: top level - arch/amd64/pci - pci_machdep.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 313 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: pci_machdep.c,v 1.69 2018/08/19 08:23:47 kettenis Exp $       */
       2             : /*      $NetBSD: pci_machdep.c,v 1.3 2003/05/07 21:33:58 fvdl Exp $     */
       3             : 
       4             : /*-
       5             :  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
       6             :  * All rights reserved.
       7             :  *
       8             :  * This code is derived from software contributed to The NetBSD Foundation
       9             :  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      10             :  * NASA Ames Research Center.
      11             :  *
      12             :  * Redistribution and use in source and binary forms, with or without
      13             :  * modification, are permitted provided that the following conditions
      14             :  * are met:
      15             :  * 1. Redistributions of source code must retain the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer.
      17             :  * 2. Redistributions in binary form must reproduce the above copyright
      18             :  *    notice, this list of conditions and the following disclaimer in the
      19             :  *    documentation and/or other materials provided with the distribution.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
      22             :  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
      23             :  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
      24             :  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
      25             :  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      26             :  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
      27             :  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
      28             :  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
      29             :  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
      30             :  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      31             :  * POSSIBILITY OF SUCH DAMAGE.
      32             :  */
      33             : 
      34             : /*
      35             :  * Copyright (c) 1996 Christopher G. Demetriou.  All rights reserved.
      36             :  * Copyright (c) 1994 Charles M. Hannum.  All rights reserved.
      37             :  *
      38             :  * Redistribution and use in source and binary forms, with or without
      39             :  * modification, are permitted provided that the following conditions
      40             :  * are met:
      41             :  * 1. Redistributions of source code must retain the above copyright
      42             :  *    notice, this list of conditions and the following disclaimer.
      43             :  * 2. Redistributions in binary form must reproduce the above copyright
      44             :  *    notice, this list of conditions and the following disclaimer in the
      45             :  *    documentation and/or other materials provided with the distribution.
      46             :  * 3. All advertising materials mentioning features or use of this software
      47             :  *    must display the following acknowledgement:
      48             :  *      This product includes software developed by Charles M. Hannum.
      49             :  * 4. The name of the author may not be used to endorse or promote products
      50             :  *    derived from this software without specific prior written permission.
      51             :  *
      52             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      53             :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      54             :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      55             :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      56             :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      57             :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      58             :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      59             :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      60             :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      61             :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      62             :  */
      63             : 
      64             : /*
      65             :  * Machine-specific functions for PCI autoconfiguration.
      66             :  */
      67             : 
      68             : #include <sys/param.h>
      69             : #include <sys/systm.h>
      70             : #include <sys/extent.h>
      71             : #include <sys/malloc.h>
      72             : 
      73             : #include <machine/bus.h>
      74             : 
      75             : #include <machine/pio.h>
      76             : #include <machine/intr.h>
      77             : #include <machine/biosvar.h>
      78             : 
      79             : #include <dev/isa/isareg.h>
      80             : #include <dev/pci/pcivar.h>
      81             : #include <dev/pci/pcireg.h>
      82             : #include <dev/pci/pcidevs.h>
      83             : #include <dev/pci/ppbreg.h>
      84             : 
      85             : #include "ioapic.h"
      86             : 
      87             : #if NIOAPIC > 0
      88             : #include <machine/i82093var.h>
      89             : #include <machine/mpbiosvar.h>
      90             : #endif
      91             : 
      92             : /*
      93             :  * Memory Mapped Configuration space access.
      94             :  *
      95             :  * Since mapping the whole configuration space will cost us up to
      96             :  * 256MB of kernel virtual memory, we use seperate mappings per bus.
      97             :  * The mappings are created on-demand, such that we only use kernel
      98             :  * virtual memory for busses that are actually present.
      99             :  */
     100             : bus_addr_t pci_mcfg_addr;
     101             : int pci_mcfg_min_bus, pci_mcfg_max_bus;
     102             : bus_space_tag_t pci_mcfgt;
     103             : bus_space_handle_t pci_mcfgh[256];
     104             : 
     105             : struct mutex pci_conf_lock = MUTEX_INITIALIZER(IPL_HIGH);
     106             : 
     107             : #define PCI_CONF_LOCK()                                         \
     108             : do {                                                                    \
     109             :         mtx_enter(&pci_conf_lock);                                  \
     110             : } while (0)
     111             : 
     112             : #define PCI_CONF_UNLOCK()                                               \
     113             : do {                                                                    \
     114             :         mtx_leave(&pci_conf_lock);                                  \
     115             : } while (0)
     116             : 
     117             : #define PCI_MODE1_ENABLE        0x80000000UL
     118             : #define PCI_MODE1_ADDRESS_REG   0x0cf8
     119             : #define PCI_MODE1_DATA_REG      0x0cfc
     120             : 
     121             : /*
     122             :  * PCI doesn't have any special needs; just use the generic versions
     123             :  * of these functions.
     124             :  */
     125             : struct bus_dma_tag pci_bus_dma_tag = {
     126             :         NULL,                   /* _may_bounce */
     127             :         _bus_dmamap_create,
     128             :         _bus_dmamap_destroy,
     129             :         _bus_dmamap_load,
     130             :         _bus_dmamap_load_mbuf,
     131             :         _bus_dmamap_load_uio,
     132             :         _bus_dmamap_load_raw,
     133             :         _bus_dmamap_unload,
     134             :         _bus_dmamap_sync,
     135             :         _bus_dmamem_alloc,
     136             :         _bus_dmamem_alloc_range,
     137             :         _bus_dmamem_free,
     138             :         _bus_dmamem_map,
     139             :         _bus_dmamem_unmap,
     140             :         _bus_dmamem_mmap,
     141             : };
     142             : 
     143             : void
     144           0 : pci_mcfg_init(bus_space_tag_t iot, bus_addr_t addr, int segment,
     145             :     int min_bus, int max_bus)
     146             : {
     147           0 :         if (segment == 0) {
     148           0 :                 pci_mcfgt = iot;
     149           0 :                 pci_mcfg_addr = addr;
     150           0 :                 pci_mcfg_min_bus = min_bus;
     151           0 :                 pci_mcfg_max_bus = max_bus;
     152           0 :         }
     153           0 : }
     154             : 
     155             : pci_chipset_tag_t
     156           0 : pci_lookup_segment(int segment)
     157             : {
     158           0 :         KASSERT(segment == 0);
     159           0 :         return NULL;
     160             : }
     161             : 
     162             : void
     163           0 : pci_attach_hook(struct device *parent, struct device *self,
     164             :     struct pcibus_attach_args *pba)
     165             : {
     166           0 :         pci_chipset_tag_t pc = pba->pba_pc;
     167             :         pcitag_t tag;
     168             :         pcireg_t id, class;
     169             : 
     170           0 :         if (pba->pba_bus != 0)
     171           0 :                 return;
     172             : 
     173             :         /*
     174             :          * In order to decide whether the system supports MSI we look
     175             :          * at the host bridge, which should be device 0 function 0 on
     176             :          * bus 0.  It is better to not enable MSI on systems that
     177             :          * support it than the other way around, so be conservative
     178             :          * here.  So we don't enable MSI if we don't find a host
     179             :          * bridge there.  We also deliberately don't enable MSI on
     180             :          * chipsets from low-end manifacturers like VIA and SiS.
     181             :          */
     182           0 :         tag = pci_make_tag(pc, 0, 0, 0);
     183           0 :         id = pci_conf_read(pc, tag, PCI_ID_REG);
     184           0 :         class = pci_conf_read(pc, tag, PCI_CLASS_REG);
     185             : 
     186           0 :         if (PCI_CLASS(class) != PCI_CLASS_BRIDGE ||
     187           0 :             PCI_SUBCLASS(class) != PCI_SUBCLASS_BRIDGE_HOST)
     188           0 :                 return;
     189             : 
     190           0 :         switch (PCI_VENDOR(id)) {
     191             :         case PCI_VENDOR_INTEL:
     192             :                 /*
     193             :                  * In the wonderful world of virtualization you can
     194             :                  * have the latest 64-bit AMD multicore CPU behind a
     195             :                  * prehistoric Intel host bridge.  Give them what they
     196             :                  * deserve.
     197             :                  */
     198           0 :                 switch (PCI_PRODUCT(id)) {
     199             :                 case PCI_PRODUCT_INTEL_82441FX: /* QEMU */
     200             :                 case PCI_PRODUCT_INTEL_82443BX: /* VMWare */
     201             :                         break;
     202             :                 default:
     203           0 :                         pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
     204           0 :                         break;
     205             :                 }
     206             :                 break;
     207             :         case PCI_VENDOR_NVIDIA:
     208             :         case PCI_VENDOR_AMD:
     209           0 :                 pba->pba_flags |= PCI_FLAGS_MSI_ENABLED;
     210           0 :                 break;
     211             :         }
     212             : 
     213             :         /*
     214             :          * Don't enable MSI on a HyperTransport bus.  In order to
     215             :          * determine that bus 0 is a HyperTransport bus, we look at
     216             :          * device 24 function 0, which is the HyperTransport
     217             :          * host/primary interface integrated on most 64-bit AMD CPUs.
     218             :          * If that device has a HyperTransport capability, bus 0 must
     219             :          * be a HyperTransport bus and we disable MSI.
     220             :          */
     221           0 :         tag = pci_make_tag(pc, 0, 24, 0);
     222           0 :         if (pci_get_capability(pc, tag, PCI_CAP_HT, NULL, NULL))
     223           0 :                 pba->pba_flags &= ~PCI_FLAGS_MSI_ENABLED;
     224           0 : }
     225             : 
     226             : int
     227           0 : pci_bus_maxdevs(pci_chipset_tag_t pc, int busno)
     228             : {
     229           0 :         return (32);
     230             : }
     231             : 
     232             : pcitag_t
     233           0 : pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
     234             : {
     235           0 :         if (bus >= 256 || device >= 32 || function >= 8)
     236           0 :                 panic("pci_make_tag: bad request");
     237             : 
     238           0 :         return (PCI_MODE1_ENABLE |
     239           0 :             (bus << 16) | (device << 11) | (function << 8));
     240             : }
     241             : 
     242             : void
     243           0 : pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp)
     244             : {
     245           0 :         if (bp != NULL)
     246           0 :                 *bp = (tag >> 16) & 0xff;
     247           0 :         if (dp != NULL)
     248           0 :                 *dp = (tag >> 11) & 0x1f;
     249           0 :         if (fp != NULL)
     250           0 :                 *fp = (tag >> 8) & 0x7;
     251           0 : }
     252             : 
     253             : int
     254           0 : pci_conf_size(pci_chipset_tag_t pc, pcitag_t tag)
     255             : {
     256           0 :         int bus;
     257             : 
     258           0 :         if (pci_mcfg_addr) {
     259           0 :                 pci_decompose_tag(pc, tag, &bus, NULL, NULL);
     260           0 :                 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus)
     261           0 :                         return PCIE_CONFIG_SPACE_SIZE;
     262             :         }
     263             : 
     264           0 :         return PCI_CONFIG_SPACE_SIZE;
     265           0 : }
     266             : 
     267             : void
     268           0 : pci_mcfg_map_bus(int bus)
     269             : {
     270           0 :         if (pci_mcfgh[bus])
     271             :                 return;
     272             : 
     273           0 :         if (bus_space_map(pci_mcfgt, pci_mcfg_addr + (bus << 20), 1 << 20,
     274             :             0, &pci_mcfgh[bus]))
     275           0 :                 panic("pci_conf_read: cannot map mcfg space");
     276           0 : }
     277             : 
     278             : pcireg_t
     279           0 : pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg)
     280             : {
     281             :         pcireg_t data;
     282           0 :         int bus;
     283             : 
     284           0 :         KASSERT((reg & 0x3) == 0);
     285             : 
     286           0 :         if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
     287           0 :                 pci_decompose_tag(pc, tag, &bus, NULL, NULL);
     288           0 :                 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
     289           0 :                         pci_mcfg_map_bus(bus);
     290           0 :                         data = bus_space_read_4(pci_mcfgt, pci_mcfgh[bus],
     291             :                             (tag & 0x000ff00) << 4 | reg);
     292           0 :                         return data;
     293             :                 }
     294             :         }
     295             : 
     296           0 :         PCI_CONF_LOCK();
     297           0 :         outl(PCI_MODE1_ADDRESS_REG, tag | reg);
     298           0 :         data = inl(PCI_MODE1_DATA_REG);
     299           0 :         outl(PCI_MODE1_ADDRESS_REG, 0);
     300           0 :         PCI_CONF_UNLOCK();
     301             : 
     302           0 :         return data;
     303           0 : }
     304             : 
     305             : void
     306           0 : pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data)
     307             : {
     308           0 :         int bus;
     309             : 
     310           0 :         KASSERT((reg & 0x3) == 0);
     311             : 
     312           0 :         if (pci_mcfg_addr && reg >= PCI_CONFIG_SPACE_SIZE) {
     313           0 :                 pci_decompose_tag(pc, tag, &bus, NULL, NULL);
     314           0 :                 if (bus >= pci_mcfg_min_bus && bus <= pci_mcfg_max_bus) {
     315           0 :                         pci_mcfg_map_bus(bus);
     316           0 :                         bus_space_write_4(pci_mcfgt, pci_mcfgh[bus],
     317             :                             (tag & 0x000ff00) << 4 | reg, data);
     318           0 :                         return;
     319             :                 }
     320             :         }
     321             : 
     322           0 :         PCI_CONF_LOCK();
     323           0 :         outl(PCI_MODE1_ADDRESS_REG, tag | reg);
     324           0 :         outl(PCI_MODE1_DATA_REG, data);
     325           0 :         outl(PCI_MODE1_ADDRESS_REG, 0);
     326           0 :         PCI_CONF_UNLOCK();
     327           0 : }
     328             : 
     329             : void msi_hwmask(struct pic *, int);
     330             : void msi_hwunmask(struct pic *, int);
     331             : void msi_addroute(struct pic *, struct cpu_info *, int, int, int);
     332             : void msi_delroute(struct pic *, struct cpu_info *, int, int, int);
     333             : 
     334             : struct pic msi_pic = {
     335             :         {0, {NULL}, NULL, 0, "msi", NULL, 0, 0},
     336             :         PIC_MSI,
     337             : #ifdef MULTIPROCESSOR
     338             :         {},
     339             : #endif
     340             :         msi_hwmask,
     341             :         msi_hwunmask,
     342             :         msi_addroute,
     343             :         msi_delroute,
     344             :         NULL,
     345             :         ioapic_edge_stubs
     346             : };
     347             : 
     348             : void
     349           0 : msi_hwmask(struct pic *pic, int pin)
     350             : {
     351           0 : }
     352             : 
     353             : void
     354           0 : msi_hwunmask(struct pic *pic, int pin)
     355             : {
     356           0 : }
     357             : 
     358             : void
     359           0 : msi_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
     360             : {
     361             :         pci_chipset_tag_t pc = NULL; /* XXX */
     362             :         pcitag_t tag = pin;
     363           0 :         pcireg_t reg, addr;
     364           0 :         int off;
     365             : 
     366           0 :         if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, &reg) == 0)
     367           0 :                 panic("%s: no msi capability", __func__);
     368             : 
     369           0 :         addr = 0xfee00000UL | (ci->ci_apicid << 12);
     370             : 
     371           0 :         if (reg & PCI_MSI_MC_C64) {
     372             :                 pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
     373           0 :                 pci_conf_write(pc, tag, off + PCI_MSI_MAU32, 0);
     374           0 :                 pci_conf_write(pc, tag, off + PCI_MSI_MD64, vec);
     375           0 :         } else {
     376             :                 pci_conf_write(pc, tag, off + PCI_MSI_MA, addr);
     377           0 :                 pci_conf_write(pc, tag, off + PCI_MSI_MD32, vec);
     378             :         }
     379           0 :         pci_conf_write(pc, tag, off, reg | PCI_MSI_MC_MSIE);
     380           0 : }
     381             : 
     382             : void
     383           0 : msi_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
     384             : {
     385             :         pci_chipset_tag_t pc = NULL; /* XXX */
     386             :         pcitag_t tag = pin;
     387           0 :         pcireg_t reg;
     388           0 :         int off;
     389             : 
     390           0 :         if (pci_get_capability(pc, tag, PCI_CAP_MSI, &off, &reg))
     391           0 :                 pci_conf_write(pc, tag, off, reg & ~PCI_MSI_MC_MSIE);
     392           0 : }
     393             : 
     394             : int
     395           0 : pci_intr_map_msi(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
     396             : {
     397           0 :         pci_chipset_tag_t pc = pa->pa_pc;
     398           0 :         pcitag_t tag = pa->pa_tag;
     399             : 
     400           0 :         if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
     401           0 :             pci_get_capability(pc, tag, PCI_CAP_MSI, NULL, NULL) == 0)
     402           0 :                 return 1;
     403             : 
     404           0 :         ihp->tag = tag;
     405           0 :         ihp->line = APIC_INT_VIA_MSG;
     406           0 :         ihp->pin = 0;
     407           0 :         return 0;
     408           0 : }
     409             : 
     410             : void msix_hwmask(struct pic *, int);
     411             : void msix_hwunmask(struct pic *, int);
     412             : void msix_addroute(struct pic *, struct cpu_info *, int, int, int);
     413             : void msix_delroute(struct pic *, struct cpu_info *, int, int, int);
     414             : 
     415             : struct pic msix_pic = {
     416             :         {0, {NULL}, NULL, 0, "msix", NULL, 0, 0},
     417             :         PIC_MSI,
     418             : #ifdef MULTIPROCESSOR
     419             :         {},
     420             : #endif
     421             :         msix_hwmask,
     422             :         msix_hwunmask,
     423             :         msix_addroute,
     424             :         msix_delroute,
     425             :         NULL,
     426             :         ioapic_edge_stubs
     427             : };
     428             : 
     429             : /*
     430             :  * We pack the MSI-X vector number into the lower 8 bits of the PCI
     431             :  * tag and use that as the MSI-X "PIC" pin number.  This allows us to
     432             :  * address 256 MSI-X vectors which ought to be enough for anybody.
     433             :  */
     434             : #define PCI_MSIX_VEC_MASK       0xff
     435             : #define PCI_MSIX_VEC(pin)       ((pin) & PCI_MSIX_VEC_MASK)
     436             : #define PCI_MSIX_TAG(pin)       ((pin) & ~PCI_MSIX_VEC_MASK)
     437             : #define PCI_MSIX_PIN(tag, vec)  ((tag) | (vec))
     438             : 
     439             : void
     440           0 : msix_hwmask(struct pic *pic, int pin)
     441             : {
     442           0 : }
     443             : 
     444             : void
     445           0 : msix_hwunmask(struct pic *pic, int pin)
     446             : {
     447           0 : }
     448             : 
     449             : void
     450           0 : msix_addroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
     451             : {
     452             :         pci_chipset_tag_t pc = NULL; /* XXX */
     453             :         bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
     454           0 :         bus_space_handle_t memh;
     455           0 :         bus_addr_t base;
     456           0 :         pcitag_t tag = PCI_MSIX_TAG(pin);
     457           0 :         int entry = PCI_MSIX_VEC(pin);
     458           0 :         pcireg_t reg, addr, table;
     459             :         uint32_t ctrl;
     460             :         int bir, offset;
     461           0 :         int off, tblsz;
     462             : 
     463           0 :         if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, &reg) == 0)
     464           0 :                 panic("%s: no msix capability", __func__);
     465             : 
     466           0 :         addr = 0xfee00000UL | (ci->ci_apicid << 12);
     467             : 
     468           0 :         table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
     469           0 :         bir = (table & PCI_MSIX_TABLE_BIR);
     470           0 :         offset = (table & PCI_MSIX_TABLE_OFF);
     471           0 :         tblsz = PCI_MSIX_MC_TBLSZ(reg) + 1;
     472             : 
     473           0 :         bir = PCI_MAPREG_START + bir * 4;
     474           0 :         if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
     475           0 :             _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
     476           0 :                 panic("%s: cannot map registers", __func__);
     477             : 
     478           0 :         bus_space_write_8(memt, memh, PCI_MSIX_MA(entry), addr);
     479           0 :         bus_space_write_4(memt, memh, PCI_MSIX_MD(entry), vec);
     480           0 :         bus_space_barrier(memt, memh, PCI_MSIX_MA(entry), 16,
     481             :             BUS_SPACE_BARRIER_WRITE);
     482           0 :         ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
     483           0 :         bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
     484             :             ctrl & ~PCI_MSIX_VC_MASK);
     485             : 
     486           0 :         _bus_space_unmap(memt, memh, tblsz * 16, NULL);
     487             : 
     488           0 :         pci_conf_write(pc, tag, off, reg | PCI_MSIX_MC_MSIXE);
     489           0 : }
     490             : 
     491             : void
     492           0 : msix_delroute(struct pic *pic, struct cpu_info *ci, int pin, int vec, int type)
     493             : {
     494             :         pci_chipset_tag_t pc = NULL; /* XXX */
     495             :         bus_space_tag_t memt = X86_BUS_SPACE_MEM; /* XXX */
     496           0 :         bus_space_handle_t memh;
     497           0 :         bus_addr_t base;
     498           0 :         pcitag_t tag = PCI_MSIX_TAG(pin);
     499           0 :         int entry = PCI_MSIX_VEC(pin);
     500           0 :         pcireg_t reg, table;
     501             :         uint32_t ctrl;
     502             :         int bir, offset;
     503           0 :         int off, tblsz;
     504             : 
     505           0 :         if (pci_get_capability(pc, tag, PCI_CAP_MSIX, &off, &reg) == 0)
     506           0 :                 return;
     507             : 
     508           0 :         table = pci_conf_read(pc, tag, off + PCI_MSIX_TABLE);
     509           0 :         bir = (table & PCI_MSIX_TABLE_BIR);
     510           0 :         offset = (table & PCI_MSIX_TABLE_OFF);
     511           0 :         tblsz = PCI_MSIX_MC_TBLSZ(reg) + 1;
     512             : 
     513           0 :         bir = PCI_MAPREG_START + bir * 4;
     514           0 :         if (pci_mem_find(pc, tag, bir, &base, NULL, NULL) ||
     515           0 :             _bus_space_map(memt, base + offset, tblsz * 16, 0, &memh))
     516           0 :                 panic("%s: cannot map registers", __func__);
     517             : 
     518           0 :         ctrl = bus_space_read_4(memt, memh, PCI_MSIX_VC(entry));
     519           0 :         bus_space_write_4(memt, memh, PCI_MSIX_VC(entry),
     520             :             ctrl | PCI_MSIX_VC_MASK);
     521             : 
     522           0 :         _bus_space_unmap(memt, memh, tblsz * 16, NULL);
     523           0 : }
     524             : 
     525             : int
     526           0 : pci_intr_map_msix(struct pci_attach_args *pa, int vec, pci_intr_handle_t *ihp)
     527             : {
     528           0 :         pci_chipset_tag_t pc = pa->pa_pc;
     529           0 :         pcitag_t tag = pa->pa_tag;
     530           0 :         pcireg_t reg;
     531             : 
     532           0 :         KASSERT(PCI_MSIX_VEC(vec) == vec);
     533             : 
     534           0 :         if ((pa->pa_flags & PCI_FLAGS_MSI_ENABLED) == 0 || mp_busses == NULL ||
     535           0 :             pci_get_capability(pc, tag, PCI_CAP_MSIX, NULL, &reg) == 0)
     536           0 :                 return 1;
     537             : 
     538           0 :         if (vec > PCI_MSIX_MC_TBLSZ(reg))
     539           0 :                 return 1;
     540             : 
     541           0 :         ihp->tag = PCI_MSIX_PIN(tag, vec);
     542           0 :         ihp->line = APIC_INT_VIA_MSGX;
     543           0 :         ihp->pin = 0;
     544           0 :         return 0;
     545           0 : }
     546             : 
     547             : int
     548           0 : pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
     549             : {
     550           0 :         int pin = pa->pa_rawintrpin;
     551           0 :         int line = pa->pa_intrline;
     552             : #if NIOAPIC > 0
     553             :         struct mp_intr_map *mip;
     554           0 :         int bus, dev, func;
     555             : #endif
     556             : 
     557           0 :         if (pin == 0) {
     558             :                 /* No IRQ used. */
     559             :                 goto bad;
     560             :         }
     561             : 
     562           0 :         if (pin > PCI_INTERRUPT_PIN_MAX) {
     563           0 :                 printf("pci_intr_map: bad interrupt pin %d\n", pin);
     564           0 :                 goto bad;
     565             :         }
     566             : 
     567           0 :         ihp->tag = pa->pa_tag;
     568           0 :         ihp->line = line;
     569           0 :         ihp->pin = pin;
     570             : 
     571             : #if NIOAPIC > 0
     572           0 :         pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &func);
     573             : 
     574           0 :         if (mp_busses != NULL) {
     575           0 :                 int mpspec_pin = (dev << 2) | (pin - 1);
     576             : 
     577           0 :                 if (bus < mp_nbusses) {
     578           0 :                         for (mip = mp_busses[bus].mb_intrs;
     579           0 :                              mip != NULL; mip = mip->next) {
     580           0 :                                 if (&mp_busses[bus] == mp_isa_bus ||
     581           0 :                                     &mp_busses[bus] == mp_eisa_bus)
     582             :                                         continue;
     583           0 :                                 if (mip->bus_pin == mpspec_pin) {
     584           0 :                                         ihp->line = mip->ioapic_ih | line;
     585           0 :                                         return 0;
     586             :                                 }
     587             :                         }
     588             :                 }
     589             : 
     590           0 :                 if (pa->pa_bridgetag) {
     591           0 :                         int swizpin = PPB_INTERRUPT_SWIZZLE(pin, dev);
     592           0 :                         if (pa->pa_bridgeih[swizpin - 1].line != -1) {
     593             :                                 ihp->line = pa->pa_bridgeih[swizpin - 1].line;
     594           0 :                                 ihp->line |= line;
     595           0 :                                 return 0;
     596             :                         }
     597           0 :                 }
     598             :                 /*
     599             :                  * No explicit PCI mapping found. This is not fatal,
     600             :                  * we'll try the ISA (or possibly EISA) mappings next.
     601             :                  */
     602           0 :         }
     603             : #endif
     604             : 
     605             :         /*
     606             :          * Section 6.2.4, `Miscellaneous Functions', says that 255 means
     607             :          * `unknown' or `no connection' on a PC.  We assume that a device with
     608             :          * `no connection' either doesn't have an interrupt (in which case the
     609             :          * pin number should be 0, and would have been noticed above), or
     610             :          * wasn't configured by the BIOS (in which case we punt, since there's
     611             :          * no real way we can know how the interrupt lines are mapped in the
     612             :          * hardware).
     613             :          *
     614             :          * XXX
     615             :          * Since IRQ 0 is only used by the clock, and we can't actually be sure
     616             :          * that the BIOS did its job, we also recognize that as meaning that
     617             :          * the BIOS has not configured the device.
     618             :          */
     619           0 :         if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION)
     620             :                 goto bad;
     621             : 
     622           0 :         if (line >= NUM_LEGACY_IRQS) {
     623           0 :                 printf("pci_intr_map: bad interrupt line %d\n", line);
     624           0 :                 goto bad;
     625             :         }
     626           0 :         if (line == 2) {
     627           0 :                 printf("pci_intr_map: changed line 2 to line 9\n");
     628             :                 line = 9;
     629           0 :         }
     630             : 
     631             : #if NIOAPIC > 0
     632           0 :         if (mp_busses != NULL) {
     633           0 :                 if (mip == NULL && mp_isa_bus) {
     634           0 :                         for (mip = mp_isa_bus->mb_intrs; mip != NULL;
     635           0 :                             mip = mip->next) {
     636           0 :                                 if (mip->bus_pin == line) {
     637           0 :                                         ihp->line = mip->ioapic_ih | line;
     638           0 :                                         return 0;
     639             :                                 }
     640             :                         }
     641             :                 }
     642             : #if NEISA > 0
     643             :                 if (mip == NULL && mp_eisa_bus) {
     644             :                         for (mip = mp_eisa_bus->mb_intrs;  mip != NULL;
     645             :                             mip = mip->next) {
     646             :                                 if (mip->bus_pin == line) {
     647             :                                         ihp->line = mip->ioapic_ih | line;
     648             :                                         return 0;
     649             :                                 }
     650             :                         }
     651             :                 }
     652             : #endif
     653           0 :                 if (mip == NULL) {
     654           0 :                         printf("pci_intr_map: "
     655             :                             "bus %d dev %d func %d pin %d; line %d\n",
     656           0 :                             bus, dev, func, pin, line);
     657           0 :                         printf("pci_intr_map: no MP mapping found\n");
     658           0 :                 }
     659             :         }
     660             : #endif
     661             : 
     662           0 :         return 0;
     663             : 
     664             : bad:
     665           0 :         ihp->line = -1;
     666           0 :         return 1;
     667           0 : }
     668             : 
     669             : const char *
     670           0 : pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih)
     671             : {
     672             :         static char irqstr[64];
     673             : 
     674           0 :         if (ih.line == 0)
     675           0 :                 panic("pci_intr_string: bogus handle 0x%x", ih.line);
     676             : 
     677           0 :         if (ih.line & APIC_INT_VIA_MSG)
     678           0 :                 return ("msi");
     679           0 :         if (ih.line & APIC_INT_VIA_MSGX)
     680           0 :                 return ("msix");
     681             : 
     682             : #if NIOAPIC > 0
     683           0 :         if (ih.line & APIC_INT_VIA_APIC)
     684           0 :                 snprintf(irqstr, sizeof(irqstr), "apic %d int %d",
     685           0 :                     APIC_IRQ_APIC(ih.line), APIC_IRQ_PIN(ih.line));
     686             :         else
     687           0 :                 snprintf(irqstr, sizeof(irqstr), "irq %d",
     688           0 :                     pci_intr_line(pc, ih));
     689             : #else
     690             :         snprintf(irqstr, sizeof(irqstr), "irq %d", pci_intr_line(pc, ih));
     691             : #endif
     692           0 :         return (irqstr);
     693           0 : }
     694             : 
     695             : #include "acpiprt.h"
     696             : #if NACPIPRT > 0
     697             : void    acpiprt_route_interrupt(int bus, int dev, int pin);
     698             : #endif
     699             : 
     700             : void *
     701           0 : pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level,
     702             :     int (*func)(void *), void *arg, const char *what)
     703             : {
     704             :         int pin, irq;
     705           0 :         int bus, dev;
     706           0 :         pcitag_t tag = ih.tag;
     707             :         struct pic *pic;
     708             : 
     709           0 :         if (ih.line & APIC_INT_VIA_MSG) {
     710           0 :                 return intr_establish(-1, &msi_pic, tag, IST_PULSE, level,
     711             :                     func, arg, what);
     712             :         }
     713           0 :         if (ih.line & APIC_INT_VIA_MSGX) {
     714           0 :                 return intr_establish(-1, &msix_pic, tag, IST_PULSE, level,
     715             :                     func, arg, what);
     716             :         }
     717             : 
     718           0 :         pci_decompose_tag(pc, ih.tag, &bus, &dev, NULL);
     719             : #if NACPIPRT > 0
     720           0 :         acpiprt_route_interrupt(bus, dev, ih.pin);
     721             : #endif
     722             : 
     723             :         pic = &i8259_pic;
     724             :         pin = irq = ih.line;
     725             : 
     726             : #if NIOAPIC > 0
     727           0 :         if (ih.line & APIC_INT_VIA_APIC) {
     728           0 :                 pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih.line));
     729           0 :                 if (pic == NULL) {
     730           0 :                         printf("pci_intr_establish: bad ioapic %d\n",
     731             :                             APIC_IRQ_APIC(ih.line));
     732           0 :                         return NULL;
     733             :                 }
     734           0 :                 pin = APIC_IRQ_PIN(ih.line);
     735           0 :                 irq = APIC_IRQ_LEGACY_IRQ(ih.line);
     736           0 :                 if (irq < 0 || irq >= NUM_LEGACY_IRQS)
     737             :                         irq = -1;
     738             :         }
     739             : #endif
     740             : 
     741           0 :         return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg, what);
     742           0 : }
     743             : 
     744             : void
     745           0 : pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie)
     746             : {
     747           0 :         intr_disestablish(cookie);
     748           0 : }
     749             : 
     750             : struct extent *pciio_ex;
     751             : struct extent *pcimem_ex;
     752             : struct extent *pcibus_ex;
     753             : 
     754             : void
     755           0 : pci_init_extents(void)
     756             : {
     757             :         bios_memmap_t *bmp;
     758             :         u_int64_t size;
     759             : 
     760           0 :         if (pciio_ex == NULL) {
     761             :                 /*
     762             :                  * We only have 64K of addressable I/O space.
     763             :                  * However, since BARs may contain garbage, we cover
     764             :                  * the full 32-bit address space defined by PCI of
     765             :                  * which we only make the first 64K available.
     766             :                  */
     767           0 :                 pciio_ex = extent_create("pciio", 0, 0xffffffff, M_DEVBUF,
     768             :                     NULL, 0, EX_NOWAIT | EX_FILLED);
     769           0 :                 if (pciio_ex == NULL)
     770           0 :                         return;
     771           0 :                 extent_free(pciio_ex, 0, 0x10000, EX_NOWAIT);
     772           0 :         }
     773             : 
     774           0 :         if (pcimem_ex == NULL) {
     775             :                 /*
     776             :                  * Cover the 36-bit address space addressable by PAE
     777             :                  * here.  As long as vendors continue to support
     778             :                  * 32-bit operating systems, we should never see BARs
     779             :                  * outside that region.
     780             :                  *
     781             :                  * Dell 13G servers have important devices outside the
     782             :                  * 36-bit address space.  Until we can extract the address
     783             :                  * ranges from ACPI, expand the allowed range to suit.
     784             :                  */
     785           0 :                 pcimem_ex = extent_create("pcimem", 0, 0xffffffffffffffffUL,
     786             :                     M_DEVBUF, NULL, 0, EX_NOWAIT);
     787           0 :                 if (pcimem_ex == NULL)
     788           0 :                         return;
     789           0 :                 extent_alloc_region(pcimem_ex, 0x40000000000UL,
     790             :                     0xfffffc0000000000UL, EX_NOWAIT);
     791             : 
     792           0 :                 for (bmp = bios_memmap; bmp->type != BIOS_MAP_END; bmp++) {
     793             :                         /*
     794             :                          * Ignore address space beyond 4G.
     795             :                          */
     796           0 :                         if (bmp->addr >= 0x100000000ULL)
     797             :                                 continue;
     798           0 :                         size = bmp->size;
     799           0 :                         if (bmp->addr + size >= 0x100000000ULL)
     800           0 :                                 size = 0x100000000ULL - bmp->addr;
     801             : 
     802             :                         /* Ignore zero-sized regions. */
     803           0 :                         if (size == 0)
     804             :                                 continue;
     805             : 
     806           0 :                         if (extent_alloc_region(pcimem_ex, bmp->addr, size,
     807             :                             EX_NOWAIT))
     808           0 :                                 printf("memory map conflict 0x%llx/0x%llx\n",
     809           0 :                                     bmp->addr, bmp->size);
     810             :                 }
     811             : 
     812             :                 /* Take out the video buffer area and BIOS areas. */
     813           0 :                 extent_alloc_region(pcimem_ex, IOM_BEGIN, IOM_SIZE,
     814             :                     EX_CONFLICTOK | EX_NOWAIT);
     815           0 :         }
     816             : 
     817           0 :         if (pcibus_ex == NULL) {
     818           0 :                 pcibus_ex = extent_create("pcibus", 0, 0xff, M_DEVBUF,
     819             :                     NULL, 0, EX_NOWAIT);
     820           0 :         }
     821           0 : }
     822             : 
     823             : #include "acpi.h"
     824             : #if NACPI > 0
     825             : void acpi_pci_match(struct device *, struct pci_attach_args *);
     826             : pcireg_t acpi_pci_min_powerstate(pci_chipset_tag_t, pcitag_t);
     827             : void acpi_pci_set_powerstate(pci_chipset_tag_t, pcitag_t, int, int);
     828             : #endif
     829             : 
     830             : void
     831           0 : pci_dev_postattach(struct device *dev, struct pci_attach_args *pa)
     832             : {
     833             : #if NACPI > 0
     834           0 :         acpi_pci_match(dev, pa);
     835             : #endif
     836           0 : }
     837             : 
     838             : pcireg_t
     839           0 : pci_min_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
     840             : {
     841             : #if NACPI > 0
     842           0 :         return acpi_pci_min_powerstate(pc, tag);
     843             : #else
     844             :         return pci_get_powerstate(pc, tag);
     845             : #endif
     846             : }
     847             : 
     848             : void
     849           0 : pci_set_powerstate_md(pci_chipset_tag_t pc, pcitag_t tag, int state, int pre)
     850             : {
     851             : #if NACPI > 0
     852           0 :         acpi_pci_set_powerstate(pc, tag, state, pre);
     853             : #endif
     854           0 : }

Generated by: LCOV version 1.13