Home | History | Annotate | Line # | Download | only in pci
pq3pci.c revision 1.3.2.3
      1  1.3.2.2  rmind /*	$NetBSD: pq3pci.c,v 1.3.2.3 2011/04/21 01:41:19 rmind Exp $	*/
      2  1.3.2.2  rmind /*-
      3  1.3.2.2  rmind  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
      4  1.3.2.2  rmind  * All rights reserved.
      5  1.3.2.2  rmind  *
      6  1.3.2.2  rmind  * This code is derived from software contributed to The NetBSD Foundation
      7  1.3.2.2  rmind  * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
      8  1.3.2.2  rmind  * Agency and which was developed by Matt Thomas of 3am Software Foundry.
      9  1.3.2.2  rmind  *
     10  1.3.2.2  rmind  * This material is based upon work supported by the Defense Advanced Research
     11  1.3.2.2  rmind  * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
     12  1.3.2.2  rmind  * Contract No. N66001-09-C-2073.
     13  1.3.2.2  rmind  * Approved for Public Release, Distribution Unlimited
     14  1.3.2.2  rmind  *
     15  1.3.2.2  rmind  * Redistribution and use in source and binary forms, with or without
     16  1.3.2.2  rmind  * modification, are permitted provided that the following conditions
     17  1.3.2.2  rmind  * are met:
     18  1.3.2.2  rmind  * 1. Redistributions of source code must retain the above copyright
     19  1.3.2.2  rmind  *    notice, this list of conditions and the following disclaimer.
     20  1.3.2.2  rmind  * 2. Redistributions in binary form must reproduce the above copyright
     21  1.3.2.2  rmind  *    notice, this list of conditions and the following disclaimer in the
     22  1.3.2.2  rmind  *    documentation and/or other materials provided with the distribution.
     23  1.3.2.2  rmind  *
     24  1.3.2.2  rmind  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     25  1.3.2.2  rmind  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  1.3.2.2  rmind  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     27  1.3.2.2  rmind  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     28  1.3.2.2  rmind  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29  1.3.2.2  rmind  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  1.3.2.2  rmind  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31  1.3.2.2  rmind  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     32  1.3.2.2  rmind  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33  1.3.2.2  rmind  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34  1.3.2.2  rmind  * POSSIBILITY OF SUCH DAMAGE.
     35  1.3.2.2  rmind  */
     36  1.3.2.2  rmind 
     37  1.3.2.2  rmind #define	PCI_PRIVATE
     38  1.3.2.2  rmind #define	GLOBAL_PRIVATE
     39  1.3.2.2  rmind #define	__INTR_PRIVATE
     40  1.3.2.2  rmind 
     41  1.3.2.2  rmind #include "opt_mpc85xx.h"
     42  1.3.2.2  rmind #include "opt_pci.h"
     43  1.3.2.2  rmind #include "locators.h"
     44  1.3.2.2  rmind 
     45  1.3.2.2  rmind #include <sys/cdefs.h>
     46  1.3.2.2  rmind 
     47  1.3.2.2  rmind __KERNEL_RCSID(0, "$NetBSD: pq3pci.c,v 1.3.2.3 2011/04/21 01:41:19 rmind Exp $");
     48  1.3.2.2  rmind 
     49  1.3.2.2  rmind #include <sys/param.h>
     50  1.3.2.2  rmind #include <sys/device.h>
     51  1.3.2.2  rmind #include <sys/cpu.h>
     52  1.3.2.2  rmind #include <sys/intr.h>
     53  1.3.2.2  rmind #include <sys/bus.h>
     54  1.3.2.2  rmind #include <sys/extent.h>
     55  1.3.2.2  rmind #include <sys/bitops.h>
     56  1.3.2.2  rmind #include <sys/kmem.h>
     57  1.3.2.2  rmind #include <sys/malloc.h>	/* for extent */
     58  1.3.2.2  rmind 
     59  1.3.2.2  rmind #include <dev/pci/pcireg.h>
     60  1.3.2.2  rmind #include <dev/pci/pcivar.h>
     61  1.3.2.2  rmind #include <dev/pci/pciconf.h>
     62  1.3.2.2  rmind #include <dev/pci/pcidevs.h>
     63  1.3.2.2  rmind 
     64  1.3.2.2  rmind #include <powerpc/booke/cpuvar.h>
     65  1.3.2.2  rmind #include <powerpc/booke/spr.h>
     66  1.3.2.2  rmind #include <powerpc/booke/e500var.h>
     67  1.3.2.2  rmind #include <powerpc/booke/e500reg.h>
     68  1.3.2.2  rmind #include <powerpc/booke/openpicreg.h>
     69  1.3.2.2  rmind 
     70  1.3.2.2  rmind #define	PORDEVSR_MPC8536_TRUTH_ENCODE(inst, field, value, result) \
     71  1.3.2.2  rmind     TRUTH_ENCODE(SVR_MPC8536v1, inst, PORDEVSR_##field, \
     72  1.3.2.2  rmind 	__SHIFTIN(field##_##MPC8536##_##value, PORDEVSR_##field), result)
     73  1.3.2.2  rmind #define	PORDEVSR_MPC8544_TRUTH_ENCODE(inst, field, value, result) \
     74  1.3.2.2  rmind     TRUTH_ENCODE(SVR_MPC8544v1, inst, PORDEVSR_##field, \
     75  1.3.2.2  rmind 	__SHIFTIN(field##_##MPC8544##_##value, PORDEVSR_##field), result)
     76  1.3.2.2  rmind #define	PORDEVSR_MPC8548_TRUTH_ENCODE(inst, field, value, result) \
     77  1.3.2.2  rmind     TRUTH_ENCODE(SVR_MPC8548v1, inst, PORDEVSR_##field, \
     78  1.3.2.2  rmind 	__SHIFTIN(field##_##MPC8548##_##value, PORDEVSR_##field), result)
     79  1.3.2.2  rmind #define	PORDEVSR_MPC8555_TRUTH_ENCODE(inst, field, value, result) \
     80  1.3.2.2  rmind     TRUTH_ENCODE(SVR_MPC8555v1, inst, PORDEVSR_##field, \
     81  1.3.2.2  rmind 	__SHIFTIN(field##_##MPC8555##_##value, PORDEVSR_##field), result)
     82  1.3.2.2  rmind #define	PORDEVSR_MPC8572_TRUTH_ENCODE(inst, field, value, result) \
     83  1.3.2.2  rmind     TRUTH_ENCODE(SVR_MPC8572v1, inst, PORDEVSR_##field, \
     84  1.3.2.2  rmind 	__SHIFTIN(field##_##MPC8572##_##value, PORDEVSR_##field), result)
     85  1.3.2.2  rmind #define	PORDEVSR_P20x0_TRUTH_ENCODE(inst, field, value, result) \
     86  1.3.2.3  rmind     TRUTH_ENCODE(SVR_P2020v2, inst, PORDEVSR_##field, \
     87  1.3.2.2  rmind 	__SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result), \
     88  1.3.2.3  rmind     TRUTH_ENCODE(SVR_P2010v2, inst, PORDEVSR_##field, \
     89  1.3.2.2  rmind 	__SHIFTIN(field##_##P20x0##_##value, PORDEVSR_##field), result)
     90  1.3.2.2  rmind 
     91  1.3.2.2  rmind #define	PORDEVSR_TRUTH_ENCODE(svr, inst, field, value, result) \
     92  1.3.2.2  rmind     TRUTH_ENCODE(svr, inst, PORDEVSR_##field, \
     93  1.3.2.2  rmind 	__SHIFTIN(field##_##value, PORDEVSR_##field), result)
     94  1.3.2.2  rmind 
     95  1.3.2.2  rmind const struct e500_truthtab pq3pci_pcie_lanes[] = {
     96  1.3.2.2  rmind #ifdef MPC8548
     97  1.3.2.2  rmind     PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, SRIO2500_PCIE1_X4, 4),
     98  1.3.2.2  rmind     PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, SRIO1250_PCIE1_X4, 4),
     99  1.3.2.2  rmind     PORDEVSR_MPC8548_TRUTH_ENCODE(0, IOSEL, PCIE1_X8, 8),
    100  1.3.2.2  rmind #endif
    101  1.3.2.2  rmind 
    102  1.3.2.2  rmind #ifdef MPC8544
    103  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE1_ON, 4),
    104  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE1_SGMII_ON, 4),
    105  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE12_ON, 4),
    106  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE12_SGMII_ON, 4),
    107  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE123_ON, 4),
    108  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(1, IOSEL, PCIE123_SGMII_ON, 4),
    109  1.3.2.2  rmind 
    110  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE12_ON, 4),
    111  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE12_SGMII_ON, 4),
    112  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE123_ON, 4),
    113  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(2, IOSEL, PCIE123_SGMII_ON, 4),
    114  1.3.2.2  rmind 
    115  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(3, IOSEL, PCIE123_ON, 1),
    116  1.3.2.2  rmind     PORDEVSR_MPC8544_TRUTH_ENCODE(3, IOSEL, PCIE123_SGMII_ON, 1),
    117  1.3.2.2  rmind #endif
    118  1.3.2.2  rmind 
    119  1.3.2.2  rmind #ifdef MPC8536
    120  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
    121  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X8, 8),
    122  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE12_X4, 4),
    123  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(1, IOSEL, PCIE1_X4_PCI23_X2, 4),
    124  1.3.2.2  rmind 
    125  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(2, IOSEL, PCIE12_X4, 4),
    126  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(2, IOSEL, PCIE1_X4_PCI23_X2, 2),
    127  1.3.2.2  rmind 
    128  1.3.2.2  rmind     PORDEVSR_MPC8536_TRUTH_ENCODE(3, IOSEL, PCIE1_X4_PCI23_X2, 2),
    129  1.3.2.2  rmind #endif
    130  1.3.2.2  rmind 
    131  1.3.2.2  rmind #ifdef MPC8572
    132  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, SRIO2500_PCIE1_X4, 4),
    133  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, SRIO1250_PCIE1_X4, 4),
    134  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
    135  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE12_X4, 4),
    136  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X4_23_X2, 4),
    137  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(1, IOSEL, PCIE1_X8, 8),
    138  1.3.2.2  rmind 
    139  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(2, IOSEL, PCIE12_X4, 4),
    140  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(2, IOSEL, PCIE1_X4_23_X2, 2),
    141  1.3.2.2  rmind 
    142  1.3.2.2  rmind     PORDEVSR_MPC8572_TRUTH_ENCODE(3, IOSEL, PCIE1_X4_23_X2, 2),
    143  1.3.2.2  rmind #endif
    144  1.3.2.2  rmind 
    145  1.3.2.2  rmind #ifdef P2020
    146  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X1, 1),
    147  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE12_X1_3_X2, 1),
    148  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE13_X2, 2),
    149  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X4, 4),
    150  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X1_SRIO2500_1X, 1),
    151  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE12_X1_SGMII23, 1),
    152  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(1, IOSEL, PCIE1_X2_SGMII23, 2),
    153  1.3.2.2  rmind 
    154  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(2, IOSEL, PCIE12_X1_3_X2, 1),
    155  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(2, IOSEL, PCIE12_X1_SGMII23, 1),
    156  1.3.2.2  rmind 
    157  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(3, IOSEL, PCIE12_X1_3_X2, 2),
    158  1.3.2.2  rmind     PORDEVSR_P20x0_TRUTH_ENCODE(3, IOSEL, PCIE13_X2, 2),
    159  1.3.2.2  rmind #endif
    160  1.3.2.2  rmind };
    161  1.3.2.2  rmind 
    162  1.3.2.2  rmind static const struct e500_truthtab pq3pci_pci_pcix[] = {
    163  1.3.2.2  rmind #ifdef MPC8548
    164  1.3.2.2  rmind     PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI1, PCIX, 1),
    165  1.3.2.2  rmind #endif
    166  1.3.2.2  rmind };
    167  1.3.2.2  rmind 
    168  1.3.2.2  rmind static const struct e500_truthtab pq3pci_pci_pci32[] = {
    169  1.3.2.2  rmind #ifdef MPC8548
    170  1.3.2.2  rmind     PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI32, FALSE, 64),
    171  1.3.2.2  rmind     PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI32, TRUE, 32),
    172  1.3.2.2  rmind #endif
    173  1.3.2.2  rmind 
    174  1.3.2.2  rmind #ifdef MPC8555
    175  1.3.2.2  rmind     PORDEVSR_TRUTH_ENCODE(SVR_MPC8555v1, 0, PCI32, FALSE, 64),
    176  1.3.2.2  rmind     PORDEVSR_TRUTH_ENCODE(SVR_MPC8555v1, 0, PCI32, TRUE, 32),
    177  1.3.2.2  rmind #endif
    178  1.3.2.2  rmind };
    179  1.3.2.2  rmind 
    180  1.3.2.2  rmind struct pq3pci_bst {
    181  1.3.2.2  rmind 	struct powerpc_bus_space bs_tag;
    182  1.3.2.2  rmind 	char bs_name[16];
    183  1.3.2.2  rmind 	char bs_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8)] __aligned(8);
    184  1.3.2.2  rmind };
    185  1.3.2.2  rmind 
    186  1.3.2.2  rmind typedef enum { IH_NONE, IH_INTX, IH_MSI, IH_MSIX } pq3pci_intr_class_t;
    187  1.3.2.2  rmind 
    188  1.3.2.2  rmind struct pq3pci_genihand {
    189  1.3.2.2  rmind 	pq3pci_intr_class_t ih_class;
    190  1.3.2.2  rmind 	int (*ih_func)(void *);
    191  1.3.2.2  rmind 	void *ih_arg;
    192  1.3.2.2  rmind 	struct pq3pci_softc *ih_sc;
    193  1.3.2.2  rmind };
    194  1.3.2.2  rmind 
    195  1.3.2.2  rmind struct pq3pci_intrhand {
    196  1.3.2.2  rmind 	struct pq3pci_genihand pih_ih;
    197  1.3.2.2  rmind 	SIMPLEQ_ENTRY(pq3pci_intrhand) pih_link;
    198  1.3.2.2  rmind 	int pih_ipl;
    199  1.3.2.2  rmind 	struct pq3pci_intrsource *pih_source;
    200  1.3.2.2  rmind 	uint64_t pih_count;
    201  1.3.2.2  rmind };
    202  1.3.2.2  rmind 
    203  1.3.2.2  rmind struct pq3pci_callhand {
    204  1.3.2.2  rmind 	struct pq3pci_genihand pch_ih;
    205  1.3.2.2  rmind 	struct callout pch_callout;
    206  1.3.2.2  rmind 	int pch_ipl;
    207  1.3.2.2  rmind };
    208  1.3.2.2  rmind 
    209  1.3.2.2  rmind #define	PIH_MAKE(irq, ist, nmsi) (((nmsi) << 20) | ((irq) << 8) | (ist))
    210  1.3.2.2  rmind #define	PIH_IST(pih)		(((pih) >> 0) & 0xff)
    211  1.3.2.2  rmind #define	PIH_IRQ(pih)		(((pih) >> 8) & 0xfff)
    212  1.3.2.2  rmind #define	PIH_NMSI(pih)		(((pih) >> 20) & 0xff)
    213  1.3.2.2  rmind 
    214  1.3.2.2  rmind struct pq3pci_intrsource {
    215  1.3.2.2  rmind 	SIMPLEQ_ENTRY(pq3pci_intrsource) pis_link;
    216  1.3.2.2  rmind 	SIMPLEQ_HEAD(,pq3pci_intrhand) pis_ihands;
    217  1.3.2.2  rmind 	struct evcnt pis_ev;
    218  1.3.2.2  rmind 	struct evcnt pis_ev_spurious;
    219  1.3.2.2  rmind 	kmutex_t *pis_lock;
    220  1.3.2.2  rmind 	pci_intr_handle_t pis_handle;
    221  1.3.2.2  rmind 	void *pis_ih;
    222  1.3.2.2  rmind };
    223  1.3.2.2  rmind 
    224  1.3.2.2  rmind struct pq3pci_msihand {
    225  1.3.2.2  rmind 	struct pq3pci_genihand msih_ih;
    226  1.3.2.2  rmind 	struct pq3pci_msigroup *msih_group;
    227  1.3.2.2  rmind 	struct evcnt msih_ev;
    228  1.3.2.2  rmind 	struct evcnt msih_ev_spurious;
    229  1.3.2.2  rmind 	pcitag_t msih_tag;
    230  1.3.2.2  rmind 	int msih_msioff;
    231  1.3.2.2  rmind };
    232  1.3.2.2  rmind 
    233  1.3.2.2  rmind struct pq3pci_msigroup {
    234  1.3.2.2  rmind 	kmutex_t *msig_lock;
    235  1.3.2.2  rmind 	void *msig_ih;
    236  1.3.2.2  rmind 	uint32_t msig_free_mask;
    237  1.3.2.2  rmind 	int msig_ipl;
    238  1.3.2.2  rmind 	u_int msig_group;
    239  1.3.2.2  rmind 	bus_size_t msig_msir;
    240  1.3.2.2  rmind 	struct pq3pci_msihand msig_ihands[32];
    241  1.3.2.2  rmind };
    242  1.3.2.2  rmind 
    243  1.3.2.2  rmind struct pq3pci_softc {
    244  1.3.2.2  rmind 	device_t sc_dev;
    245  1.3.2.2  rmind 	bus_space_tag_t sc_bst;
    246  1.3.2.2  rmind 	bus_space_handle_t sc_bsh;
    247  1.3.2.2  rmind 	void *sc_ih;
    248  1.3.2.2  rmind 	bool sc_pcie;
    249  1.3.2.2  rmind 	struct genppc_pci_chipset sc_pc;
    250  1.3.2.2  rmind 	struct pq3pci_bst sc_pci_io_bst;
    251  1.3.2.2  rmind 	struct pq3pci_bst sc_pci_mem_bst;
    252  1.3.2.2  rmind 	u_int sc_pba_flags;
    253  1.3.2.2  rmind 	kmutex_t *sc_conf_lock;
    254  1.3.2.2  rmind 	kmutex_t *sc_intr_lock;
    255  1.3.2.2  rmind 	struct evcnt sc_ev_spurious;
    256  1.3.2.2  rmind 	prop_dictionary_t sc_intrmap;
    257  1.3.2.2  rmind 	uint32_t sc_intrmask;
    258  1.3.2.2  rmind };
    259  1.3.2.2  rmind 
    260  1.3.2.2  rmind static int pq3pci_cpunode_match(device_t, cfdata_t, void *aux);
    261  1.3.2.2  rmind static void pq3pci_cpunode_attach(device_t, device_t, void *aux);
    262  1.3.2.2  rmind static pci_chipset_tag_t pq3pci_pci_chipset_init(struct pq3pci_softc *);
    263  1.3.2.2  rmind 
    264  1.3.2.2  rmind static SIMPLEQ_HEAD(,pq3pci_intrsource) pq3pci_intrsources
    265  1.3.2.2  rmind     = SIMPLEQ_HEAD_INITIALIZER(pq3pci_intrsources);
    266  1.3.2.2  rmind static struct pq3pci_msigroup *pq3pci_msigroups[8];
    267  1.3.2.2  rmind 
    268  1.3.2.2  rmind static struct pq3pci_intrsource *
    269  1.3.2.2  rmind 	pq3pci_intr_source_lookup(struct pq3pci_softc *, pci_intr_handle_t);
    270  1.3.2.2  rmind 
    271  1.3.2.2  rmind static const char msi_intr_names[8][32][8] = {
    272  1.3.2.2  rmind     {
    273  1.3.2.2  rmind 	"msi 0",   "msi 1",   "msi 2",   "msi 3",
    274  1.3.2.2  rmind 	"msi 4",   "msi 5",   "msi 6",   "msi 7",
    275  1.3.2.2  rmind 	"msi 8",   "msi 9",   "msi 10",  "msi 11",
    276  1.3.2.2  rmind 	"msi 12",  "msi 13",  "msi 14",  "msi 15",
    277  1.3.2.2  rmind 	"msi 16",  "msi 17",  "msi 18",  "msi 19",
    278  1.3.2.2  rmind 	"msi 20",  "msi 21",  "msi 22",  "msi 23",
    279  1.3.2.2  rmind 	"msi 24",  "msi 25",  "msi 26",  "msi 27",
    280  1.3.2.2  rmind 	"msi 28",  "msi 29",  "msi 30",  "msi 31",
    281  1.3.2.2  rmind     }, {
    282  1.3.2.2  rmind 	"msi 32",  "msi 33",  "msi 34",  "msi 35",
    283  1.3.2.2  rmind 	"msi 36",  "msi 37",  "msi 38",  "msi 39",
    284  1.3.2.2  rmind 	"msi 40",  "msi 41",  "msi 42",  "msi 43",
    285  1.3.2.2  rmind 	"msi 44",  "msi 45",  "msi 46",  "msi 47",
    286  1.3.2.2  rmind 	"msi 48",  "msi 49",  "msi 50",  "msi 51",
    287  1.3.2.2  rmind 	"msi 52",  "msi 53",  "msi 54",  "msi 55",
    288  1.3.2.2  rmind 	"msi 56",  "msi 57",  "msi 58",  "msi 59",
    289  1.3.2.2  rmind 	"msi 60",  "msi 61",  "msi 62",  "msi 63",
    290  1.3.2.2  rmind     }, {
    291  1.3.2.2  rmind 	"msi 64",  "msi 65",  "msi 66",  "msi 67",
    292  1.3.2.2  rmind 	"msi 68",  "msi 69",  "msi 70",  "msi 71",
    293  1.3.2.2  rmind 	"msi 72",  "msi 73",  "msi 74",  "msi 75",
    294  1.3.2.2  rmind 	"msi 76",  "msi 77",  "msi 78",  "msi 79",
    295  1.3.2.2  rmind 	"msi 80",  "msi 81",  "msi 82",  "msi 83",
    296  1.3.2.2  rmind 	"msi 84",  "msi 85",  "msi 86",  "msi 87",
    297  1.3.2.2  rmind 	"msi 88",  "msi 89",  "msi 90",  "msi 91",
    298  1.3.2.2  rmind 	"msi 92",  "msi 93",  "msi 94",  "msi 95",
    299  1.3.2.2  rmind     }, {
    300  1.3.2.2  rmind 	"msi 96",  "msi 97",  "msi 98",  "msi 99",
    301  1.3.2.2  rmind 	"msi 100", "msi 101", "msi 102", "msi 103",
    302  1.3.2.2  rmind 	"msi 104", "msi 105", "msi 106", "msi 107",
    303  1.3.2.2  rmind 	"msi 108", "msi 109", "msi 110", "msi 111",
    304  1.3.2.2  rmind 	"msi 112", "msi 113", "msi 114", "msi 115",
    305  1.3.2.2  rmind 	"msi 116", "msi 117", "msi 118", "msi 119",
    306  1.3.2.2  rmind 	"msi 120", "msi 121", "msi 122", "msi 123",
    307  1.3.2.2  rmind 	"msi 124", "msi 125", "msi 126", "msi 127",
    308  1.3.2.2  rmind     }, {
    309  1.3.2.2  rmind 	"msi 128", "msi 129", "msi 130", "msi 131",
    310  1.3.2.2  rmind 	"msi 132", "msi 133", "msi 134", "msi 135",
    311  1.3.2.2  rmind 	"msi 136", "msi 137", "msi 138", "msi 139",
    312  1.3.2.2  rmind 	"msi 140", "msi 141", "msi 142", "msi 143",
    313  1.3.2.2  rmind 	"msi 144", "msi 145", "msi 146", "msi 147",
    314  1.3.2.2  rmind 	"msi 148", "msi 149", "msi 150", "msi 151",
    315  1.3.2.2  rmind 	"msi 152", "msi 153", "msi 154", "msi 155",
    316  1.3.2.2  rmind 	"msi 156", "msi 157", "msi 158", "msi 159",
    317  1.3.2.2  rmind     }, {
    318  1.3.2.2  rmind 	"msi 160", "msi 161", "msi 162", "msi 163",
    319  1.3.2.2  rmind 	"msi 164", "msi 165", "msi 166", "msi 167",
    320  1.3.2.2  rmind 	"msi 168", "msi 169", "msi 170", "msi 171",
    321  1.3.2.2  rmind 	"msi 172", "msi 173", "msi 174", "msi 175",
    322  1.3.2.2  rmind 	"msi 176", "msi 177", "msi 178", "msi 179",
    323  1.3.2.2  rmind 	"msi 180", "msi 181", "msi 182", "msi 183",
    324  1.3.2.2  rmind 	"msi 184", "msi 185", "msi 186", "msi 187",
    325  1.3.2.2  rmind 	"msi 188", "msi 189", "msi 190", "msi 191",
    326  1.3.2.2  rmind     }, {
    327  1.3.2.2  rmind 	"msi 192", "msi 193", "msi 194", "msi 195",
    328  1.3.2.2  rmind 	"msi 196", "msi 197", "msi 198", "msi 199",
    329  1.3.2.2  rmind 	"msi 200", "msi 201", "msi 202", "msi 203",
    330  1.3.2.2  rmind 	"msi 204", "msi 205", "msi 206", "msi 207",
    331  1.3.2.2  rmind 	"msi 208", "msi 209", "msi 210", "msi 211",
    332  1.3.2.2  rmind 	"msi 212", "msi 213", "msi 214", "msi 215",
    333  1.3.2.2  rmind 	"msi 216", "msi 217", "msi 218", "msi 219",
    334  1.3.2.2  rmind 	"msi 220", "msi 221", "msi 222", "msi 223",
    335  1.3.2.2  rmind     }, {
    336  1.3.2.2  rmind 	"msi 224", "msi 225", "msi 226", "msi 227",
    337  1.3.2.2  rmind 	"msi 228", "msi 229", "msi 230", "msi 231",
    338  1.3.2.2  rmind 	"msi 232", "msi 233", "msi 234", "msi 235",
    339  1.3.2.2  rmind 	"msi 236", "msi 237", "msi 238", "msi 239",
    340  1.3.2.2  rmind 	"msi 240", "msi 241", "msi 242", "msi 243",
    341  1.3.2.2  rmind 	"msi 244", "msi 245", "msi 246", "msi 247",
    342  1.3.2.2  rmind 	"msi 248", "msi 249", "msi 250", "msi 251",
    343  1.3.2.2  rmind 	"msi 252", "msi 253", "msi 254", "msi 255",
    344  1.3.2.2  rmind     },
    345  1.3.2.2  rmind };
    346  1.3.2.2  rmind 
    347  1.3.2.2  rmind CFATTACH_DECL_NEW(pq3pci_cpunode, sizeof(struct pq3pci_softc),
    348  1.3.2.2  rmind     pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
    349  1.3.2.2  rmind 
    350  1.3.2.2  rmind CFATTACH_DECL_NEW(pq3pcie_cpunode, sizeof(struct pq3pci_softc),
    351  1.3.2.2  rmind     pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL);
    352  1.3.2.2  rmind 
    353  1.3.2.2  rmind int
    354  1.3.2.2  rmind pq3pci_cpunode_match(device_t parent, cfdata_t cf, void *aux)
    355  1.3.2.2  rmind {
    356  1.3.2.2  rmind 
    357  1.3.2.2  rmind 	if (!e500_cpunode_submatch(parent, cf, cf->cf_name + 3, aux))
    358  1.3.2.2  rmind 		return 0;
    359  1.3.2.2  rmind 
    360  1.3.2.2  rmind 	return 1;
    361  1.3.2.2  rmind }
    362  1.3.2.2  rmind 
    363  1.3.2.2  rmind struct pq3pci_owin {
    364  1.3.2.2  rmind 	uint32_t potar;
    365  1.3.2.2  rmind 	uint32_t potear;
    366  1.3.2.2  rmind 	uint32_t powbar;
    367  1.3.2.2  rmind 	uint32_t powar;
    368  1.3.2.2  rmind };
    369  1.3.2.2  rmind 
    370  1.3.2.2  rmind static bool
    371  1.3.2.2  rmind pq3pci_owin_setup(struct pq3pci_softc *sc, u_int winnum,
    372  1.3.2.2  rmind 	const struct pq3pci_owin *owin)
    373  1.3.2.2  rmind {
    374  1.3.2.2  rmind 	const bool io_win = (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO;
    375  1.3.2.2  rmind 	struct pq3pci_bst *bs = io_win ? &sc->sc_pci_io_bst : &sc->sc_pci_mem_bst;
    376  1.3.2.2  rmind 	const uint64_t pci_base = ((uint64_t)owin->potar << 12)
    377  1.3.2.2  rmind 	    | ((uint64_t)owin->potear << (32+12));
    378  1.3.2.2  rmind 	const uint64_t local_base = (uint64_t)owin->powbar << 12;
    379  1.3.2.2  rmind 	const u_int win_size_log2 = PEXIWAR_IWS_GET(owin->powar) + 1;
    380  1.3.2.2  rmind 
    381  1.3.2.2  rmind 	bs->bs_tag.pbs_flags = _BUS_SPACE_LITTLE_ENDIAN
    382  1.3.2.2  rmind 	    | (io_win ? _BUS_SPACE_IO_TYPE : _BUS_SPACE_MEM_TYPE);
    383  1.3.2.2  rmind 	bs->bs_tag.pbs_base = pci_base;
    384  1.3.2.2  rmind 	bs->bs_tag.pbs_offset = local_base - pci_base;
    385  1.3.2.2  rmind 	bs->bs_tag.pbs_limit = bs->bs_tag.pbs_base + (1ULL << win_size_log2);
    386  1.3.2.2  rmind 
    387  1.3.2.2  rmind #if 0
    388  1.3.2.2  rmind 	const char units[] = " KMGTP";
    389  1.3.2.2  rmind 	aprint_normal_dev(sc->sc_dev,
    390  1.3.2.2  rmind 	     "outbound window %u: potar=%#x, potear=%#x, powbar=%x, powar=%#x\n",
    391  1.3.2.2  rmind 	     winnum, owin->potar, owin->potear, owin->powbar, owin->powar);
    392  1.3.2.2  rmind 	aprint_normal_dev(sc->sc_dev,
    393  1.3.2.2  rmind 	    "outbound window %u: maps %u%cB of PCI %s space @ %#"PRIx64" onto local addresses @ %#"PRIx64".\n",
    394  1.3.2.2  rmind 	    winnum, 1 << (win_size_log2 % 10), units[win_size_log2 / 10],
    395  1.3.2.2  rmind 	    (owin->powar & PEXOWAR_RTT) == PEXOWAR_RTT_IO ? "I/O" : "memory",
    396  1.3.2.2  rmind 	    local_base, pci_base);
    397  1.3.2.2  rmind #endif
    398  1.3.2.2  rmind 
    399  1.3.2.2  rmind 	snprintf(bs->bs_name, sizeof(bs->bs_name), "%s-%s@%u",
    400  1.3.2.2  rmind 	    device_xname(sc->sc_dev), io_win ? "io" : "mem", winnum);
    401  1.3.2.2  rmind 
    402  1.3.2.2  rmind #if 0
    403  1.3.2.2  rmind 	printf("%s: %s: base=%#x offset=%#x limit=%#x\n", __func__, bs->bs_name,
    404  1.3.2.2  rmind 	    bs->bs_tag.pbs_base, bs->bs_tag.pbs_offset, bs->bs_tag.pbs_limit);
    405  1.3.2.2  rmind #endif
    406  1.3.2.2  rmind 
    407  1.3.2.2  rmind 	int error = bus_space_init(&bs->bs_tag, bs->bs_name,
    408  1.3.2.2  rmind 	    bs->bs_ex_storage, sizeof(bs->bs_ex_storage));
    409  1.3.2.2  rmind 	if (error) {
    410  1.3.2.2  rmind 		aprint_error(": failed to create %s bus space: %d\n",
    411  1.3.2.2  rmind 		    bs->bs_name, error);
    412  1.3.2.2  rmind 		return false;
    413  1.3.2.2  rmind 	}
    414  1.3.2.2  rmind 	aprint_debug_dev(sc->sc_dev, "bus space %s created\n", bs->bs_name);
    415  1.3.2.2  rmind 	sc->sc_pba_flags |=
    416  1.3.2.2  rmind 	    io_win ? PCI_FLAGS_IO_ENABLED : PCI_FLAGS_MEM_ENABLED;
    417  1.3.2.2  rmind 	return true;
    418  1.3.2.2  rmind }
    419  1.3.2.2  rmind 
    420  1.3.2.2  rmind struct pq3pci_iwin {
    421  1.3.2.2  rmind 	uint32_t pitar;
    422  1.3.2.2  rmind 	uint32_t piwbar;
    423  1.3.2.2  rmind 	uint32_t piwbear;
    424  1.3.2.2  rmind 	uint32_t piwar;
    425  1.3.2.2  rmind };
    426  1.3.2.2  rmind 
    427  1.3.2.2  rmind static bool
    428  1.3.2.2  rmind pq3pci_iwin_setup(struct pq3pci_softc *sc, u_int winnum,
    429  1.3.2.2  rmind 	const struct pq3pci_iwin *iwin)
    430  1.3.2.2  rmind {
    431  1.3.2.2  rmind 	const uint64_t pci_base = ((uint64_t)iwin->piwbar << 12)
    432  1.3.2.2  rmind 	    | ((uint64_t)iwin->piwbear << (32+12));
    433  1.3.2.2  rmind 	const uint64_t local_base = (uint64_t)iwin->pitar << 12;
    434  1.3.2.2  rmind 	const u_int win_size_log2 = PEXIWAR_IWS_GET(iwin->piwar) + 1;
    435  1.3.2.2  rmind #if DEBUG > 1
    436  1.3.2.2  rmind 	const char units[] = " KMGTP";
    437  1.3.2.2  rmind 	aprint_normal_dev(sc->sc_dev,
    438  1.3.2.2  rmind 	    "inbound window %u: pitar=%#x, piwbar=%x, piwbear=%#x, piwar=%#x\n",
    439  1.3.2.2  rmind 	    winnum, iwin->pitar, iwin->piwbar, iwin->piwbear, iwin->piwar);
    440  1.3.2.2  rmind 	aprint_normal_dev(sc->sc_dev,
    441  1.3.2.2  rmind 	    "inbound window %u: maps %u%cB of PCI address space @ %#"PRIx64" to local memory @ %#"PRIx64".\n",
    442  1.3.2.2  rmind 	    winnum, 1 << (win_size_log2 % 10), units[win_size_log2 / 10],
    443  1.3.2.2  rmind 	    pci_base, local_base);
    444  1.3.2.2  rmind #endif /* DEBUG */
    445  1.3.2.2  rmind 	/*
    446  1.3.2.2  rmind 	 * Let's make sure this window is usable.
    447  1.3.2.2  rmind 	 */
    448  1.3.2.2  rmind 	if (pci_base != 0) {
    449  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    450  1.3.2.2  rmind 		    "PCI base (%#"PRIx64" != 0\n", pci_base);
    451  1.3.2.2  rmind 		return false;
    452  1.3.2.2  rmind 	}
    453  1.3.2.2  rmind 	if (local_base != 0) {
    454  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    455  1.3.2.2  rmind 		    "local base (%#"PRIx64" != 0\n", local_base);
    456  1.3.2.2  rmind 		return false;
    457  1.3.2.2  rmind 	}
    458  1.3.2.2  rmind 	if ((iwin->piwar & PEXIWAR_RTT) != PEXIWAR_RTT_MEM_SNOOP) {
    459  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    460  1.3.2.2  rmind 		    "unsupported read transaction type (%#"PRIxMAX")\n",
    461  1.3.2.2  rmind 		    iwin->piwar & PEXIWAR_RTT);
    462  1.3.2.2  rmind 		return false;
    463  1.3.2.2  rmind 	}
    464  1.3.2.2  rmind 	if ((iwin->piwar & PEXIWAR_WTT) != PEXIWAR_WTT_MEM_SNOOP) {
    465  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    466  1.3.2.2  rmind 		    "unsupported write transaction type (%#"PRIxMAX")\n",
    467  1.3.2.2  rmind 		    iwin->piwar & PEXIWAR_WTT);
    468  1.3.2.2  rmind 		return false;
    469  1.3.2.2  rmind 	}
    470  1.3.2.2  rmind 	if ((iwin->piwar & PEXIWAR_TRGT) != PEXIWAR_TRGT_LOCALMEM) {
    471  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    472  1.3.2.2  rmind 		    "unsupported target (%#"PRIxMAX")\n",
    473  1.3.2.2  rmind 		    iwin->piwar & PEXIWAR_TRGT);
    474  1.3.2.2  rmind 		return false;
    475  1.3.2.2  rmind 	}
    476  1.3.2.2  rmind 	if (board_info_get_number("mem-size") > (1ULL << win_size_log2)) {
    477  1.3.2.2  rmind 		aprint_error(": invalid inbound window: "
    478  1.3.2.2  rmind 		    "doesn't map all of memory (%#"PRIx64" < %#"PRIx64")\n",
    479  1.3.2.2  rmind 		    1ULL << win_size_log2, board_info_get_number("mem-size"));
    480  1.3.2.2  rmind 		return false;
    481  1.3.2.2  rmind 	}
    482  1.3.2.2  rmind 	return true;
    483  1.3.2.2  rmind }
    484  1.3.2.2  rmind 
    485  1.3.2.2  rmind static void
    486  1.3.2.2  rmind pq3pci_pch_callout(void *v)
    487  1.3.2.2  rmind {
    488  1.3.2.2  rmind 	struct pq3pci_callhand * const pch = v;
    489  1.3.2.2  rmind 
    490  1.3.2.2  rmind 	int s = splraise(pch->pch_ipl);
    491  1.3.2.2  rmind 	(*pch->pch_ih.ih_func)(pch->pch_ih.ih_arg);
    492  1.3.2.2  rmind 	splx(s);
    493  1.3.2.2  rmind 	callout_schedule(&pch->pch_callout, 1);
    494  1.3.2.2  rmind }
    495  1.3.2.2  rmind 
    496  1.3.2.2  rmind static int
    497  1.3.2.2  rmind pq3pci_msi_spurious_intr(void *v)
    498  1.3.2.2  rmind {
    499  1.3.2.2  rmind 	(void) v;
    500  1.3.2.2  rmind 
    501  1.3.2.2  rmind 	return 0;
    502  1.3.2.2  rmind }
    503  1.3.2.2  rmind 
    504  1.3.2.2  rmind static int
    505  1.3.2.2  rmind pq3pci_msi_intr(void *v)
    506  1.3.2.2  rmind {
    507  1.3.2.2  rmind 	struct pq3pci_msigroup * const msig = v;
    508  1.3.2.2  rmind 
    509  1.3.2.2  rmind 	mutex_spin_enter(msig->msig_lock);
    510  1.3.2.2  rmind 	KASSERT(curcpu()->ci_cpl == msig->msig_ipl);
    511  1.3.2.2  rmind 	//KASSERT(curcpu()->ci_idepth == 0);
    512  1.3.2.2  rmind 	for (int rv = 0;;) {
    513  1.3.2.2  rmind 		uint32_t group = cpu_read_4(msig->msig_msir);
    514  1.3.2.2  rmind 		if (group == 0) {
    515  1.3.2.2  rmind 			mutex_spin_exit(msig->msig_lock);
    516  1.3.2.2  rmind 			return rv;
    517  1.3.2.2  rmind 		}
    518  1.3.2.2  rmind 
    519  1.3.2.2  rmind 		const bool working_msi_p =
    520  1.3.2.2  rmind 		    msig->msig_group != 0 || (group & 1) == 0;
    521  1.3.2.2  rmind 		if (working_msi_p) {
    522  1.3.2.2  rmind 			/*
    523  1.3.2.2  rmind 			 * if MSIs are working, just clear the free MSIs.
    524  1.3.2.2  rmind 			 */
    525  1.3.2.2  rmind 			group &= ~msig->msig_free_mask;
    526  1.3.2.2  rmind 		} else {
    527  1.3.2.2  rmind 			/*
    528  1.3.2.2  rmind 			 * If MSIs are broken, we don't really what MSIs
    529  1.3.2.2  rmind 			 * have happened.
    530  1.3.2.2  rmind 			 */
    531  1.3.2.2  rmind 			for (struct pq3pci_msihand *msih = msig->msig_ihands + 31;
    532  1.3.2.2  rmind 			     group != 0;
    533  1.3.2.2  rmind 			     msih--) {
    534  1.3.2.2  rmind 				const u_int n = __builtin_clz(group);
    535  1.3.2.2  rmind 				msih -= n;
    536  1.3.2.2  rmind 				group <<= n + 1;
    537  1.3.2.2  rmind 				msih->msih_ev.ev_count++;
    538  1.3.2.2  rmind 			}
    539  1.3.2.2  rmind 			group = ~msig->msig_free_mask;
    540  1.3.2.2  rmind 		}
    541  1.3.2.2  rmind 		for (struct pq3pci_msihand *msih = msig->msig_ihands + 31;
    542  1.3.2.2  rmind 		     group != 0;
    543  1.3.2.2  rmind 		     msih--) {
    544  1.3.2.2  rmind 			KASSERT(msig->msig_ihands <= msih);
    545  1.3.2.2  rmind 			KASSERT(msih < &msig->msig_ihands[32]);
    546  1.3.2.2  rmind 			const u_int n = __builtin_clz(group);
    547  1.3.2.2  rmind 			msih -= n;
    548  1.3.2.2  rmind 			group <<= n + 1;
    549  1.3.2.2  rmind 			msih->msih_ev.ev_count += working_msi_p;
    550  1.3.2.2  rmind 			if ((*msih->msih_ih.ih_func)(msih->msih_ih.ih_arg)) {
    551  1.3.2.2  rmind 				rv = 1;
    552  1.3.2.2  rmind 				msih->msih_ev.ev_count += !working_msi_p;
    553  1.3.2.2  rmind 			} else {
    554  1.3.2.2  rmind 				msih->msih_ev_spurious.ev_count += working_msi_p;
    555  1.3.2.2  rmind 			}
    556  1.3.2.2  rmind 		}
    557  1.3.2.2  rmind 	}
    558  1.3.2.2  rmind }
    559  1.3.2.2  rmind 
    560  1.3.2.2  rmind static int
    561  1.3.2.2  rmind pq3pci_onchip_intr(void *v)
    562  1.3.2.2  rmind {
    563  1.3.2.2  rmind 	panic(__func__);
    564  1.3.2.2  rmind }
    565  1.3.2.2  rmind 
    566  1.3.2.2  rmind static int
    567  1.3.2.2  rmind pq3pci_pis_intr(void *v)
    568  1.3.2.2  rmind {
    569  1.3.2.2  rmind 	struct pq3pci_intrsource * const pis = v;
    570  1.3.2.2  rmind 	struct pq3pci_intrhand *pih;
    571  1.3.2.2  rmind 	int rv = 0;
    572  1.3.2.2  rmind 
    573  1.3.2.2  rmind 	mutex_spin_enter(pis->pis_lock);
    574  1.3.2.2  rmind 	pis->pis_ev.ev_count++;
    575  1.3.2.2  rmind 	SIMPLEQ_FOREACH(pih, &pis->pis_ihands, pih_link) {
    576  1.3.2.2  rmind 		struct pq3pci_softc * const sc = pih->pih_ih.ih_sc;
    577  1.3.2.2  rmind 		int s = splraise(pih->pih_ipl);
    578  1.3.2.2  rmind 		pih->pih_count++;
    579  1.3.2.2  rmind 		rv = (*pih->pih_ih.ih_func)(pih->pih_ih.ih_arg);
    580  1.3.2.2  rmind 		splx(s);
    581  1.3.2.2  rmind #if 0
    582  1.3.2.2  rmind 		printf("%s %d:%s %"PRIu64": %p(%p) %"PRIu64": %d\n", __func__,
    583  1.3.2.2  rmind 		    curcpu()->ci_idepth,
    584  1.3.2.2  rmind 		    pis->pis_ev.ev_group, pis->pis_ev.ev_count,
    585  1.3.2.2  rmind 		    pih->pih_ih.ih_func, pih->pih_ih.ih_arg, pih->pih_count, rv);
    586  1.3.2.2  rmind #endif
    587  1.3.2.2  rmind 		if (rv != 0) {
    588  1.3.2.2  rmind 			bus_space_read_4(sc->sc_bst, sc->sc_bsh, PCI_INT_ACK);
    589  1.3.2.2  rmind 			break;
    590  1.3.2.2  rmind 		}
    591  1.3.2.2  rmind 		pih->pih_count--;
    592  1.3.2.2  rmind 	}
    593  1.3.2.2  rmind 	if (rv == 0)
    594  1.3.2.2  rmind 		pis->pis_ev_spurious.ev_count++;
    595  1.3.2.2  rmind 	mutex_spin_exit(pis->pis_lock);
    596  1.3.2.2  rmind 	return rv;
    597  1.3.2.2  rmind }
    598  1.3.2.2  rmind 
    599  1.3.2.2  rmind static void
    600  1.3.2.2  rmind pq3pci_intr_source_setup(struct pq3pci_softc *sc,
    601  1.3.2.2  rmind 	struct pq3pci_intrsource *pis, pci_intr_handle_t handle)
    602  1.3.2.2  rmind {
    603  1.3.2.2  rmind 	SIMPLEQ_INIT(&pis->pis_ihands);
    604  1.3.2.2  rmind 	pis->pis_handle = handle;
    605  1.3.2.2  rmind 	pis->pis_ih = intr_establish(PIH_IRQ(handle), IPL_VM, PIH_IST(handle),
    606  1.3.2.2  rmind 	    pq3pci_pis_intr, pis);
    607  1.3.2.2  rmind 	pis->pis_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
    608  1.3.2.2  rmind 	const char * const intrstr
    609  1.3.2.2  rmind 	    = intr_string(PIH_IRQ(handle), PIH_IST(handle));
    610  1.3.2.2  rmind 	evcnt_attach_dynamic(&pis->pis_ev, EVCNT_TYPE_INTR,
    611  1.3.2.2  rmind 	    NULL, intrstr, "intr");
    612  1.3.2.2  rmind 	evcnt_attach_dynamic(&pis->pis_ev_spurious, EVCNT_TYPE_INTR,
    613  1.3.2.2  rmind 	    &pis->pis_ev, intrstr, "spurious intr");
    614  1.3.2.2  rmind 	SIMPLEQ_INSERT_TAIL(&pq3pci_intrsources, pis, pis_link);
    615  1.3.2.2  rmind }
    616  1.3.2.2  rmind 
    617  1.3.2.2  rmind static bool
    618  1.3.2.2  rmind pq3pci_intrmap_setup(struct pq3pci_softc *sc,
    619  1.3.2.2  rmind 	const struct cpunode_locators *cnl)
    620  1.3.2.2  rmind {
    621  1.3.2.2  rmind 	char prop_name[32];
    622  1.3.2.2  rmind 	snprintf(prop_name, sizeof(prop_name), "%s%u-interrupt-map",
    623  1.3.2.2  rmind 	    cnl->cnl_name, cnl->cnl_instance);
    624  1.3.2.2  rmind 	sc->sc_intrmap = board_info_get_object(prop_name);
    625  1.3.2.2  rmind 	if (sc->sc_intrmap == NULL) {
    626  1.3.2.2  rmind 		aprint_error(": missing %s board property", prop_name);
    627  1.3.2.2  rmind 		return false;
    628  1.3.2.2  rmind 	}
    629  1.3.2.2  rmind 
    630  1.3.2.2  rmind 	KASSERT(prop_object_type(sc->sc_intrmap) == PROP_TYPE_DICTIONARY);
    631  1.3.2.2  rmind 	prop_number_t pn = prop_dictionary_get(sc->sc_intrmap, "interrupt-mask");
    632  1.3.2.2  rmind 	KASSERT(pn != NULL);
    633  1.3.2.2  rmind 
    634  1.3.2.2  rmind 	sc->sc_intrmask = prop_number_unsigned_integer_value(pn);
    635  1.3.2.2  rmind 
    636  1.3.2.2  rmind 	sc->sc_ih = intr_establish(cnl->cnl_intrs[0], IPL_VM, IST_ONCHIP,
    637  1.3.2.2  rmind 	    pq3pci_onchip_intr, sc);
    638  1.3.2.2  rmind 	if (sc->sc_ih == NULL)
    639  1.3.2.2  rmind 		panic("%s: failed to establish interrupt %d\n",
    640  1.3.2.2  rmind 		    device_xname(sc->sc_dev), cnl->cnl_intrs[0]);
    641  1.3.2.2  rmind 
    642  1.3.2.2  rmind 	return true;
    643  1.3.2.2  rmind }
    644  1.3.2.2  rmind 
    645  1.3.2.2  rmind void
    646  1.3.2.2  rmind pq3pci_cpunode_attach(device_t parent, device_t self, void *aux)
    647  1.3.2.2  rmind {
    648  1.3.2.2  rmind 	struct cpunode_softc * const psc = device_private(parent);
    649  1.3.2.2  rmind 	struct pq3pci_softc * const sc = device_private(self);
    650  1.3.2.2  rmind 	struct cpunode_attach_args * const cna = aux;
    651  1.3.2.2  rmind 	struct cpunode_locators * const cnl = &cna->cna_locs;
    652  1.3.2.2  rmind 	char buf[32];
    653  1.3.2.2  rmind 
    654  1.3.2.2  rmind 	sc->sc_dev = self;
    655  1.3.2.2  rmind 	sc->sc_bst = cna->cna_memt;
    656  1.3.2.2  rmind 	psc->sc_children |= cna->cna_childmask;
    657  1.3.2.2  rmind 	sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0;
    658  1.3.2.2  rmind 
    659  1.3.2.2  rmind 	const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR);
    660  1.3.2.2  rmind 	if (sc->sc_pcie) {
    661  1.3.2.2  rmind 		u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr,
    662  1.3.2.2  rmind 		    pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0);
    663  1.3.2.2  rmind 		if (lanes == 0) {
    664  1.3.2.2  rmind 			aprint_normal(": disabled\n");
    665  1.3.2.2  rmind 			return;
    666  1.3.2.2  rmind 		}
    667  1.3.2.2  rmind 		snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes);
    668  1.3.2.2  rmind 	} else {
    669  1.3.2.2  rmind 		bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr,
    670  1.3.2.2  rmind 		    pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0);
    671  1.3.2.2  rmind 		u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr,
    672  1.3.2.2  rmind 		    pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32);
    673  1.3.2.2  rmind 		snprintf(buf, sizeof(buf), "%u-bit PCI%s",
    674  1.3.2.2  rmind 		    width, (pcix_p ? "X" : ""));
    675  1.3.2.2  rmind 	}
    676  1.3.2.2  rmind 
    677  1.3.2.2  rmind 	if (!pq3pci_intrmap_setup(sc, cnl))
    678  1.3.2.2  rmind 		return;
    679  1.3.2.2  rmind 
    680  1.3.2.2  rmind 	evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL,
    681  1.3.2.2  rmind 	    device_xname(self), "spurious intr");
    682  1.3.2.2  rmind 
    683  1.3.2.2  rmind 	int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0,
    684  1.3.2.2  rmind 	    &sc->sc_bsh);
    685  1.3.2.2  rmind 	if (error) {
    686  1.3.2.2  rmind 		aprint_error(": failed to map registers: %d\n", error);
    687  1.3.2.2  rmind 		return;
    688  1.3.2.2  rmind 	}
    689  1.3.2.2  rmind 
    690  1.3.2.2  rmind 	u_int valid_owins = 0;
    691  1.3.2.2  rmind 	for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0;
    692  1.3.2.2  rmind 	     i < 4; i++, off += PEXOTAR1 - PEXOTAR0) {
    693  1.3.2.2  rmind 		struct pq3pci_owin owin;
    694  1.3.2.2  rmind 		owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    695  1.3.2.2  rmind 		    PEXOTAR0 + off);
    696  1.3.2.2  rmind 		owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    697  1.3.2.2  rmind 		    PEXOTEAR0 + off);
    698  1.3.2.2  rmind 		owin.powbar = 0;
    699  1.3.2.2  rmind 		if (i > 0) {
    700  1.3.2.2  rmind 			/* Doesn't exist for outbound window 0 */
    701  1.3.2.2  rmind 			owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    702  1.3.2.2  rmind 			    PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off);
    703  1.3.2.2  rmind 		}
    704  1.3.2.2  rmind 		owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    705  1.3.2.2  rmind 		    PEXOWAR0 + off);
    706  1.3.2.2  rmind #if 0
    707  1.3.2.2  rmind 		aprint_normal_dev(self,
    708  1.3.2.2  rmind 		    "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n",
    709  1.3.2.2  rmind 		    i, owin.potar, owin.potear, owin.powbar, owin.powar);
    710  1.3.2.2  rmind #endif
    711  1.3.2.2  rmind 		if (owin.powar & PEXOWAR_EN) {
    712  1.3.2.2  rmind 			valid_owins++;
    713  1.3.2.2  rmind 			if (!pq3pci_owin_setup(sc, i, &owin))
    714  1.3.2.2  rmind 				return;
    715  1.3.2.2  rmind 		}
    716  1.3.2.2  rmind 	}
    717  1.3.2.2  rmind #ifndef PCI_NETBSD_CONFIGURE
    718  1.3.2.2  rmind 	if (valid_owins == 0) {
    719  1.3.2.2  rmind 		aprint_normal(": %s controller%s\n", buf,
    720  1.3.2.2  rmind 		    " (disabled)");
    721  1.3.2.2  rmind 		return;
    722  1.3.2.2  rmind 	}
    723  1.3.2.2  rmind #endif
    724  1.3.2.2  rmind 
    725  1.3.2.2  rmind 	u_int valid_iwins = 0;
    726  1.3.2.2  rmind 	for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) {
    727  1.3.2.2  rmind 		struct pq3pci_iwin iwin;
    728  1.3.2.2  rmind 		iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    729  1.3.2.2  rmind 		    PEXITAR1 + off);
    730  1.3.2.2  rmind 		iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    731  1.3.2.2  rmind 		    PEXIWBAR1 + off);
    732  1.3.2.2  rmind 		if (i > 0) {
    733  1.3.2.2  rmind 			/* Doesn't exist */
    734  1.3.2.2  rmind 			iwin.piwbear = bus_space_read_4(sc->sc_bst,
    735  1.3.2.2  rmind 			    sc->sc_bsh,
    736  1.3.2.2  rmind 			    PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off);
    737  1.3.2.2  rmind 		} else {
    738  1.3.2.2  rmind 			iwin.piwbear = 0;
    739  1.3.2.2  rmind 		}
    740  1.3.2.2  rmind 		iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh,
    741  1.3.2.2  rmind 		    PEXIWAR1 + off);
    742  1.3.2.2  rmind #if 0
    743  1.3.2.2  rmind 		aprint_normal_dev(self,
    744  1.3.2.2  rmind 		    "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n",
    745  1.3.2.2  rmind 		    i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar);
    746  1.3.2.2  rmind #endif
    747  1.3.2.2  rmind 		if (iwin.piwar & PEXIWAR_EN) {
    748  1.3.2.2  rmind 			valid_iwins++;
    749  1.3.2.2  rmind 			if (!pq3pci_iwin_setup(sc, i, &iwin))
    750  1.3.2.2  rmind 				return;
    751  1.3.2.2  rmind 		}
    752  1.3.2.2  rmind 	}
    753  1.3.2.2  rmind 
    754  1.3.2.2  rmind 	sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM);
    755  1.3.2.2  rmind 
    756  1.3.2.2  rmind 	pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc);
    757  1.3.2.2  rmind 
    758  1.3.2.2  rmind #ifndef PCI_NETBSD_CONFIGURE
    759  1.3.2.2  rmind 	if (valid_iwins == 0) {
    760  1.3.2.2  rmind 		aprint_normal(": %s controller%s\n", buf,
    761  1.3.2.2  rmind 		    " (disabled)");
    762  1.3.2.2  rmind 		return;
    763  1.3.2.2  rmind 	}
    764  1.3.2.2  rmind #else
    765  1.3.2.2  rmind 	if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) {
    766  1.3.2.2  rmind 		aprint_normal(": %s controller%s\n", buf,
    767  1.3.2.2  rmind 		    " (offline)");
    768  1.3.2.2  rmind 		return;
    769  1.3.2.2  rmind 	}
    770  1.3.2.2  rmind 	if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) {
    771  1.3.2.2  rmind 		aprint_normal(": %s controller%s\n", buf,
    772  1.3.2.2  rmind 		    " (agent mode)");
    773  1.3.2.2  rmind 		return;
    774  1.3.2.2  rmind 	}
    775  1.3.2.2  rmind 	if (valid_iwins == 0) {
    776  1.3.2.2  rmind 		struct pq3pci_iwin iwin = {
    777  1.3.2.2  rmind 		    .pitar = 0,
    778  1.3.2.2  rmind 		    .piwbar = 0,
    779  1.3.2.2  rmind 		    .piwbear = 0,
    780  1.3.2.2  rmind 		    .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM
    781  1.3.2.2  rmind 			|PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP
    782  1.3.2.2  rmind 			|__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS),
    783  1.3.2.2  rmind 		};
    784  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar);
    785  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar);
    786  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear);
    787  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar);
    788  1.3.2.2  rmind 
    789  1.3.2.2  rmind 		if (!pq3pci_iwin_setup(sc, 2, &iwin)) {
    790  1.3.2.2  rmind 			aprint_error(": error creating inbound window\n");
    791  1.3.2.2  rmind 			return;
    792  1.3.2.2  rmind 		}
    793  1.3.2.2  rmind 
    794  1.3.2.2  rmind 	}
    795  1.3.2.2  rmind 
    796  1.3.2.2  rmind 	if (valid_owins == 0) {
    797  1.3.2.2  rmind 		u_long membase, iobase;
    798  1.3.2.2  rmind 		error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE,
    799  1.3.2.2  rmind 		   PCI_MEMSIZE, EX_WAITOK, &membase);
    800  1.3.2.2  rmind 		if (error) {
    801  1.3.2.2  rmind 			aprint_error(
    802  1.3.2.2  rmind 			    ": error allocating address space for %s: %d\n",
    803  1.3.2.2  rmind 			    "PCI memory", error);
    804  1.3.2.2  rmind 			return;
    805  1.3.2.2  rmind 		}
    806  1.3.2.2  rmind 		struct pq3pci_owin owin1 = {
    807  1.3.2.2  rmind 		    .potar = membase >> 12,
    808  1.3.2.2  rmind 		    .potear = 0,
    809  1.3.2.2  rmind 		    .powbar = membase >> 12,
    810  1.3.2.2  rmind 		    .powar = PEXOWAR_EN|PEXOWAR_TC0
    811  1.3.2.2  rmind 			|PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM
    812  1.3.2.2  rmind 			|__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS),
    813  1.3.2.2  rmind 		};
    814  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar);
    815  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear);
    816  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar);
    817  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar);
    818  1.3.2.2  rmind 		if (!pq3pci_owin_setup(sc, 1, &owin1)) {
    819  1.3.2.2  rmind 			aprint_error(
    820  1.3.2.2  rmind 			    ": error creating bus space for %s\n",
    821  1.3.2.2  rmind 			    "PCI memory");
    822  1.3.2.2  rmind 			return;
    823  1.3.2.2  rmind 		}
    824  1.3.2.2  rmind 
    825  1.3.2.2  rmind 		error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE,
    826  1.3.2.2  rmind 		   PCI_IOSIZE, EX_WAITOK, &iobase);
    827  1.3.2.2  rmind 		if (error) {
    828  1.3.2.2  rmind 			aprint_error(
    829  1.3.2.2  rmind 			    ": error allocating address space for %s: %d\n",
    830  1.3.2.2  rmind 			    "PCI I/O space", error);
    831  1.3.2.2  rmind 			return;
    832  1.3.2.2  rmind 		}
    833  1.3.2.2  rmind 		struct pq3pci_owin owin2 = {
    834  1.3.2.2  rmind 		    .potar = 0,
    835  1.3.2.2  rmind 		    .potear = 0,
    836  1.3.2.2  rmind 		    .powbar = iobase >> 12,
    837  1.3.2.2  rmind 		    .powar = PEXOWAR_EN|PEXOWAR_TC0
    838  1.3.2.2  rmind 			|PEXOWAR_RTT_IO|PEXOWAR_WTT_IO
    839  1.3.2.2  rmind 			|__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS),
    840  1.3.2.2  rmind 		};
    841  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar);
    842  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear);
    843  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar);
    844  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar);
    845  1.3.2.2  rmind 		if (!pq3pci_owin_setup(sc, 2, &owin2)) {
    846  1.3.2.2  rmind 			aprint_error(
    847  1.3.2.2  rmind 			    ": error creating bus space for %s\n",
    848  1.3.2.2  rmind 			    "PCI I/O space");
    849  1.3.2.2  rmind 			return;
    850  1.3.2.2  rmind 		}
    851  1.3.2.2  rmind 
    852  1.3.2.2  rmind 		struct extent *ioext = extent_create("pciio", 0, PCI_IOSIZE,
    853  1.3.2.2  rmind 		     M_DEVBUF, NULL, 0, EX_NOWAIT);
    854  1.3.2.2  rmind 		struct extent *memext = extent_create("pcimem", membase,
    855  1.3.2.2  rmind 		     membase + PCI_MEMSIZE, M_DEVBUF, NULL, 0, EX_NOWAIT);
    856  1.3.2.2  rmind 
    857  1.3.2.2  rmind 		error = pci_configure_bus(pc, ioext, memext, NULL, 0,
    858  1.3.2.2  rmind 		    curcpu()->ci_ci.dcache_line_size);
    859  1.3.2.2  rmind 
    860  1.3.2.2  rmind 		extent_destroy(ioext);
    861  1.3.2.2  rmind 		extent_destroy(memext);
    862  1.3.2.2  rmind 
    863  1.3.2.2  rmind 		if (error) {
    864  1.3.2.2  rmind 			aprint_normal(": configuration failed\n");
    865  1.3.2.2  rmind 			return;
    866  1.3.2.2  rmind 		}
    867  1.3.2.2  rmind 	}
    868  1.3.2.2  rmind #endif
    869  1.3.2.2  rmind 
    870  1.3.2.2  rmind 	aprint_normal(": %s controller%s\n", buf, "");
    871  1.3.2.2  rmind 
    872  1.3.2.2  rmind 	struct pcibus_attach_args pba;
    873  1.3.2.2  rmind 	memset(&pba, 0, sizeof(pba));
    874  1.3.2.2  rmind 
    875  1.3.2.2  rmind 	pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY
    876  1.3.2.2  rmind 	    | PCI_FLAGS_MSIX_OKAY;
    877  1.3.2.2  rmind 	if (pba.pba_flags & PCI_FLAGS_IO_ENABLED)
    878  1.3.2.2  rmind 		pba.pba_iot = pc->pc_iot;
    879  1.3.2.2  rmind 	if (pba.pba_flags & PCI_FLAGS_MEM_ENABLED)
    880  1.3.2.2  rmind 		pba.pba_memt = pc->pc_memt;
    881  1.3.2.2  rmind 	pba.pba_dmat = cna->cna_dmat;
    882  1.3.2.2  rmind 	pba.pba_pc = pc;
    883  1.3.2.2  rmind 	pba.pba_bus = 0;
    884  1.3.2.2  rmind 
    885  1.3.2.2  rmind 	/*
    886  1.3.2.2  rmind 	 * Program BAR0 so that MSIs can work.
    887  1.3.2.2  rmind 	 */
    888  1.3.2.2  rmind 	pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset);
    889  1.3.2.2  rmind 	pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG);
    890  1.3.2.2  rmind 	cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
    891  1.3.2.2  rmind 	pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts);
    892  1.3.2.2  rmind 
    893  1.3.2.2  rmind #if 0
    894  1.3.2.2  rmind 	/*
    895  1.3.2.2  rmind 	 *
    896  1.3.2.2  rmind 	 */
    897  1.3.2.2  rmind 	pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0));
    898  1.3.2.2  rmind #endif
    899  1.3.2.2  rmind #if 0
    900  1.3.2.2  rmind 	if (sc->sc_pcie)
    901  1.3.2.2  rmind 		pci_conf_print(pc, 0, NULL);
    902  1.3.2.2  rmind #endif
    903  1.3.2.2  rmind 
    904  1.3.2.2  rmind 	config_found_ia(self, "pcibus", &pba, pcibusprint);
    905  1.3.2.2  rmind }
    906  1.3.2.2  rmind 
    907  1.3.2.2  rmind static void
    908  1.3.2.2  rmind pq3pci_attach_hook(device_t parent, device_t self,
    909  1.3.2.2  rmind 	struct pcibus_attach_args *pba)
    910  1.3.2.2  rmind {
    911  1.3.2.2  rmind 	/* do nothing */
    912  1.3.2.2  rmind }
    913  1.3.2.2  rmind 
    914  1.3.2.2  rmind static int
    915  1.3.2.2  rmind pq3pci_bus_maxdevs(void *v, int busno)
    916  1.3.2.2  rmind {
    917  1.3.2.2  rmind 	struct pq3pci_softc * const sc = v;
    918  1.3.2.2  rmind 	return sc->sc_pcie && busno < 2 ? 1 : 32;
    919  1.3.2.2  rmind }
    920  1.3.2.2  rmind 
    921  1.3.2.2  rmind static void
    922  1.3.2.2  rmind pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func)
    923  1.3.2.2  rmind {
    924  1.3.2.2  rmind 	if (bus)
    925  1.3.2.2  rmind 		*bus = (tag >> 16) & 0xff;
    926  1.3.2.2  rmind 	if (dev)
    927  1.3.2.2  rmind 		*dev = (tag >> 11) & 0x1f;
    928  1.3.2.2  rmind 	if (func)
    929  1.3.2.2  rmind 		*func = (tag >> 8) & 0x07;
    930  1.3.2.2  rmind }
    931  1.3.2.2  rmind 
    932  1.3.2.2  rmind static pcitag_t
    933  1.3.2.2  rmind pq3pci_make_tag(void *v, int bus, int dev, int func)
    934  1.3.2.2  rmind {
    935  1.3.2.2  rmind 	return (bus << 16) | (dev << 11) | (func << 8);
    936  1.3.2.2  rmind }
    937  1.3.2.2  rmind 
    938  1.3.2.2  rmind static inline pcitag_t
    939  1.3.2.2  rmind pq3pci_config_addr_read(pci_chipset_tag_t pc)
    940  1.3.2.2  rmind {
    941  1.3.2.2  rmind 	pcitag_t v;
    942  1.3.2.2  rmind         __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr));
    943  1.3.2.2  rmind         __asm volatile("mbar\n\tmsync");
    944  1.3.2.2  rmind 	return v;
    945  1.3.2.2  rmind }
    946  1.3.2.2  rmind 
    947  1.3.2.2  rmind static inline void
    948  1.3.2.2  rmind pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v)
    949  1.3.2.2  rmind {
    950  1.3.2.2  rmind         __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr));
    951  1.3.2.2  rmind         __asm volatile("mbar\n\tmsync");
    952  1.3.2.2  rmind }
    953  1.3.2.2  rmind 
    954  1.3.2.2  rmind static inline pcireg_t
    955  1.3.2.2  rmind pq3pci_config_data_read(pci_chipset_tag_t pc)
    956  1.3.2.2  rmind {
    957  1.3.2.2  rmind 	pcireg_t v;
    958  1.3.2.2  rmind         __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data));
    959  1.3.2.2  rmind         __asm volatile("mbar\n\tmsync");
    960  1.3.2.2  rmind 	return v;
    961  1.3.2.2  rmind }
    962  1.3.2.2  rmind 
    963  1.3.2.2  rmind static inline void
    964  1.3.2.2  rmind pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v)
    965  1.3.2.2  rmind {
    966  1.3.2.2  rmind         __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data));
    967  1.3.2.2  rmind         __asm volatile("mbar\n\tmsync");
    968  1.3.2.2  rmind }
    969  1.3.2.2  rmind 
    970  1.3.2.2  rmind static pcireg_t
    971  1.3.2.2  rmind pq3pci_conf_read(void *v, pcitag_t tag, int reg)
    972  1.3.2.2  rmind {
    973  1.3.2.2  rmind 	struct pq3pci_softc * const sc = v;
    974  1.3.2.2  rmind 	struct genppc_pci_chipset * const pc = &sc->sc_pc;
    975  1.3.2.2  rmind 
    976  1.3.2.2  rmind 	if (reg >= 256) {
    977  1.3.2.2  rmind 		if (!sc->sc_pcie)
    978  1.3.2.2  rmind 			return 0xffffffff;
    979  1.3.2.2  rmind 		reg = (reg & 0xff) | ((reg & 0xf00) << 16);
    980  1.3.2.2  rmind 	}
    981  1.3.2.2  rmind 	if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) {
    982  1.3.2.2  rmind 	//	pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
    983  1.3.2.2  rmind 	//	printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status);
    984  1.3.2.2  rmind 	//	if ((slot_status & __BIT(6+16)) == 0)
    985  1.3.2.2  rmind 	//		printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN);
    986  1.3.2.2  rmind 	//		return 0xffffffff;
    987  1.3.2.2  rmind 	}
    988  1.3.2.2  rmind 
    989  1.3.2.2  rmind 	mutex_spin_enter(sc->sc_conf_lock);
    990  1.3.2.2  rmind 
    991  1.3.2.2  rmind 	pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
    992  1.3.2.2  rmind 	pcireg_t rv = pq3pci_config_data_read(pc);
    993  1.3.2.2  rmind 
    994  1.3.2.2  rmind 	mutex_spin_exit(sc->sc_conf_lock);
    995  1.3.2.2  rmind 
    996  1.3.2.2  rmind #if 0
    997  1.3.2.2  rmind 	uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR);
    998  1.3.2.2  rmind 	if (err & PEXERRDR_ICCA) {
    999  1.3.2.2  rmind 		aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n",
   1000  1.3.2.2  rmind 		    __func__, tag, reg, pq3pci_config_addr_read(pc));
   1001  1.3.2.2  rmind 		bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR,
   1002  1.3.2.2  rmind 		    PEXERRDR_ICCA);
   1003  1.3.2.2  rmind 	}
   1004  1.3.2.2  rmind #endif
   1005  1.3.2.2  rmind 	return rv;
   1006  1.3.2.2  rmind }
   1007  1.3.2.2  rmind 
   1008  1.3.2.2  rmind static void
   1009  1.3.2.2  rmind pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data)
   1010  1.3.2.2  rmind {
   1011  1.3.2.2  rmind 	struct pq3pci_softc * const sc = v;
   1012  1.3.2.2  rmind 	struct genppc_pci_chipset * const pc = &sc->sc_pc;
   1013  1.3.2.2  rmind 
   1014  1.3.2.2  rmind 	if (reg >= 256) {
   1015  1.3.2.2  rmind 		if (!sc->sc_pcie)
   1016  1.3.2.2  rmind 			return;
   1017  1.3.2.2  rmind 		reg = (reg & 0xff) | ((reg & 0xf00) << 16);
   1018  1.3.2.2  rmind 	}
   1019  1.3.2.2  rmind 
   1020  1.3.2.2  rmind 	mutex_spin_enter(sc->sc_conf_lock);
   1021  1.3.2.2  rmind 
   1022  1.3.2.2  rmind #if 0
   1023  1.3.2.2  rmind 	aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n",
   1024  1.3.2.2  rmind 	    __func__, tag, reg, data);
   1025  1.3.2.2  rmind #endif
   1026  1.3.2.2  rmind 	pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN);
   1027  1.3.2.2  rmind 	pq3pci_config_data_write(pc, data);
   1028  1.3.2.2  rmind 
   1029  1.3.2.2  rmind 	mutex_spin_exit(sc->sc_conf_lock);
   1030  1.3.2.2  rmind }
   1031  1.3.2.2  rmind 
   1032  1.3.2.2  rmind static int
   1033  1.3.2.2  rmind pq3pci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func,
   1034  1.3.2.2  rmind 	pcireg_t id)
   1035  1.3.2.2  rmind {
   1036  1.3.2.2  rmind 	struct pq3pci_softc * const sc = pc->pc_conf_v;
   1037  1.3.2.2  rmind 	if (sc->sc_pcie && bus != 0) {
   1038  1.3.2.2  rmind 		pcireg_t slot_status = pci_conf_read(pc, 0, 0x64);
   1039  1.3.2.2  rmind 		if ((slot_status & __BIT(6+16)) == 0)
   1040  1.3.2.2  rmind 			return 0;
   1041  1.3.2.2  rmind 	}
   1042  1.3.2.2  rmind 	if (!sc->sc_pcie && bus == 0 && dev == 0) {
   1043  1.3.2.2  rmind 		return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM);
   1044  1.3.2.2  rmind 	}
   1045  1.3.2.2  rmind 	return PCI_CONF_DEFAULT;
   1046  1.3.2.2  rmind }
   1047  1.3.2.2  rmind 
   1048  1.3.2.2  rmind static void
   1049  1.3.2.2  rmind pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl)
   1050  1.3.2.2  rmind {
   1051  1.3.2.2  rmind 	const char (*intr_names)[8] = msi_intr_names[group];
   1052  1.3.2.2  rmind 
   1053  1.3.2.2  rmind 	KASSERT(ipl == IPL_VM);
   1054  1.3.2.2  rmind 
   1055  1.3.2.2  rmind 	pq3pci_msigroups[group] = msig;
   1056  1.3.2.2  rmind 	msig->msig_group = group;
   1057  1.3.2.2  rmind 	msig->msig_free_mask = ~0 << (group == 0);
   1058  1.3.2.2  rmind 	msig->msig_ipl = ipl;
   1059  1.3.2.2  rmind 	msig->msig_lock = mutex_obj_alloc(MUTEX_DEFAULT, ipl);
   1060  1.3.2.2  rmind 	msig->msig_ih = intr_establish(msig->msig_group, ipl, IST_MSIGROUP,
   1061  1.3.2.2  rmind 	    pq3pci_msi_intr, msig);
   1062  1.3.2.2  rmind 	msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group);
   1063  1.3.2.2  rmind 	for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) {
   1064  1.3.2.2  rmind 		struct pq3pci_msihand * const msih = msig->msig_ihands + i;
   1065  1.3.2.2  rmind 		msih->msih_ih.ih_class = IH_MSI;
   1066  1.3.2.2  rmind 		msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
   1067  1.3.2.2  rmind 		msih->msih_ih.ih_arg = msih;
   1068  1.3.2.2  rmind 		msih->msih_group = msig;
   1069  1.3.2.2  rmind 		evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR,
   1070  1.3.2.2  rmind 		    NULL, intr_names[i], "intr");
   1071  1.3.2.2  rmind 		evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR,
   1072  1.3.2.2  rmind 		    &msih->msih_ev, intr_names[i], "spurious intr");
   1073  1.3.2.2  rmind 	}
   1074  1.3.2.2  rmind }
   1075  1.3.2.2  rmind 
   1076  1.3.2.2  rmind static pci_intr_handle_t
   1077  1.3.2.2  rmind pq3pci_msi_alloc(int ipl, u_int rmsi)
   1078  1.3.2.2  rmind {
   1079  1.3.2.2  rmind 	size_t freegroup = 0;
   1080  1.3.2.2  rmind 	size_t maplen = __arraycount(pq3pci_msigroups);
   1081  1.3.2.2  rmind 	KASSERT(rmsi <= 5);
   1082  1.3.2.2  rmind 	uint32_t bitmap[maplen];
   1083  1.3.2.2  rmind 
   1084  1.3.2.2  rmind 	for (u_int i = 0; i < maplen; i++) {
   1085  1.3.2.2  rmind 		struct pq3pci_msigroup * const msig = pq3pci_msigroups[i];
   1086  1.3.2.2  rmind 		if (msig == NULL) {
   1087  1.3.2.2  rmind 			bitmap[i] = 0;
   1088  1.3.2.2  rmind 			if (freegroup == 0)
   1089  1.3.2.2  rmind 				freegroup = i + 1;
   1090  1.3.2.2  rmind 			continue;
   1091  1.3.2.2  rmind 		}
   1092  1.3.2.2  rmind 		/*
   1093  1.3.2.2  rmind 		 * If this msigroup has the wrong IPL or there's nothing
   1094  1.3.2.2  rmind 		 * free, try the next one.
   1095  1.3.2.2  rmind 		 */
   1096  1.3.2.2  rmind 		if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) {
   1097  1.3.2.2  rmind 			bitmap[i] = 0;
   1098  1.3.2.2  rmind 			continue;
   1099  1.3.2.2  rmind 		}
   1100  1.3.2.2  rmind 
   1101  1.3.2.2  rmind 		bitmap[i] = msig->msig_free_mask;
   1102  1.3.2.2  rmind 	}
   1103  1.3.2.2  rmind 	for (u_int i = 0; i < maplen; i++) {
   1104  1.3.2.2  rmind 		uint32_t mapbits = bitmap[i];
   1105  1.3.2.2  rmind 		u_int n = ffs(mapbits);
   1106  1.3.2.2  rmind 		if (n--) {
   1107  1.3.2.2  rmind 			return PIH_MAKE(i * 32 + n, IST_MSI, 0);
   1108  1.3.2.2  rmind 		}
   1109  1.3.2.2  rmind 	}
   1110  1.3.2.2  rmind 
   1111  1.3.2.2  rmind 	if (freegroup-- == 0)
   1112  1.3.2.2  rmind 		return 0;
   1113  1.3.2.2  rmind 
   1114  1.3.2.2  rmind 	struct pq3pci_msigroup * const msig =
   1115  1.3.2.2  rmind 	    kmem_zalloc(sizeof(*msig), KM_SLEEP);
   1116  1.3.2.2  rmind 	KASSERT(msig != NULL);
   1117  1.3.2.2  rmind 	pq3pci_msi_group_setup(msig, freegroup, ipl);
   1118  1.3.2.2  rmind 	u_int n = ffs(msig->msig_free_mask) - 1;
   1119  1.3.2.2  rmind 	return PIH_MAKE(freegroup * 32 + n, IST_MSI, 0);
   1120  1.3.2.2  rmind }
   1121  1.3.2.2  rmind 
   1122  1.3.2.2  rmind static struct pq3pci_msihand *
   1123  1.3.2.2  rmind pq3pci_msi_lookup(pci_intr_handle_t handle)
   1124  1.3.2.2  rmind {
   1125  1.3.2.2  rmind 	const int irq = PIH_IRQ(handle);
   1126  1.3.2.2  rmind 	KASSERT(irq < 256);
   1127  1.3.2.2  rmind 	struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
   1128  1.3.2.2  rmind 	KASSERT(msig != NULL);
   1129  1.3.2.2  rmind 	return &msig->msig_ihands[irq & 31];
   1130  1.3.2.2  rmind }
   1131  1.3.2.2  rmind 
   1132  1.3.2.2  rmind static struct pq3pci_msihand *
   1133  1.3.2.2  rmind pq3pci_msi_claim(pci_intr_handle_t handle)
   1134  1.3.2.2  rmind {
   1135  1.3.2.2  rmind 	const int irq = PIH_IRQ(handle);
   1136  1.3.2.2  rmind 	uint32_t irq_mask = __BIT(irq & 31);
   1137  1.3.2.2  rmind 	KASSERT(irq < 256);
   1138  1.3.2.2  rmind 	struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32];
   1139  1.3.2.2  rmind 	KASSERT(msig != NULL);
   1140  1.3.2.2  rmind 	struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31];
   1141  1.3.2.2  rmind 	mutex_spin_enter(msig->msig_lock);
   1142  1.3.2.2  rmind 	KASSERT(msig->msig_free_mask & irq_mask);
   1143  1.3.2.2  rmind 	msig->msig_free_mask ^= irq_mask;
   1144  1.3.2.2  rmind 	mutex_spin_exit(msig->msig_lock);
   1145  1.3.2.2  rmind 	return msih;
   1146  1.3.2.2  rmind }
   1147  1.3.2.2  rmind 
   1148  1.3.2.2  rmind static struct pq3pci_intrsource *
   1149  1.3.2.2  rmind pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle)
   1150  1.3.2.2  rmind {
   1151  1.3.2.2  rmind 	struct pq3pci_intrsource *pis;
   1152  1.3.2.2  rmind 	SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) {
   1153  1.3.2.2  rmind 		if (pis->pis_handle == handle)
   1154  1.3.2.2  rmind 			return pis;
   1155  1.3.2.2  rmind 	}
   1156  1.3.2.2  rmind 	pis = kmem_zalloc(sizeof(*pis), KM_SLEEP);
   1157  1.3.2.2  rmind 	pq3pci_intr_source_setup(sc, pis, handle);
   1158  1.3.2.2  rmind 	return pis;
   1159  1.3.2.2  rmind }
   1160  1.3.2.2  rmind 
   1161  1.3.2.2  rmind static pci_intr_handle_t
   1162  1.3.2.3  rmind pq3pci_intr_handle_lookup(struct pq3pci_softc *sc,
   1163  1.3.2.3  rmind     const struct pci_attach_args *pa)
   1164  1.3.2.2  rmind {
   1165  1.3.2.2  rmind 	prop_dictionary_t entry;
   1166  1.3.2.2  rmind 
   1167  1.3.2.2  rmind 	if (sc->sc_pcie) do {
   1168  1.3.2.2  rmind 		pcireg_t msictl;
   1169  1.3.2.2  rmind 		int msioff;
   1170  1.3.2.2  rmind 		if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI,
   1171  1.3.2.2  rmind 					&msioff, &msictl))
   1172  1.3.2.2  rmind 			break;
   1173  1.3.2.2  rmind 		msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff);
   1174  1.3.2.2  rmind 		msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
   1175  1.3.2.2  rmind 		msictl &= ~(PCI_MSI_CTL_MME_MASK << PCI_MSI_CTL_MME_SHIFT);
   1176  1.3.2.2  rmind 		int rmsi = (msictl >> PCI_MSI_CTL_MMC_SHIFT) & PCI_MSI_CTL_MMC_MASK;
   1177  1.3.2.2  rmind 		pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl);
   1178  1.3.2.2  rmind 		pci_intr_handle_t handle = pq3pci_msi_alloc(IPL_VM, rmsi);
   1179  1.3.2.2  rmind 		struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle);
   1180  1.3.2.2  rmind 		msih->msih_tag = pa->pa_tag;
   1181  1.3.2.2  rmind 		msih->msih_msioff = msioff;
   1182  1.3.2.2  rmind 		return handle;
   1183  1.3.2.2  rmind 	} while (false);
   1184  1.3.2.2  rmind 
   1185  1.3.2.2  rmind 
   1186  1.3.2.2  rmind 	if (sc->sc_intrmask == 0) {
   1187  1.3.2.2  rmind 		entry = prop_dictionary_get(sc->sc_intrmap, "000000");
   1188  1.3.2.2  rmind 	} else {
   1189  1.3.2.2  rmind 		char prop_name[8];
   1190  1.3.2.2  rmind 		u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask);
   1191  1.3.2.2  rmind 		pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc;
   1192  1.3.2.2  rmind 
   1193  1.3.2.2  rmind 		snprintf(prop_name, sizeof(prop_name), "%06x",
   1194  1.3.2.2  rmind 		    tag & sc->sc_intrmask);
   1195  1.3.2.2  rmind 
   1196  1.3.2.2  rmind #if 0
   1197  1.3.2.2  rmind 		printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n",
   1198  1.3.2.2  rmind 		    __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin,
   1199  1.3.2.2  rmind 		    tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name);
   1200  1.3.2.2  rmind #endif
   1201  1.3.2.2  rmind 
   1202  1.3.2.2  rmind 		entry = prop_dictionary_get(sc->sc_intrmap, prop_name);
   1203  1.3.2.2  rmind 	}
   1204  1.3.2.2  rmind 	KASSERT(entry != NULL);
   1205  1.3.2.2  rmind 	KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY);
   1206  1.3.2.2  rmind 
   1207  1.3.2.2  rmind 	prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt");
   1208  1.3.2.2  rmind 	KASSERT(pn_irq != NULL);
   1209  1.3.2.2  rmind 	KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER);
   1210  1.3.2.2  rmind 	int irq = prop_number_unsigned_integer_value(pn_irq);
   1211  1.3.2.2  rmind 	prop_number_t pn_ist = prop_dictionary_get(entry, "type");
   1212  1.3.2.2  rmind 	KASSERT(pn_ist != NULL);
   1213  1.3.2.2  rmind 	KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER);
   1214  1.3.2.2  rmind 	int ist = prop_number_unsigned_integer_value(pn_ist);
   1215  1.3.2.2  rmind 
   1216  1.3.2.2  rmind 	return PIH_MAKE(irq, ist, 0);
   1217  1.3.2.2  rmind }
   1218  1.3.2.2  rmind 
   1219  1.3.2.2  rmind static int
   1220  1.3.2.3  rmind pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep)
   1221  1.3.2.2  rmind {
   1222  1.3.2.2  rmind 	struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v;
   1223  1.3.2.2  rmind 
   1224  1.3.2.2  rmind 	if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE)
   1225  1.3.2.2  rmind 		return ENOENT;
   1226  1.3.2.2  rmind 
   1227  1.3.2.2  rmind 	*handlep = pq3pci_intr_handle_lookup(sc, pa);
   1228  1.3.2.2  rmind 
   1229  1.3.2.2  rmind 	return 0;
   1230  1.3.2.2  rmind }
   1231  1.3.2.2  rmind 
   1232  1.3.2.2  rmind static const char *
   1233  1.3.2.2  rmind pq3pci_intr_string(void *v, pci_intr_handle_t handle)
   1234  1.3.2.2  rmind {
   1235  1.3.2.2  rmind 	if (PIH_IST(handle) == IST_MSI) {
   1236  1.3.2.2  rmind 		const char (*intr_names)[8] = msi_intr_names[0];
   1237  1.3.2.2  rmind 		return intr_names[PIH_IRQ(handle)];
   1238  1.3.2.2  rmind 	}
   1239  1.3.2.2  rmind 
   1240  1.3.2.2  rmind 	return intr_string(PIH_IRQ(handle), PIH_IST(handle));
   1241  1.3.2.2  rmind }
   1242  1.3.2.2  rmind 
   1243  1.3.2.2  rmind static const struct evcnt *
   1244  1.3.2.2  rmind pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle)
   1245  1.3.2.2  rmind {
   1246  1.3.2.2  rmind 	struct pq3pci_softc * const sc = v;
   1247  1.3.2.2  rmind 	struct pq3pci_intrsource * const pis =
   1248  1.3.2.2  rmind 	    pq3pci_intr_source_lookup(sc, handle);
   1249  1.3.2.2  rmind 
   1250  1.3.2.2  rmind 	KASSERT(pis != NULL);
   1251  1.3.2.2  rmind 
   1252  1.3.2.2  rmind 	return &pis->pis_ev;
   1253  1.3.2.2  rmind }
   1254  1.3.2.2  rmind 
   1255  1.3.2.2  rmind static void *
   1256  1.3.2.2  rmind pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl,
   1257  1.3.2.2  rmind 	int (*func)(void *), void *arg)
   1258  1.3.2.2  rmind {
   1259  1.3.2.2  rmind 	struct pq3pci_softc * const sc = v;
   1260  1.3.2.2  rmind 
   1261  1.3.2.2  rmind 	if (0) {
   1262  1.3.2.2  rmind 		struct pq3pci_callhand * const pch =
   1263  1.3.2.2  rmind 		    kmem_zalloc(sizeof(*pch), KM_SLEEP);
   1264  1.3.2.2  rmind 		KASSERT(pch);
   1265  1.3.2.2  rmind 		pch->pch_ih.ih_arg = arg;
   1266  1.3.2.2  rmind 		pch->pch_ih.ih_func = func;
   1267  1.3.2.2  rmind 		pch->pch_ih.ih_sc = sc;
   1268  1.3.2.2  rmind 		pch->pch_ipl = ipl;
   1269  1.3.2.2  rmind 
   1270  1.3.2.2  rmind 		callout_init(&pch->pch_callout, 0);
   1271  1.3.2.2  rmind 		callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
   1272  1.3.2.2  rmind 
   1273  1.3.2.2  rmind 		return pch;
   1274  1.3.2.2  rmind 	}
   1275  1.3.2.2  rmind 
   1276  1.3.2.2  rmind 	const int ist = PIH_IST(handle);
   1277  1.3.2.2  rmind 
   1278  1.3.2.2  rmind 	if (ist == IST_MSI) {
   1279  1.3.2.2  rmind 		pci_chipset_tag_t pc = &sc->sc_pc;
   1280  1.3.2.2  rmind 		struct pq3pci_msihand * const msih = pq3pci_msi_claim(handle);
   1281  1.3.2.2  rmind 		pcireg_t cmdsts, msictl;
   1282  1.3.2.2  rmind 
   1283  1.3.2.2  rmind 		if (msih == NULL)
   1284  1.3.2.2  rmind 			return NULL;
   1285  1.3.2.2  rmind 
   1286  1.3.2.2  rmind 		struct pq3pci_msigroup * const msig = msih->msih_group;
   1287  1.3.2.2  rmind 		const pcitag_t tag = msih->msih_tag;
   1288  1.3.2.2  rmind 
   1289  1.3.2.2  rmind 		mutex_spin_enter(msig->msig_lock);
   1290  1.3.2.2  rmind 		msih->msih_ih.ih_class = IH_MSI;
   1291  1.3.2.2  rmind 		msih->msih_ih.ih_arg = arg;
   1292  1.3.2.2  rmind 		msih->msih_ih.ih_func = func;
   1293  1.3.2.2  rmind 		msih->msih_ih.ih_sc = sc;
   1294  1.3.2.2  rmind 
   1295  1.3.2.2  rmind 		int off = msih->msih_msioff;
   1296  1.3.2.2  rmind 		msictl = pci_conf_read(pc, tag, off);
   1297  1.3.2.2  rmind 
   1298  1.3.2.2  rmind 		/*
   1299  1.3.2.2  rmind 		 * The PCSRBAR has already been setup as a 1:1 BAR so we point
   1300  1.3.2.2  rmind 		 * MSIs at the MSII register in the OpenPIC.
   1301  1.3.2.2  rmind 		 */
   1302  1.3.2.2  rmind 		off += 4;
   1303  1.3.2.2  rmind 		pci_conf_write(pc, tag, off,
   1304  1.3.2.2  rmind 		    sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR);
   1305  1.3.2.2  rmind 
   1306  1.3.2.2  rmind 		/*
   1307  1.3.2.2  rmind 		 * Upper address is going to be 0.
   1308  1.3.2.2  rmind 		 */
   1309  1.3.2.2  rmind 		if (msictl & PCI_MSI_CTL_64BIT_ADDR) {
   1310  1.3.2.2  rmind 			off += 4;
   1311  1.3.2.2  rmind 			pci_conf_write(pc, tag, off, 0);
   1312  1.3.2.2  rmind 		}
   1313  1.3.2.2  rmind 
   1314  1.3.2.2  rmind 		/*
   1315  1.3.2.2  rmind 		 * Set the magic value.  Since PCI writes this to the least
   1316  1.3.2.2  rmind 		 * significant byte of AD[31:0], let's hope the bridge byte
   1317  1.3.2.2  rmind 		 * swaps to so it's the most significant bytes or nothing is
   1318  1.3.2.2  rmind 		 * going to happen.
   1319  1.3.2.2  rmind 		 */
   1320  1.3.2.2  rmind 		off += 4;
   1321  1.3.2.2  rmind 		pci_conf_write(pc, tag, off, PIH_IRQ(handle));
   1322  1.3.2.2  rmind 
   1323  1.3.2.2  rmind 		/*
   1324  1.3.2.2  rmind 		 * Should the driver do this?  How would it know to do it?
   1325  1.3.2.2  rmind 		 */
   1326  1.3.2.2  rmind 		if (msictl & PCI_MSI_CTL_PERVEC_MASK) {
   1327  1.3.2.2  rmind 			off += 4;
   1328  1.3.2.2  rmind 			pci_conf_write(pc, tag, off, 0);
   1329  1.3.2.2  rmind 		}
   1330  1.3.2.2  rmind 
   1331  1.3.2.2  rmind 		/*
   1332  1.3.2.2  rmind 		 * Let's make sure he won't raise any INTx.  Technically
   1333  1.3.2.2  rmind 		 * setting MSI enable will prevent that as well but might
   1334  1.3.2.2  rmind 		 * as well be as safe as possible.
   1335  1.3.2.2  rmind 		 */
   1336  1.3.2.2  rmind 		cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG);
   1337  1.3.2.2  rmind 		cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE;
   1338  1.3.2.2  rmind 		pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts);
   1339  1.3.2.2  rmind 
   1340  1.3.2.2  rmind #if 1
   1341  1.3.2.2  rmind 		/*
   1342  1.3.2.2  rmind 		 * Now we can enable the MSI
   1343  1.3.2.2  rmind 		 */
   1344  1.3.2.2  rmind 		msictl |= PCI_MSI_CTL_MSI_ENABLE;
   1345  1.3.2.2  rmind 		pci_conf_write(pc, tag, msih->msih_msioff, msictl);
   1346  1.3.2.2  rmind #endif
   1347  1.3.2.2  rmind 
   1348  1.3.2.2  rmind 		mutex_spin_exit(msig->msig_lock);
   1349  1.3.2.2  rmind 
   1350  1.3.2.2  rmind #if 0
   1351  1.3.2.2  rmind 		struct pq3pci_callhand * const pch =
   1352  1.3.2.2  rmind 		    kmem_zalloc(sizeof(*pch), KM_SLEEP);
   1353  1.3.2.2  rmind 		KASSERT(pch);
   1354  1.3.2.2  rmind 
   1355  1.3.2.2  rmind 		pch->pch_ih.ih_arg = msig;
   1356  1.3.2.2  rmind 		pch->pch_ih.ih_func = pq3pci_msi_intr;
   1357  1.3.2.2  rmind #if 1
   1358  1.3.2.2  rmind 		pch->pch_ih.ih_arg = arg;
   1359  1.3.2.2  rmind 		pch->pch_ih.ih_func = func;
   1360  1.3.2.2  rmind #endif
   1361  1.3.2.2  rmind 		pch->pch_ih.ih_sc = sc;
   1362  1.3.2.2  rmind 		pch->pch_ipl = ipl;
   1363  1.3.2.2  rmind 
   1364  1.3.2.2  rmind 		callout_init(&pch->pch_callout, 0);
   1365  1.3.2.2  rmind 		callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch);
   1366  1.3.2.2  rmind 
   1367  1.3.2.2  rmind #if 1
   1368  1.3.2.2  rmind 		return pch;
   1369  1.3.2.2  rmind #endif
   1370  1.3.2.2  rmind #endif
   1371  1.3.2.2  rmind 
   1372  1.3.2.2  rmind 		return msih;
   1373  1.3.2.2  rmind 	} else {
   1374  1.3.2.2  rmind 		struct pq3pci_intrsource * const pis =
   1375  1.3.2.2  rmind 		    pq3pci_intr_source_lookup(sc, handle);
   1376  1.3.2.2  rmind 		KASSERT(pis != NULL);
   1377  1.3.2.2  rmind 
   1378  1.3.2.2  rmind 		struct pq3pci_intrhand * const pih =
   1379  1.3.2.2  rmind 		    kmem_zalloc(sizeof(*pih), KM_SLEEP);
   1380  1.3.2.2  rmind 
   1381  1.3.2.2  rmind 		if (pih == NULL)
   1382  1.3.2.2  rmind 			return NULL;
   1383  1.3.2.2  rmind 
   1384  1.3.2.2  rmind 		pih->pih_ih.ih_class = IH_INTX;
   1385  1.3.2.2  rmind 		pih->pih_ih.ih_func = func;
   1386  1.3.2.2  rmind 		pih->pih_ih.ih_arg = arg;
   1387  1.3.2.2  rmind 		pih->pih_ih.ih_sc = sc;
   1388  1.3.2.2  rmind 		pih->pih_ipl = ipl;
   1389  1.3.2.2  rmind 		pih->pih_source = pis;
   1390  1.3.2.2  rmind 
   1391  1.3.2.2  rmind 		mutex_spin_enter(pis->pis_lock);
   1392  1.3.2.2  rmind 		SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link);
   1393  1.3.2.2  rmind 		mutex_spin_exit(pis->pis_lock);
   1394  1.3.2.2  rmind 
   1395  1.3.2.2  rmind 		return pih;
   1396  1.3.2.2  rmind 	}
   1397  1.3.2.2  rmind }
   1398  1.3.2.2  rmind 
   1399  1.3.2.2  rmind static void
   1400  1.3.2.2  rmind pq3pci_intr_disestablish(void *v, void *ih)
   1401  1.3.2.2  rmind {
   1402  1.3.2.2  rmind 	struct pq3pci_genihand * const gih = ih;
   1403  1.3.2.2  rmind 
   1404  1.3.2.2  rmind 	if (gih->ih_class == IH_INTX) {
   1405  1.3.2.2  rmind 		struct pq3pci_intrhand * const pih = ih;
   1406  1.3.2.2  rmind 		struct pq3pci_intrsource * const pis = pih->pih_source;
   1407  1.3.2.2  rmind 
   1408  1.3.2.2  rmind 		mutex_spin_enter(pis->pis_lock);
   1409  1.3.2.2  rmind 		SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link);
   1410  1.3.2.2  rmind 		mutex_spin_exit(pis->pis_lock);
   1411  1.3.2.2  rmind 
   1412  1.3.2.2  rmind 		kmem_free(pih, sizeof(*pih));
   1413  1.3.2.2  rmind 		return;
   1414  1.3.2.2  rmind 	}
   1415  1.3.2.2  rmind 	struct pq3pci_msihand * const msih = ih;
   1416  1.3.2.2  rmind 	struct pq3pci_msigroup * const msig = msih->msih_group;
   1417  1.3.2.2  rmind 	struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc;
   1418  1.3.2.2  rmind 	const pcitag_t tag = msih->msih_tag;
   1419  1.3.2.2  rmind 
   1420  1.3.2.2  rmind 	mutex_spin_enter(msig->msig_lock);
   1421  1.3.2.2  rmind 
   1422  1.3.2.2  rmind 	/*
   1423  1.3.2.2  rmind 	 * disable the MSI
   1424  1.3.2.2  rmind 	 */
   1425  1.3.2.2  rmind 	pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff);
   1426  1.3.2.2  rmind 	msictl &= ~PCI_MSI_CTL_MSI_ENABLE;
   1427  1.3.2.2  rmind 	pci_conf_write(pc, tag, msih->msih_msioff, msictl);
   1428  1.3.2.2  rmind 
   1429  1.3.2.2  rmind 	msih->msih_ih.ih_func = pq3pci_msi_spurious_intr;
   1430  1.3.2.2  rmind 	msih->msih_ih.ih_arg = msig;
   1431  1.3.2.2  rmind 	msih->msih_ih.ih_sc = NULL;
   1432  1.3.2.2  rmind 	msih->msih_tag = 0;
   1433  1.3.2.2  rmind 	msih->msih_msioff = 0;
   1434  1.3.2.2  rmind 	mutex_spin_exit(msig->msig_lock);
   1435  1.3.2.2  rmind }
   1436  1.3.2.2  rmind 
   1437  1.3.2.2  rmind static void
   1438  1.3.2.2  rmind pq3pci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin,
   1439  1.3.2.2  rmind 	int swiz, int *iline)
   1440  1.3.2.2  rmind {
   1441  1.3.2.2  rmind }
   1442  1.3.2.2  rmind 
   1443  1.3.2.2  rmind static pci_chipset_tag_t
   1444  1.3.2.2  rmind pq3pci_pci_chipset_init(struct pq3pci_softc *sc)
   1445  1.3.2.2  rmind {
   1446  1.3.2.2  rmind 	struct genppc_pci_chipset * const pc = &sc->sc_pc;
   1447  1.3.2.2  rmind 
   1448  1.3.2.2  rmind 	pc->pc_conf_v = sc;
   1449  1.3.2.2  rmind 	pc->pc_attach_hook = pq3pci_attach_hook;
   1450  1.3.2.2  rmind         pc->pc_bus_maxdevs = pq3pci_bus_maxdevs;
   1451  1.3.2.2  rmind         pc->pc_make_tag = pq3pci_make_tag;
   1452  1.3.2.2  rmind         pc->pc_conf_read = pq3pci_conf_read;
   1453  1.3.2.2  rmind         pc->pc_conf_write = pq3pci_conf_write;
   1454  1.3.2.2  rmind #ifdef PCI_NETBSD_CONFIGURE
   1455  1.3.2.2  rmind         pc->pc_conf_hook = pq3pci_conf_hook;
   1456  1.3.2.2  rmind #endif
   1457  1.3.2.2  rmind 
   1458  1.3.2.2  rmind         pc->pc_intr_v = sc;
   1459  1.3.2.2  rmind         pc->pc_intr_map = pq3pci_intr_map;
   1460  1.3.2.2  rmind         pc->pc_intr_string = pq3pci_intr_string;
   1461  1.3.2.2  rmind         pc->pc_intr_evcnt = pq3pci_intr_evcnt;
   1462  1.3.2.2  rmind         pc->pc_intr_establish = pq3pci_intr_establish;
   1463  1.3.2.2  rmind         pc->pc_intr_disestablish = pq3pci_intr_disestablish;
   1464  1.3.2.2  rmind         pc->pc_conf_interrupt = pq3pci_conf_interrupt;
   1465  1.3.2.2  rmind         pc->pc_decompose_tag = pq3pci_decompose_tag;
   1466  1.3.2.2  rmind         pc->pc_conf_hook = pq3pci_conf_hook;
   1467  1.3.2.2  rmind 
   1468  1.3.2.2  rmind 	/*
   1469  1.3.2.2  rmind 	 * This is a horrible kludge but it makes life easier.
   1470  1.3.2.2  rmind 	 */
   1471  1.3.2.2  rmind         pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR);
   1472  1.3.2.2  rmind         pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA);
   1473  1.3.2.2  rmind         pc->pc_bus = 0;
   1474  1.3.2.2  rmind         pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag;
   1475  1.3.2.2  rmind         pc->pc_iot = &sc->sc_pci_io_bst.bs_tag;
   1476  1.3.2.2  rmind 
   1477  1.3.2.2  rmind 	SIMPLEQ_INIT(&pc->pc_pbi);
   1478  1.3.2.2  rmind 
   1479  1.3.2.2  rmind 	return pc;
   1480  1.3.2.2  rmind }
   1481