pq3pci.c revision 1.30
1/* $NetBSD: pq3pci.c,v 1.30 2022/01/11 22:45:56 andvar 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.30 2022/01/11 22:45:56 andvar 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_integer_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 mutex_init(&pq3pci_intrsources_lock, MUTEX_DEFAULT, IPL_VM); 731 mutex_init(&pq3pci_msigroups_lock, MUTEX_DEFAULT, IPL_VM); 732 733 return 0; 734} 735 736void 737pq3pci_cpunode_attach(device_t parent, device_t self, void *aux) 738{ 739 struct cpunode_softc * const psc = device_private(parent); 740 struct pq3pci_softc * const sc = device_private(self); 741 struct cpunode_attach_args * const cna = aux; 742 struct cpunode_locators * const cnl = &cna->cna_locs; 743 char buf[32]; 744 745 sc->sc_dev = self; 746 sc->sc_bst = cna->cna_memt; 747 psc->sc_children |= cna->cna_childmask; 748 sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0; 749 750 RUN_ONCE(&pq3pci_init_once, pq3pci_once_init); 751 752 const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR); 753 if (sc->sc_pcie) { 754 u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr, 755 pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0); 756 if (lanes == 0) { 757 aprint_normal(": disabled\n"); 758 return; 759 } 760 snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes); 761 } else { 762 bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr, 763 pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0); 764 u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr, 765 pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32); 766 snprintf(buf, sizeof(buf), "%u-bit PCI%s", 767 width, (pcix_p ? "X" : "")); 768 } 769 770 if (!pq3pci_intrmap_setup(sc, cnl)) 771 return; 772 773 evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL, 774 device_xname(self), "spurious intr"); 775 776 int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0, 777 &sc->sc_bsh); 778 if (error) { 779 aprint_error(": failed to map registers: %d\n", error); 780 return; 781 } 782 783 u_int valid_owins = 0; 784 for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0; 785 i < 4; i++, off += PEXOTAR1 - PEXOTAR0) { 786 struct pq3pci_owin owin; 787 owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 788 PEXOTAR0 + off); 789 owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 790 PEXOTEAR0 + off); 791 owin.powbar = 0; 792 if (i > 0) { 793 /* Doesn't exist for outbound window 0 */ 794 owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 795 PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off); 796 } 797 owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 798 PEXOWAR0 + off); 799#if 0 800 aprint_normal_dev(self, 801 "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n", 802 i, owin.potar, owin.potear, owin.powbar, owin.powar); 803#endif 804 if (owin.powar & PEXOWAR_EN) { 805 valid_owins++; 806 pq3pci_owin_record(sc, i, &owin); 807 } 808 } 809 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true) 810 || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) { 811 return; 812 } 813#ifndef PCI_NETBSD_CONFIGURE 814 if (valid_owins == 0) { 815 aprint_normal(": %s controller%s\n", buf, 816 " (disabled)"); 817 return; 818 } 819#endif 820 821 u_int valid_iwins = 0; 822 for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) { 823 struct pq3pci_iwin iwin; 824 iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 825 PEXITAR1 + off); 826 iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 827 PEXIWBAR1 + off); 828 if (i > 0) { 829 /* Doesn't exist */ 830 iwin.piwbear = bus_space_read_4(sc->sc_bst, 831 sc->sc_bsh, 832 PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off); 833 } else { 834 iwin.piwbear = 0; 835 } 836 iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 837 PEXIWAR1 + off); 838#if 0 839 aprint_normal_dev(self, 840 "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n", 841 i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar); 842#endif 843 if (iwin.piwar & PEXIWAR_EN) { 844 valid_iwins++; 845 if (!pq3pci_iwin_setup(sc, i, &iwin)) 846 return; 847 } 848 } 849 850 sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM); 851 852 pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc); 853 854#ifndef PCI_NETBSD_CONFIGURE 855 if (valid_iwins == 0) { 856 aprint_normal(": %s controller%s\n", buf, 857 " (disabled)"); 858 return; 859 } 860#else 861 if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) { 862 aprint_normal(": %s controller%s\n", buf, 863 " (offline)"); 864 return; 865 } 866 if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) { 867 aprint_normal(": %s controller%s\n", buf, 868 " (agent mode)"); 869 return; 870 } 871 if (valid_iwins == 0) { 872 struct pq3pci_iwin iwin = { 873 .pitar = 0, 874 .piwbar = 0, 875 .piwbear = 0, 876 .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM 877 |PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP 878 |__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS), 879 }; 880 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar); 881 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar); 882 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear); 883 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar); 884 885 if (!pq3pci_iwin_setup(sc, 2, &iwin)) { 886 aprint_error(": error creating inbound window\n"); 887 return; 888 } 889 890 } 891 892 if (valid_owins == 0) { 893 u_long membase, iobase; 894 error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE, 895 PCI_MEMSIZE, EX_WAITOK, &membase); 896 if (error) { 897 aprint_error( 898 ": error allocating address space for %s: %d\n", 899 "PCI memory", error); 900 return; 901 } 902 struct pq3pci_owin owin1 = { 903 .potar = membase >> 12, 904 .potear = 0, 905 .powbar = membase >> 12, 906 .powar = PEXOWAR_EN|PEXOWAR_TC0 907 |PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM 908 |__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS), 909 }; 910 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar); 911 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear); 912 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar); 913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar); 914 pq3pci_owin_record(sc, 1, &owin1); 915 if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) { 916 return; 917 } 918 919 error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE, 920 PCI_IOSIZE, EX_WAITOK, &iobase); 921 if (error) { 922 aprint_error( 923 ": error allocating address space for %s: %d\n", 924 "PCI I/O space", error); 925 return; 926 } 927 struct pq3pci_owin owin2 = { 928 .potar = 0, 929 .potear = 0, 930 .powbar = iobase >> 12, 931 .powar = PEXOWAR_EN|PEXOWAR_TC0 932 |PEXOWAR_RTT_IO|PEXOWAR_WTT_IO 933 |__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS), 934 }; 935 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar); 936 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear); 937 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar); 938 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar); 939 pq3pci_owin_record(sc, 2, &owin1); 940 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)) { 941 return; 942 } 943 944 struct pciconf_resources *pcires = pciconf_resource_init(); 945 946 pciconf_resource_add(pcires, PCICONF_RESOURCE_IO, 947 0, PCI_IOSIZE); 948 pciconf_resource_add(pcires, PCICONF_RESOURCE_MEM, 949 membase, PCI_MEMSIZE); 950 951 error = pci_configure_bus(pc, pcires, 0, 952 curcpu()->ci_ci.dcache_line_size); 953 954 pciconf_resource_fini(pcires); 955 956 if (error) { 957 aprint_normal(": configuration failed\n"); 958 return; 959 } 960 } 961#endif 962 963 aprint_normal(": %s controller%s\n", buf, ""); 964 965 struct pcibus_attach_args pba; 966 memset(&pba, 0, sizeof(pba)); 967 968 pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY 969 | PCI_FLAGS_MSIX_OKAY; 970 if (pba.pba_flags & PCI_FLAGS_IO_OKAY) 971 pba.pba_iot = pc->pc_iot; 972 if (pba.pba_flags & PCI_FLAGS_MEM_OKAY) 973 pba.pba_memt = pc->pc_memt; 974 pba.pba_dmat = cna->cna_dmat; 975 pba.pba_pc = pc; 976 pba.pba_bus = 0; 977 978 /* 979 * Program BAR0 so that MSIs can work. 980 */ 981 pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset); 982 pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG); 983 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE; 984 pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts); 985 986#if 0 987 /* 988 * 989 */ 990 pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0)); 991#endif 992#if 0 993 if (sc->sc_pcie) 994 pci_conf_print(pc, 0, NULL); 995#endif 996 997 config_found(self, &pba, pcibusprint, CFARGS_NONE); 998} 999 1000static void 1001pq3pci_attach_hook(device_t parent, device_t self, 1002 struct pcibus_attach_args *pba) 1003{ 1004 /* do nothing */ 1005} 1006 1007static int 1008pq3pci_bus_maxdevs(void *v, int busno) 1009{ 1010 struct pq3pci_softc * const sc = v; 1011 return sc->sc_pcie && busno < 2 ? 1 : 32; 1012} 1013 1014static void 1015pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func) 1016{ 1017 if (bus) 1018 *bus = (tag >> 16) & 0xff; 1019 if (dev) 1020 *dev = (tag >> 11) & 0x1f; 1021 if (func) 1022 *func = (tag >> 8) & 0x07; 1023} 1024 1025static pcitag_t 1026pq3pci_make_tag(void *v, int bus, int dev, int func) 1027{ 1028 return (bus << 16) | (dev << 11) | (func << 8); 1029} 1030 1031#if 0 1032static inline pcitag_t 1033pq3pci_config_addr_read(pci_chipset_tag_t pc) 1034{ 1035 pcitag_t v; 1036 __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr)); 1037 __asm volatile("mbar\n\tmsync"); 1038 return v; 1039} 1040#endif 1041 1042static inline void 1043pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v) 1044{ 1045 __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr)); 1046 __asm volatile("mbar\n\tmsync"); 1047} 1048 1049static inline pcireg_t 1050pq3pci_config_data_read(pci_chipset_tag_t pc) 1051{ 1052 pcireg_t v; 1053 __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data)); 1054 __asm volatile("mbar\n\tmsync"); 1055 return v; 1056} 1057 1058static inline void 1059pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v) 1060{ 1061 __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data)); 1062 __asm volatile("mbar\n\tmsync"); 1063} 1064 1065static pcireg_t 1066pq3pci_conf_read(void *v, pcitag_t tag, int reg) 1067{ 1068 struct pq3pci_softc * const sc = v; 1069 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1070 1071 if (reg < 0) 1072 return 0xffffffff; 1073 if (reg >= PCI_CONF_SIZE) { 1074 if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE) 1075 return 0xffffffff; 1076 reg = (reg & 0xff) | ((reg & 0xf00) << 16); 1077 } 1078 if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) { 1079 // pcireg_t slot_status = pci_conf_read(pc, 0, 0x64); 1080 // printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status); 1081 // if ((slot_status & __BIT(6+16)) == 0) 1082 // printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN); 1083 // return 0xffffffff; 1084 } 1085 1086 mutex_spin_enter(sc->sc_conf_lock); 1087 1088 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN); 1089 pcireg_t rv = pq3pci_config_data_read(pc); 1090 1091 mutex_spin_exit(sc->sc_conf_lock); 1092 1093#if 0 1094 uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR); 1095 if (err & PEXERRDR_ICCA) { 1096 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n", 1097 __func__, tag, reg, pq3pci_config_addr_read(pc)); 1098 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR, 1099 PEXERRDR_ICCA); 1100 } 1101#endif 1102 return rv; 1103} 1104 1105static void 1106pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 1107{ 1108 struct pq3pci_softc * const sc = v; 1109 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1110 1111 if (reg < 0) 1112 return; 1113 if (reg >= PCI_CONF_SIZE) { 1114 if (!sc->sc_pcie || reg >= PCI_EXTCONF_SIZE) 1115 return; 1116 reg = (reg & 0xff) | ((reg & 0xf00) << 16); 1117 } 1118 1119 mutex_spin_enter(sc->sc_conf_lock); 1120 1121#if 0 1122 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n", 1123 __func__, tag, reg, data); 1124#endif 1125 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN); 1126 pq3pci_config_data_write(pc, data); 1127 1128 mutex_spin_exit(sc->sc_conf_lock); 1129} 1130 1131#ifdef PCI_NETBSD_CONFIGURE 1132static int 1133pq3pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id) 1134{ 1135 struct pq3pci_softc * const sc = v; 1136 if (sc->sc_pcie && bus != 0) { 1137 pcireg_t slot_status = pci_conf_read(&sc->sc_pc, 0, 0x64); 1138 if ((slot_status & __BIT(6+16)) == 0) 1139 return 0; 1140 } 1141 if (!sc->sc_pcie && bus == 0 && dev == 0) { 1142 return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM); 1143 } 1144 return PCI_CONF_DEFAULT; 1145} 1146#endif 1147 1148static void 1149pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl) 1150{ 1151 char buf[12]; 1152 const char (*intr_names)[8] = msi_intr_names[group]; 1153 1154 KASSERT(ipl == IPL_VM); 1155 KASSERT(mutex_owned(&pq3pci_msigroups_lock)); 1156 1157 msig->msig_group = group; 1158 msig->msig_free_mask = ~0 << (group == 0); 1159 msig->msig_ipl = ipl; 1160 mutex_init(&msig->msig_lock, MUTEX_DEFAULT, ipl); 1161 snprintf(buf, sizeof(buf), "msi %d-%d", group * 32, group * 32 + 31); 1162 msig->msig_ih = intr_establish_xname(msig->msig_group, ipl, 1163 IST_MSIGROUP, pq3pci_msi_intr, msig, buf); 1164 msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group); 1165 for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) { 1166 struct pq3pci_msihand * const msih = msig->msig_ihands + i; 1167 msih->msih_ih.ih_class = IH_MSI; 1168 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr; 1169 msih->msih_ih.ih_arg = msih; 1170 msih->msih_group = msig; 1171 evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR, 1172 NULL, intr_names[i], "intr"); 1173 evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR, 1174 &msih->msih_ev, intr_names[i], "spurious intr"); 1175 } 1176 pq3pci_msigroups[group] = msig; 1177} 1178 1179static struct pq3pci_msihand * 1180pq3pci_msi_lookup(pci_intr_handle_t handle) 1181{ 1182 const int irq = PIH_IRQ(handle); 1183 KASSERT(irq < 256); 1184 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32]; 1185 KASSERT(msig != NULL); 1186 return &msig->msig_ihands[irq & 31]; 1187} 1188 1189static struct pq3pci_msihand * 1190pq3pci_msi_claim(pci_intr_handle_t handle) 1191{ 1192 const int irq = PIH_IRQ(handle); 1193 uint32_t irq_mask = __BIT(irq & 31); 1194 KASSERT(irq < 256); 1195 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32]; 1196 KASSERT(msig != NULL); 1197 struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31]; 1198 mutex_spin_enter(&msig->msig_lock); 1199 msig->msig_free_mask ^= irq_mask; 1200 mutex_spin_exit(&msig->msig_lock); 1201 return msih; 1202} 1203 1204static pci_intr_handle_t 1205pq3pci_msi_alloc_one(int ipl) 1206{ 1207 size_t freegroup = 0; 1208 const size_t maplen = __arraycount(pq3pci_msigroups); 1209 uint32_t bitmap[maplen]; 1210 pci_intr_handle_t handle; 1211 1212 mutex_spin_enter(&pq3pci_msigroups_lock); 1213 for (u_int i = 0; i < maplen; i++) { 1214 struct pq3pci_msigroup * const msig = pq3pci_msigroups[i]; 1215 if (msig == NULL) { 1216 bitmap[i] = 0; 1217 if (freegroup == 0) 1218 freegroup = i + 1; 1219 continue; 1220 } 1221 /* 1222 * If this msigroup has the wrong IPL or there's nothing 1223 * free, try the next one. 1224 */ 1225 if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) { 1226 bitmap[i] = 0; 1227 continue; 1228 } 1229 1230 bitmap[i] = msig->msig_free_mask; 1231 } 1232 for (u_int i = 0; i < maplen; i++) { 1233 uint32_t mapbits = bitmap[i]; 1234 u_int n = ffs(mapbits); 1235 if (n--) { 1236 handle = PIH_MAKE(i * 32 + n, IST_MSI, 0); 1237 struct pq3pci_msihand * const msih __diagused = 1238 pq3pci_msi_claim(handle); 1239 KASSERT(msih != NULL); 1240 mutex_spin_exit(&pq3pci_msigroups_lock); 1241 return handle; 1242 } 1243 } 1244 1245 if (freegroup-- == 0) { 1246 mutex_spin_exit(&pq3pci_msigroups_lock); 1247 return 0; 1248 } 1249 1250 struct pq3pci_msigroup * const msig = 1251 kmem_zalloc(sizeof(*msig), KM_NOSLEEP); 1252 if (msig == NULL) { 1253 mutex_spin_exit(&pq3pci_msigroups_lock); 1254 return 0; 1255 } 1256 pq3pci_msi_group_setup(msig, freegroup, ipl); 1257 u_int n = ffs(msig->msig_free_mask) - 1; 1258 handle = PIH_MAKE(freegroup * 32 + n, IST_MSI, 0); 1259 struct pq3pci_msihand * const msih __diagused = 1260 pq3pci_msi_claim(handle); 1261 KASSERT(msih != NULL); 1262 mutex_spin_exit(&pq3pci_msigroups_lock); 1263 return handle; 1264} 1265 1266static int 1267pq3pci_msi_alloc_vectors(struct pq3pci_softc *sc, 1268 const struct pci_attach_args *pa, pci_intr_handle_t **ihps, int count) 1269{ 1270 pci_intr_handle_t *vectors; 1271 struct pq3pci_msihand * msih; 1272 pcireg_t msictl; 1273 int msioff; 1274 1275 *ihps = NULL; 1276 1277 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI, &msioff, 1278 NULL)) 1279 return ENODEV; 1280 1281 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff); 1282 msictl &= ~PCI_MSI_CTL_MSI_ENABLE; 1283 msictl &= ~PCI_MSI_CTL_MME_MASK; 1284 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl); 1285 1286 const size_t alloc_size = sizeof(*vectors) * count; 1287 vectors = kmem_zalloc(alloc_size, KM_SLEEP); 1288 1289 for (int i = 0; i < count; ++i) { 1290 pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM); 1291 if (handle == 0) { 1292 for (int j = i - 1; j >= 0; j--) { 1293 msih = pq3pci_msi_claim(vectors[j]); 1294 msih->msih_tag = 0; 1295 msih->msih_msioff = 0; 1296 } 1297 kmem_free(vectors, alloc_size); 1298 return EBUSY; 1299 } 1300 vectors[i] = handle; 1301 1302 msih = pq3pci_msi_lookup(handle); 1303 msih->msih_tag = pa->pa_tag; 1304 msih->msih_msioff = msioff; 1305 } 1306 1307 *ihps = vectors; 1308 return 0; 1309} 1310 1311static void 1312pq3pci_msi_free_vectors(struct pq3pci_softc *sc, pci_intr_handle_t *ihp, 1313 int count) 1314{ 1315 1316 KASSERT(count > 0); 1317 1318 for (int i = 0; i < count; ++i) { 1319 struct pq3pci_msihand * const msih __diagused = 1320 pq3pci_msi_claim(ihp[i]); 1321 KASSERT(msih != NULL); 1322 } 1323 kmem_free(ihp, sizeof(*ihp) * count); 1324} 1325 1326static struct pq3pci_intrsource * 1327pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle) 1328{ 1329 struct pq3pci_intrsource *pis; 1330 mutex_spin_enter(&pq3pci_intrsources_lock); 1331 SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) { 1332 if (pis->pis_handle == handle) { 1333 mutex_spin_exit(&pq3pci_intrsources_lock); 1334 return pis; 1335 } 1336 } 1337 pis = kmem_zalloc(sizeof(*pis), KM_NOSLEEP); 1338 if (pis != NULL) 1339 pq3pci_intr_source_setup(sc, pis, handle); 1340 mutex_spin_exit(&pq3pci_intrsources_lock); 1341 return pis; 1342} 1343 1344static pci_intr_handle_t 1345pq3pci_intr_handle_lookup(struct pq3pci_softc *sc, 1346 const struct pci_attach_args *pa) 1347{ 1348 prop_dictionary_t entry; 1349 1350#ifndef PQ3PCI_INTR_MAP_NO_USE_MSI 1351 if (sc->sc_pcie) do { 1352 pcireg_t msictl; 1353 int msioff; 1354 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI, 1355 &msioff, NULL)) 1356 break; 1357 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff); 1358 msictl &= ~PCI_MSI_CTL_MSI_ENABLE; 1359 msictl &= ~PCI_MSI_CTL_MME_MASK; 1360 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl); 1361 pci_intr_handle_t handle = pq3pci_msi_alloc_one(IPL_VM); 1362 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle); 1363 msih->msih_tag = pa->pa_tag; 1364 msih->msih_msioff = msioff; 1365 return handle; 1366 } while (false); 1367#endif 1368 1369 if (sc->sc_intrmask == 0) { 1370 entry = prop_dictionary_get(sc->sc_intrmap, "000000"); 1371 } else { 1372 char prop_name[8]; 1373 u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask); 1374 pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc; 1375 1376 snprintf(prop_name, sizeof(prop_name), "%06x", 1377 tag & sc->sc_intrmask); 1378 1379#if 0 1380 printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n", 1381 __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin, 1382 tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name); 1383#endif 1384 1385 entry = prop_dictionary_get(sc->sc_intrmap, prop_name); 1386 } 1387 KASSERT(entry != NULL); 1388 KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY); 1389 1390 prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt"); 1391 KASSERT(pn_irq != NULL); 1392 KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER); 1393 int irq = prop_number_unsigned_integer_value(pn_irq); 1394 prop_number_t pn_ist = prop_dictionary_get(entry, "type"); 1395 KASSERT(pn_ist != NULL); 1396 KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER); 1397 int ist = prop_number_unsigned_integer_value(pn_ist); 1398 1399 return PIH_MAKE(irq, ist, 0); 1400} 1401 1402static int 1403pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep) 1404{ 1405 struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v; 1406 1407 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE) 1408 return ENOENT; 1409 1410 *handlep = pq3pci_intr_handle_lookup(sc, pa); 1411 1412 return 0; 1413} 1414 1415static const char * 1416pq3pci_intr_string(void *v, pci_intr_handle_t handle, char *buf, size_t len) 1417{ 1418 if (PIH_IST(handle) == IST_MSI) { 1419 const char (*intr_names)[8] = msi_intr_names[0]; 1420 strlcpy(buf, intr_names[PIH_IRQ(handle)], len); 1421 return buf; 1422 } 1423 1424 return intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, len); 1425} 1426 1427static const struct evcnt * 1428pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle) 1429{ 1430 struct pq3pci_softc * const sc = v; 1431 if (PIH_IST(handle) == IST_MSI) { 1432 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle); 1433 1434 KASSERT(msih != NULL); 1435 1436 return &msih->msih_ev; 1437 } 1438 struct pq3pci_intrsource * const pis = 1439 pq3pci_intr_source_lookup(sc, handle); 1440 if (pis != NULL) 1441 return &pis->pis_ev; 1442 return NULL; 1443} 1444 1445static void * 1446pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl, 1447 int (*func)(void *), void *arg, const char *xname) 1448{ 1449 struct pq3pci_softc * const sc = v; 1450 const int ist = PIH_IST(handle); 1451 1452 if (ist == IST_MSI) { 1453 pci_chipset_tag_t pc = &sc->sc_pc; 1454 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle); 1455 pcireg_t cmdsts, msictl; 1456 1457 if (msih == NULL) 1458 return NULL; 1459 1460 struct pq3pci_msigroup * const msig = msih->msih_group; 1461 const pcitag_t tag = msih->msih_tag; 1462 1463 mutex_spin_enter(&msig->msig_lock); 1464 msih->msih_ih.ih_class = IH_MSI; 1465 msih->msih_ih.ih_arg = arg; 1466 msih->msih_ih.ih_func = func; 1467 msih->msih_ih.ih_sc = sc; 1468 1469 int off = msih->msih_msioff; 1470 msictl = pci_conf_read(pc, tag, off); 1471 1472 /* 1473 * The PCSRBAR has already been setup as a 1:1 BAR so we point 1474 * MSIs at the MSII register in the OpenPIC. 1475 */ 1476 off += 4; 1477 pci_conf_write(pc, tag, off, 1478 sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR); 1479 1480 /* 1481 * Upper address is going to be 0. 1482 */ 1483 if (msictl & PCI_MSI_CTL_64BIT_ADDR) { 1484 off += 4; 1485 pci_conf_write(pc, tag, off, 0); 1486 } 1487 1488 /* 1489 * Set the magic value. Since PCI writes this to the least 1490 * significant byte of AD[31:0], let's hope the bridge byte 1491 * swaps to so it's the most significant bytes or nothing is 1492 * going to happen. 1493 */ 1494 off += 4; 1495 pci_conf_write(pc, tag, off, PIH_IRQ(handle)); 1496 1497 /* 1498 * Should the driver do this? How would it know to do it? 1499 */ 1500 if (msictl & PCI_MSI_CTL_PERVEC_MASK) { 1501 off += 4; 1502 pci_conf_write(pc, tag, off, 0); 1503 } 1504 1505 /* 1506 * Let's make sure he won't raise any INTx. Technically 1507 * setting MSI enable will prevent that as well but might 1508 * as well be as safe as possible. 1509 */ 1510 cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 1511 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE; 1512 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts); 1513 1514#if 1 1515 /* 1516 * Now we can enable the MSI 1517 */ 1518 msictl |= PCI_MSI_CTL_MSI_ENABLE; 1519 pci_conf_write(pc, tag, msih->msih_msioff, msictl); 1520#endif 1521 1522 mutex_spin_exit(&msig->msig_lock); 1523 1524 return msih; 1525 } 1526 1527 struct pq3pci_intrsource * const pis = 1528 pq3pci_intr_source_lookup(sc, handle); 1529 if (pis == NULL) 1530 return NULL; 1531 1532 struct pq3pci_intrhand * const pih = 1533 kmem_zalloc(sizeof(*pih), KM_SLEEP); 1534 pih->pih_ih.ih_class = IH_INTX; 1535 pih->pih_ih.ih_func = func; 1536 pih->pih_ih.ih_arg = arg; 1537 pih->pih_ih.ih_sc = sc; 1538 pih->pih_ipl = ipl; 1539 pih->pih_source = pis; 1540 1541 mutex_spin_enter(&pis->pis_lock); 1542 SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link); 1543 mutex_spin_exit(&pis->pis_lock); 1544 1545 return pih; 1546} 1547 1548static void 1549pq3pci_intr_disestablish(void *v, void *ih) 1550{ 1551 struct pq3pci_genihand * const gih = ih; 1552 1553 if (gih->ih_class == IH_INTX) { 1554 struct pq3pci_intrhand * const pih = ih; 1555 struct pq3pci_intrsource * const pis = pih->pih_source; 1556 1557 mutex_spin_enter(&pis->pis_lock); 1558 SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link); 1559 mutex_spin_exit(&pis->pis_lock); 1560 1561 kmem_free(pih, sizeof(*pih)); 1562 return; 1563 } 1564 1565 struct pq3pci_msihand * const msih = ih; 1566 struct pq3pci_msigroup * const msig = msih->msih_group; 1567 struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc; 1568 const pcitag_t tag = msih->msih_tag; 1569 1570 mutex_spin_enter(&msig->msig_lock); 1571 1572 /* 1573 * disable the MSI 1574 */ 1575 pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff); 1576 msictl &= ~PCI_MSI_CTL_MSI_ENABLE; 1577 pci_conf_write(pc, tag, msih->msih_msioff, msictl); 1578 1579 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr; 1580 msih->msih_ih.ih_arg = msig; 1581 msih->msih_ih.ih_sc = NULL; 1582 msih->msih_tag = 0; 1583 msih->msih_msioff = 0; 1584 mutex_spin_exit(&msig->msig_lock); 1585} 1586 1587static pci_intr_type_t 1588pq3pci_intr_type(void *v, pci_intr_handle_t handle) 1589{ 1590 const int ist = PIH_IST(handle); 1591 1592 if (ist == IST_MSI) 1593 return PCI_INTR_TYPE_MSI; 1594 return PCI_INTR_TYPE_INTX; 1595} 1596 1597static int 1598pq3pci_intr_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 1599 int *counts, pci_intr_type_t max_type) 1600{ 1601 int cnt[PCI_INTR_TYPE_SIZE]; 1602 int error; 1603 1604 memset(cnt, 0, sizeof(cnt)); 1605 if (counts == NULL) { 1606 /* simple pattern */ 1607 cnt[PCI_INTR_TYPE_INTX] = 1; 1608 cnt[PCI_INTR_TYPE_MSI] = 1; 1609 } else { 1610 switch (max_type) { 1611 case PCI_INTR_TYPE_MSIX: 1612 cnt[PCI_INTR_TYPE_MSIX] = counts[PCI_INTR_TYPE_MSIX]; 1613 /*FALLTHROUGH*/ 1614 case PCI_INTR_TYPE_MSI: 1615 cnt[PCI_INTR_TYPE_MSI] = counts[PCI_INTR_TYPE_MSI]; 1616 /*FALLTHROUGH*/ 1617 case PCI_INTR_TYPE_INTX: 1618 cnt[PCI_INTR_TYPE_INTX] = counts[PCI_INTR_TYPE_INTX]; 1619 break; 1620 default: 1621 return EINVAL; 1622 } 1623 } 1624 1625 if (counts != NULL) 1626 memset(counts, 0, sizeof(counts[0]) * (max_type + 1)); 1627 error = EINVAL; 1628 1629 /* try MSI-X */ 1630 if (cnt[PCI_INTR_TYPE_MSIX] == -1) /* use hardware max */ 1631 cnt[PCI_INTR_TYPE_MSIX] = pci_msix_count(pa->pa_pc, pa->pa_tag); 1632 if (cnt[PCI_INTR_TYPE_MSIX] > 0) { 1633 error = pci_msix_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSIX]); 1634 if (error == 0) { 1635 KASSERTMSG(counts != NULL, 1636 "If MSI-X is used, counts must not be NULL."); 1637 counts[PCI_INTR_TYPE_MSIX] = cnt[PCI_INTR_TYPE_MSIX]; 1638 goto out; 1639 } 1640 } 1641 1642 /* try MSI */ 1643 if (cnt[PCI_INTR_TYPE_MSI] == -1) /* use hardware max */ 1644 cnt[PCI_INTR_TYPE_MSI] = pci_msi_count(pa->pa_pc, pa->pa_tag); 1645 if (cnt[PCI_INTR_TYPE_MSI] > 0) { 1646 error = pci_msi_alloc_exact(pa, ihps, cnt[PCI_INTR_TYPE_MSI]); 1647 if (error == 0) { 1648 if (counts != NULL) { 1649 counts[PCI_INTR_TYPE_MSI] = 1650 cnt[PCI_INTR_TYPE_MSI]; 1651 } 1652 goto out; 1653 } 1654 } 1655 1656 /* try INTx */ 1657 if (cnt[PCI_INTR_TYPE_INTX] > 0) { 1658 error = pci_intx_alloc(pa, ihps); 1659 if (error == 0 && counts != NULL) { 1660 counts[PCI_INTR_TYPE_INTX] = 1; 1661 } 1662 } 1663 1664 out: 1665 return error; 1666} 1667 1668static void 1669pq3pci_intr_release(void *v, pci_intr_handle_t *ihps, int count) 1670{ 1671 1672 if (ihps == NULL) 1673 return; 1674 1675 const int ist = PIH_IST(*ihps); 1676 if (ist == IST_MSI) 1677 pq3pci_msi_free_vectors(v, ihps, count); 1678 else 1679 genppc_pci_intr_release(v, ihps, count); 1680} 1681 1682static void 1683pq3pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline) 1684{ 1685} 1686 1687/* experimental MSI support */ 1688 1689/* 1690 * This function is used by device drivers like pci_intr_map(). 1691 * 1692 * "ihps" is the array of vector numbers which MSI used instead of IRQ number. 1693 * "count" must be power of 2. 1694 * "count" can decrease if struct intrsource cannot be allocated. 1695 * if count == 0, return non-zero value. 1696 */ 1697static int 1698pq3pci_msi_alloc(const struct pci_attach_args *pa, pci_intr_handle_t **ihps, 1699 int *count, bool exact) 1700{ 1701 struct pq3pci_softc * const sc = pa->pa_pc->pc_msi_v; 1702 int hw_max; 1703 int error; 1704 1705 if (*count < 1) 1706 return EINVAL; 1707 if (((*count - 1) & *count) != 0) 1708 return EINVAL; 1709 1710 hw_max = pci_msi_count(pa->pa_pc, pa->pa_tag); 1711 if (hw_max == 0) 1712 return ENODEV; 1713 1714 if (*count > hw_max) 1715 *count = hw_max; 1716 1717 *ihps = NULL; 1718 for (; *count > 0; (*count) >>= 1) { 1719 error = pq3pci_msi_alloc_vectors(sc, pa, ihps, *count); 1720 if (error == 0) 1721 break; 1722 if (exact) 1723 return error; 1724 } 1725 if (*ihps == NULL) 1726 return ENXIO; 1727 1728 return 0; 1729} 1730 1731static pci_chipset_tag_t 1732pq3pci_pci_chipset_init(struct pq3pci_softc *sc) 1733{ 1734 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1735 1736 pc->pc_conf_v = sc; 1737 pc->pc_attach_hook = pq3pci_attach_hook; 1738 pc->pc_bus_maxdevs = pq3pci_bus_maxdevs; 1739 pc->pc_make_tag = pq3pci_make_tag; 1740 pc->pc_conf_read = pq3pci_conf_read; 1741 pc->pc_conf_write = pq3pci_conf_write; 1742#ifdef PCI_NETBSD_CONFIGURE 1743 pc->pc_conf_hook = pq3pci_conf_hook; 1744#endif 1745 1746 pc->pc_intr_v = sc; 1747 pc->pc_intr_map = pq3pci_intr_map; 1748 pc->pc_intr_string = pq3pci_intr_string; 1749 pc->pc_intr_evcnt = pq3pci_intr_evcnt; 1750 pc->pc_intr_establish = pq3pci_intr_establish; 1751 pc->pc_intr_disestablish = pq3pci_intr_disestablish; 1752 pc->pc_intr_type = pq3pci_intr_type; 1753 pc->pc_intr_alloc = pq3pci_intr_alloc; 1754 pc->pc_intr_release = pq3pci_intr_release; 1755 pc->pc_intr_setattr = genppc_pci_intr_setattr; 1756 pc->pc_intx_alloc = genppc_pci_intx_alloc; 1757 1758 pc->pc_msi_v = sc; 1759 pc->pc_msi_alloc = pq3pci_msi_alloc; 1760 1761 pc->pc_msix_v = sc; 1762 genppc_pci_chipset_msix_init(pc); 1763 1764 pc->pc_conf_interrupt = pq3pci_conf_interrupt; 1765 pc->pc_decompose_tag = pq3pci_decompose_tag; 1766 1767 /* 1768 * This is a horrible kludge but it makes life easier. 1769 */ 1770 pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR); 1771 pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA); 1772 pc->pc_bus = 0; 1773 pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag; 1774 pc->pc_iot = &sc->sc_pci_io_bst.bs_tag; 1775 1776 SIMPLEQ_INIT(&pc->pc_pbi); 1777 1778 return pc; 1779} 1780