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