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