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