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