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