pq3pci.c revision 1.17
1/* $NetBSD: pq3pci.c,v 1.17 2014/07/30 10:50:54 joerg 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.17 2014/07/30 10:50:54 joerg 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 100const 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 176static const struct e500_truthtab pq3pci_pci_pcix[] = { 177#ifdef MPC8548 178 PORDEVSR_TRUTH_ENCODE(SVR_MPC8548v1, 1, PCI1, PCIX, 1), 179#endif 180}; 181 182static 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 194struct 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 204typedef enum { IH_NONE, IH_INTX, IH_MSI, IH_MSIX } pq3pci_intr_class_t; 205 206struct 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 213struct 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 221struct 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 232struct 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 242struct 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 251struct 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 261struct 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 278static int pq3pci_cpunode_match(device_t, cfdata_t, void *aux); 279static void pq3pci_cpunode_attach(device_t, device_t, void *aux); 280static pci_chipset_tag_t pq3pci_pci_chipset_init(struct pq3pci_softc *); 281 282static SIMPLEQ_HEAD(,pq3pci_intrsource) pq3pci_intrsources 283 = SIMPLEQ_HEAD_INITIALIZER(pq3pci_intrsources); 284static struct pq3pci_msigroup *pq3pci_msigroups[8]; 285 286static struct pq3pci_intrsource * 287 pq3pci_intr_source_lookup(struct pq3pci_softc *, pci_intr_handle_t); 288 289static 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 365CFATTACH_DECL_NEW(pq3pci_cpunode, sizeof(struct pq3pci_softc), 366 pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL); 367 368CFATTACH_DECL_NEW(pq3pcie_cpunode, sizeof(struct pq3pci_softc), 369 pq3pci_cpunode_match, pq3pci_cpunode_attach, NULL, NULL); 370 371int 372pq3pci_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 381struct pq3pci_owin { 382 uint32_t potar; 383 uint32_t potear; 384 uint32_t powbar; 385 uint32_t powar; 386}; 387 388static void 389pq3pci_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 431static bool 432pq3pci_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 475struct pq3pci_iwin { 476 uint32_t pitar; 477 uint32_t piwbar; 478 uint32_t piwbear; 479 uint32_t piwar; 480}; 481 482static bool 483pq3pci_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 540static void 541pq3pci_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 551static int 552pq3pci_msi_spurious_intr(void *v) 553{ 554 (void) v; 555 556 return 0; 557} 558 559static int 560pq3pci_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 623static int 624pq3pci_onchip_intr(void *v) 625{ 626 panic(__func__); 627} 628 629static int 630pq3pci_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 662static void 663pq3pci_intr_source_setup(struct pq3pci_softc *sc, 664 struct pq3pci_intrsource *pis, pci_intr_handle_t handle) 665{ 666 char buf[PCI_INTRSTR_LEN]; 667 SIMPLEQ_INIT(&pis->pis_ihands); 668 pis->pis_handle = handle; 669 pis->pis_ih = intr_establish(PIH_IRQ(handle), IPL_VM, PIH_IST(handle), 670 pq3pci_pis_intr, pis); 671 pis->pis_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM); 672 const char * const intrstr 673 = intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, sizeof(buf)); 674 evcnt_attach_dynamic(&pis->pis_ev, EVCNT_TYPE_INTR, 675 NULL, intrstr, "intr"); 676 evcnt_attach_dynamic(&pis->pis_ev_spurious, EVCNT_TYPE_INTR, 677 &pis->pis_ev, intrstr, "spurious intr"); 678 SIMPLEQ_INSERT_TAIL(&pq3pci_intrsources, pis, pis_link); 679} 680 681static bool 682pq3pci_intrmap_setup(struct pq3pci_softc *sc, 683 const struct cpunode_locators *cnl) 684{ 685 char prop_name[32]; 686 snprintf(prop_name, sizeof(prop_name), "%s%u-interrupt-map", 687 cnl->cnl_name, cnl->cnl_instance); 688 sc->sc_intrmap = board_info_get_object(prop_name); 689 if (sc->sc_intrmap == NULL) { 690 aprint_error(": missing %s board property", prop_name); 691 return false; 692 } 693 694 KASSERT(prop_object_type(sc->sc_intrmap) == PROP_TYPE_DICTIONARY); 695 prop_number_t pn = prop_dictionary_get(sc->sc_intrmap, "interrupt-mask"); 696 KASSERT(pn != NULL); 697 698 sc->sc_intrmask = prop_number_unsigned_integer_value(pn); 699 700 sc->sc_ih = intr_establish(cnl->cnl_intrs[0], IPL_VM, IST_ONCHIP, 701 pq3pci_onchip_intr, sc); 702 if (sc->sc_ih == NULL) 703 panic("%s: failed to establish interrupt %d\n", 704 device_xname(sc->sc_dev), cnl->cnl_intrs[0]); 705 706 return true; 707} 708 709void 710pq3pci_cpunode_attach(device_t parent, device_t self, void *aux) 711{ 712 struct cpunode_softc * const psc = device_private(parent); 713 struct pq3pci_softc * const sc = device_private(self); 714 struct cpunode_attach_args * const cna = aux; 715 struct cpunode_locators * const cnl = &cna->cna_locs; 716 char buf[32]; 717 718 sc->sc_dev = self; 719 sc->sc_bst = cna->cna_memt; 720 psc->sc_children |= cna->cna_childmask; 721 sc->sc_pcie = strcmp(cnl->cnl_name, "pcie") == 0; 722 723 const uint32_t pordevsr = cpu_read_4(GLOBAL_BASE + PORDEVSR); 724 if (sc->sc_pcie) { 725 u_int lanes = e500_truth_decode(cnl->cnl_instance, pordevsr, 726 pq3pci_pcie_lanes, __arraycount(pq3pci_pcie_lanes), 0); 727 if (lanes == 0) { 728 aprint_normal(": disabled\n"); 729 return; 730 } 731 snprintf(buf, sizeof(buf), "PCI-Express x%u", lanes); 732 } else { 733 bool pcix_p = e500_truth_decode(cnl->cnl_instance, pordevsr, 734 pq3pci_pci_pcix, __arraycount(pq3pci_pci_pcix), 0); 735 u_int width = e500_truth_decode(cnl->cnl_instance, pordevsr, 736 pq3pci_pci_pci32, __arraycount(pq3pci_pci_pci32), 32); 737 snprintf(buf, sizeof(buf), "%u-bit PCI%s", 738 width, (pcix_p ? "X" : "")); 739 } 740 741 if (!pq3pci_intrmap_setup(sc, cnl)) 742 return; 743 744 evcnt_attach_dynamic(&sc->sc_ev_spurious, EVCNT_TYPE_INTR, NULL, 745 device_xname(self), "spurious intr"); 746 747 int error = bus_space_map(sc->sc_bst, cnl->cnl_addr, cnl->cnl_size, 0, 748 &sc->sc_bsh); 749 if (error) { 750 aprint_error(": failed to map registers: %d\n", error); 751 return; 752 } 753 754 u_int valid_owins = 0; 755 for (u_int i = 1, off = PEXOTAR1 - PEXOTAR0; 756 i < 4; i++, off += PEXOTAR1 - PEXOTAR0) { 757 struct pq3pci_owin owin; 758 owin.potar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 759 PEXOTAR0 + off); 760 owin.potear = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 761 PEXOTEAR0 + off); 762 owin.powbar = 0; 763 if (i > 0) { 764 /* Doesn't exist for outbound window 0 */ 765 owin.powbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 766 PEXOWBAR1 - (PEXOTAR1 - PEXOTAR0) + off); 767 } 768 owin.powar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 769 PEXOWAR0 + off); 770#if 0 771 aprint_normal_dev(self, 772 "owin[%u]: potar=%#x potear=%#x powbar=%#x powar=%#x\n", 773 i, owin.potar, owin.potear, owin.powbar, owin.powar); 774#endif 775 if (owin.powar & PEXOWAR_EN) { 776 valid_owins++; 777 pq3pci_owin_record(sc, i, &owin); 778 } 779 } 780 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true) 781 || !pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) { 782 return; 783 } 784#ifndef PCI_NETBSD_CONFIGURE 785 if (valid_owins == 0) { 786 aprint_normal(": %s controller%s\n", buf, 787 " (disabled)"); 788 return; 789 } 790#endif 791 792 u_int valid_iwins = 0; 793 for (u_int i = 0, off = 0; i < 3; i++, off += PEXITAR2 - PEXITAR1) { 794 struct pq3pci_iwin iwin; 795 iwin.pitar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 796 PEXITAR1 + off); 797 iwin.piwbar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 798 PEXIWBAR1 + off); 799 if (i > 0) { 800 /* Doesn't exist */ 801 iwin.piwbear = bus_space_read_4(sc->sc_bst, 802 sc->sc_bsh, 803 PEXIWBEAR2 - (PEXITAR2 - PEXITAR1) + off); 804 } else { 805 iwin.piwbear = 0; 806 } 807 iwin.piwar = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 808 PEXIWAR1 + off); 809#if 0 810 aprint_normal_dev(self, 811 "iwin[%u]: pitar=%#x piwbar=%#x piwbear=%#x piwar=%#x\n", 812 i, iwin.pitar, iwin.piwbar, iwin.piwbear, iwin.piwar); 813#endif 814 if (iwin.piwar & PEXIWAR_EN) { 815 valid_iwins++; 816 if (!pq3pci_iwin_setup(sc, i, &iwin)) 817 return; 818 } 819 } 820 821 sc->sc_conf_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_VM); 822 823 pci_chipset_tag_t pc = pq3pci_pci_chipset_init(sc); 824 825#ifndef PCI_NETBSD_CONFIGURE 826 if (valid_iwins == 0) { 827 aprint_normal(": %s controller%s\n", buf, 828 " (disabled)"); 829 return; 830 } 831#else 832 if (sc->sc_pcie && pci_conf_read(pc, 0, PEX_LTSSM) < LTSSM_L0) { 833 aprint_normal(": %s controller%s\n", buf, 834 " (offline)"); 835 return; 836 } 837 if (!sc->sc_pcie && (pci_conf_read(pc, 0, PCI_PBFR) & PBFR_PAH)) { 838 aprint_normal(": %s controller%s\n", buf, 839 " (agent mode)"); 840 return; 841 } 842 if (valid_iwins == 0) { 843 struct pq3pci_iwin iwin = { 844 .pitar = 0, 845 .piwbar = 0, 846 .piwbear = 0, 847 .piwar = PEXIWAR_EN|PEXIWAR_PF|PEXIWAR_TRGT_LOCALMEM 848 |PEXIWAR_RTT_MEM_SNOOP|PEXIWAR_WTT_MEM_SNOOP 849 |__SHIFTIN(30-__builtin_clz(pmemsize),PEXIWAR_IWS), 850 }; 851 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXITAR2, iwin.pitar); 852 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBAR2, iwin.piwbar); 853 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWBEAR2, iwin.piwbear); 854 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXIWAR2, iwin.piwar); 855 856 if (!pq3pci_iwin_setup(sc, 2, &iwin)) { 857 aprint_error(": error creating inbound window\n"); 858 return; 859 } 860 861 } 862 863 if (valid_owins == 0) { 864 u_long membase, iobase; 865 error = extent_alloc(pcimem_ex, PCI_MEMSIZE, PCI_MEMSIZE, 866 PCI_MEMSIZE, EX_WAITOK, &membase); 867 if (error) { 868 aprint_error( 869 ": error allocating address space for %s: %d\n", 870 "PCI memory", error); 871 return; 872 } 873 struct pq3pci_owin owin1 = { 874 .potar = membase >> 12, 875 .potear = 0, 876 .powbar = membase >> 12, 877 .powar = PEXOWAR_EN|PEXOWAR_TC0 878 |PEXOWAR_RTT_MEM|PEXOWAR_WTT_MEM 879 |__SHIFTIN(ilog2(PCI_MEMSIZE)-1,PEXOWAR_OWS), 880 }; 881 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR1, owin1.potar); 882 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR1, owin1.potear); 883 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR1, owin1.powbar); 884 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR1, owin1.powar); 885 pq3pci_owin_record(sc, 1, &owin1); 886 if (!pq3pci_owin_init(sc, &sc->sc_pci_mem_bst, false)) { 887 return; 888 } 889 890 error = extent_alloc(pciio_ex, PCI_IOSIZE, PCI_IOSIZE, 891 PCI_IOSIZE, EX_WAITOK, &iobase); 892 if (error) { 893 aprint_error( 894 ": error allocating address space for %s: %d\n", 895 "PCI I/O space", error); 896 return; 897 } 898 struct pq3pci_owin owin2 = { 899 .potar = 0, 900 .potear = 0, 901 .powbar = iobase >> 12, 902 .powar = PEXOWAR_EN|PEXOWAR_TC0 903 |PEXOWAR_RTT_IO|PEXOWAR_WTT_IO 904 |__SHIFTIN(ilog2(PCI_IOSIZE)-1,PEXOWAR_OWS), 905 }; 906 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTAR2, owin2.potar); 907 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOTEAR2, owin2.potear); 908 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWBAR2, owin2.powbar); 909 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEXOWAR2, owin2.powar); 910 pq3pci_owin_record(sc, 2, &owin1); 911 if (!pq3pci_owin_init(sc, &sc->sc_pci_io_bst, true)) { 912 return; 913 } 914 915 struct extent *ioext = extent_create("pciio", 0, PCI_IOSIZE, 916 NULL, 0, EX_NOWAIT); 917 struct extent *memext = extent_create("pcimem", membase, 918 membase + PCI_MEMSIZE, NULL, 0, EX_NOWAIT); 919 920 error = pci_configure_bus(pc, ioext, memext, NULL, 0, 921 curcpu()->ci_ci.dcache_line_size); 922 923 extent_destroy(ioext); 924 extent_destroy(memext); 925 926 if (error) { 927 aprint_normal(": configuration failed\n"); 928 return; 929 } 930 } 931#endif 932 933 aprint_normal(": %s controller%s\n", buf, ""); 934 935 struct pcibus_attach_args pba; 936 memset(&pba, 0, sizeof(pba)); 937 938 pba.pba_flags = sc->sc_pba_flags | PCI_FLAGS_MSI_OKAY 939 | PCI_FLAGS_MSIX_OKAY; 940 if (pba.pba_flags & PCI_FLAGS_IO_OKAY) 941 pba.pba_iot = pc->pc_iot; 942 if (pba.pba_flags & PCI_FLAGS_MEM_OKAY) 943 pba.pba_memt = pc->pc_memt; 944 pba.pba_dmat = cna->cna_dmat; 945 pba.pba_pc = pc; 946 pba.pba_bus = 0; 947 948 /* 949 * Program BAR0 so that MSIs can work. 950 */ 951 pci_conf_write(pc, 0, PCI_BAR0, sc->sc_bst->pbs_offset); 952 pcireg_t cmdsts = pci_conf_read(pc, 0, PCI_COMMAND_STATUS_REG); 953 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE; 954 pci_conf_write(pc, 0, PCI_COMMAND_STATUS_REG, cmdsts); 955 956#if 0 957 /* 958 * 959 */ 960 pq3pci_intr_source_lookup(sc, PIH_MAKE(0, IST_LEVEL, 0)); 961#endif 962#if 0 963 if (sc->sc_pcie) 964 pci_conf_print(pc, 0, NULL); 965#endif 966 967 config_found_ia(self, "pcibus", &pba, pcibusprint); 968} 969 970static void 971pq3pci_attach_hook(device_t parent, device_t self, 972 struct pcibus_attach_args *pba) 973{ 974 /* do nothing */ 975} 976 977static int 978pq3pci_bus_maxdevs(void *v, int busno) 979{ 980 struct pq3pci_softc * const sc = v; 981 return sc->sc_pcie && busno < 2 ? 1 : 32; 982} 983 984static void 985pq3pci_decompose_tag(void *v, pcitag_t tag, int *bus, int *dev, int *func) 986{ 987 if (bus) 988 *bus = (tag >> 16) & 0xff; 989 if (dev) 990 *dev = (tag >> 11) & 0x1f; 991 if (func) 992 *func = (tag >> 8) & 0x07; 993} 994 995static pcitag_t 996pq3pci_make_tag(void *v, int bus, int dev, int func) 997{ 998 return (bus << 16) | (dev << 11) | (func << 8); 999} 1000 1001#if 0 1002static inline pcitag_t 1003pq3pci_config_addr_read(pci_chipset_tag_t pc) 1004{ 1005 pcitag_t v; 1006 __asm volatile("lwz\t%0, 0(%1)" : "=r"(v) : "b"(pc->pc_addr)); 1007 __asm volatile("mbar\n\tmsync"); 1008 return v; 1009} 1010#endif 1011 1012static inline void 1013pq3pci_config_addr_write(pci_chipset_tag_t pc, pcitag_t v) 1014{ 1015 __asm volatile("stw\t%0, 0(%1)" :: "r"(v), "b"(pc->pc_addr)); 1016 __asm volatile("mbar\n\tmsync"); 1017} 1018 1019static inline pcireg_t 1020pq3pci_config_data_read(pci_chipset_tag_t pc) 1021{ 1022 pcireg_t v; 1023 __asm volatile("lwbrx\t%0, 0, %1" : "=r"(v) : "b"(pc->pc_data)); 1024 __asm volatile("mbar\n\tmsync"); 1025 return v; 1026} 1027 1028static inline void 1029pq3pci_config_data_write(pci_chipset_tag_t pc, pcireg_t v) 1030{ 1031 __asm volatile("stwbrx\t%0, 0, %1" :: "r"(v), "r"(pc->pc_data)); 1032 __asm volatile("mbar\n\tmsync"); 1033} 1034 1035static pcireg_t 1036pq3pci_conf_read(void *v, pcitag_t tag, int reg) 1037{ 1038 struct pq3pci_softc * const sc = v; 1039 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1040 1041 if (reg >= 256) { 1042 if (!sc->sc_pcie) 1043 return 0xffffffff; 1044 reg = (reg & 0xff) | ((reg & 0xf00) << 16); 1045 } 1046 if (sc->sc_pcie && ((tag >> 16) & 0xff) != 0) { 1047 // pcireg_t slot_status = pci_conf_read(pc, 0, 0x64); 1048 // printf("%s: tag 0x0 slot status: %#x\n",__func__, slot_status); 1049 // if ((slot_status & __BIT(6+16)) == 0) 1050 // printf(" addr=%#llx ", tag | reg | PEX_CONFIG_ADDR_EN); 1051 // return 0xffffffff; 1052 } 1053 1054 mutex_spin_enter(sc->sc_conf_lock); 1055 1056 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN); 1057 pcireg_t rv = pq3pci_config_data_read(pc); 1058 1059 mutex_spin_exit(sc->sc_conf_lock); 1060 1061#if 0 1062 uint32_t err = bus_space_read_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR); 1063 if (err & PEXERRDR_ICCA) { 1064 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x icca: %#x\n", 1065 __func__, tag, reg, pq3pci_config_addr_read(pc)); 1066 bus_space_write_4(sc->sc_bst, sc->sc_bsh, PEX_ERR_DR, 1067 PEXERRDR_ICCA); 1068 } 1069#endif 1070 return rv; 1071} 1072 1073static void 1074pq3pci_conf_write(void *v, pcitag_t tag, int reg, pcireg_t data) 1075{ 1076 struct pq3pci_softc * const sc = v; 1077 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1078 1079 if (reg >= 256) { 1080 if (!sc->sc_pcie) 1081 return; 1082 reg = (reg & 0xff) | ((reg & 0xf00) << 16); 1083 } 1084 1085 mutex_spin_enter(sc->sc_conf_lock); 1086 1087#if 0 1088 aprint_error_dev(sc->sc_dev, "%s: tag %#x reg %#x data %#x\n", 1089 __func__, tag, reg, data); 1090#endif 1091 pq3pci_config_addr_write(pc, tag | reg | PEX_CONFIG_ADDR_EN); 1092 pq3pci_config_data_write(pc, data); 1093 1094 mutex_spin_exit(sc->sc_conf_lock); 1095} 1096 1097static int 1098pq3pci_conf_hook(void *v, int bus, int dev, int func, pcireg_t id) 1099{ 1100 struct pq3pci_softc * const sc = v; 1101 if (sc->sc_pcie && bus != 0) { 1102 pcireg_t slot_status = pci_conf_read(&sc->sc_pc, 0, 0x64); 1103 if ((slot_status & __BIT(6+16)) == 0) 1104 return 0; 1105 } 1106 if (!sc->sc_pcie && bus == 0 && dev == 0) { 1107 return PCI_CONF_DEFAULT ^ (PCI_CONF_MAP_IO|PCI_CONF_MAP_MEM|PCI_CONF_MAP_ROM); 1108 } 1109 return PCI_CONF_DEFAULT; 1110} 1111 1112static void 1113pq3pci_msi_group_setup(struct pq3pci_msigroup *msig, u_int group, int ipl) 1114{ 1115 const char (*intr_names)[8] = msi_intr_names[group]; 1116 1117 KASSERT(ipl == IPL_VM); 1118 1119 pq3pci_msigroups[group] = msig; 1120 msig->msig_group = group; 1121 msig->msig_free_mask = ~0 << (group == 0); 1122 msig->msig_ipl = ipl; 1123 msig->msig_lock = mutex_obj_alloc(MUTEX_DEFAULT, ipl); 1124 msig->msig_ih = intr_establish(msig->msig_group, ipl, IST_MSIGROUP, 1125 pq3pci_msi_intr, msig); 1126 msig->msig_msir = OPENPIC_BASE + OPENPIC_MSIR(msig->msig_group); 1127 for (u_int i = 0; i < __arraycount(msig->msig_ihands); i++) { 1128 struct pq3pci_msihand * const msih = msig->msig_ihands + i; 1129 msih->msih_ih.ih_class = IH_MSI; 1130 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr; 1131 msih->msih_ih.ih_arg = msih; 1132 msih->msih_group = msig; 1133 evcnt_attach_dynamic(&msih->msih_ev, EVCNT_TYPE_INTR, 1134 NULL, intr_names[i], "intr"); 1135 evcnt_attach_dynamic(&msih->msih_ev_spurious, EVCNT_TYPE_INTR, 1136 &msih->msih_ev, intr_names[i], "spurious intr"); 1137 } 1138} 1139 1140static pci_intr_handle_t 1141pq3pci_msi_alloc(int ipl, u_int rmsi) 1142{ 1143 size_t freegroup = 0; 1144 size_t maplen = __arraycount(pq3pci_msigroups); 1145 KASSERT(rmsi <= 5); 1146 uint32_t bitmap[maplen]; 1147 1148 for (u_int i = 0; i < maplen; i++) { 1149 struct pq3pci_msigroup * const msig = pq3pci_msigroups[i]; 1150 if (msig == NULL) { 1151 bitmap[i] = 0; 1152 if (freegroup == 0) 1153 freegroup = i + 1; 1154 continue; 1155 } 1156 /* 1157 * If this msigroup has the wrong IPL or there's nothing 1158 * free, try the next one. 1159 */ 1160 if (msig->msig_ipl != ipl || msig->msig_free_mask == 0) { 1161 bitmap[i] = 0; 1162 continue; 1163 } 1164 1165 bitmap[i] = msig->msig_free_mask; 1166 } 1167 for (u_int i = 0; i < maplen; i++) { 1168 uint32_t mapbits = bitmap[i]; 1169 u_int n = ffs(mapbits); 1170 if (n--) { 1171 return PIH_MAKE(i * 32 + n, IST_MSI, 0); 1172 } 1173 } 1174 1175 if (freegroup-- == 0) 1176 return 0; 1177 1178 struct pq3pci_msigroup * const msig = 1179 kmem_zalloc(sizeof(*msig), KM_SLEEP); 1180 KASSERT(msig != NULL); 1181 pq3pci_msi_group_setup(msig, freegroup, ipl); 1182 u_int n = ffs(msig->msig_free_mask) - 1; 1183 return PIH_MAKE(freegroup * 32 + n, IST_MSI, 0); 1184} 1185 1186static struct pq3pci_msihand * 1187pq3pci_msi_lookup(pci_intr_handle_t handle) 1188{ 1189 const int irq = PIH_IRQ(handle); 1190 KASSERT(irq < 256); 1191 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32]; 1192 KASSERT(msig != NULL); 1193 return &msig->msig_ihands[irq & 31]; 1194} 1195 1196static struct pq3pci_msihand * 1197pq3pci_msi_claim(pci_intr_handle_t handle) 1198{ 1199 const int irq = PIH_IRQ(handle); 1200 uint32_t irq_mask = __BIT(irq & 31); 1201 KASSERT(irq < 256); 1202 struct pq3pci_msigroup * const msig = pq3pci_msigroups[irq / 32]; 1203 KASSERT(msig != NULL); 1204 struct pq3pci_msihand * const msih = &msig->msig_ihands[irq & 31]; 1205 mutex_spin_enter(msig->msig_lock); 1206 KASSERT(msig->msig_free_mask & irq_mask); 1207 msig->msig_free_mask ^= irq_mask; 1208 mutex_spin_exit(msig->msig_lock); 1209 return msih; 1210} 1211 1212static struct pq3pci_intrsource * 1213pq3pci_intr_source_lookup(struct pq3pci_softc *sc, pci_intr_handle_t handle) 1214{ 1215 struct pq3pci_intrsource *pis; 1216 SIMPLEQ_FOREACH(pis, &pq3pci_intrsources, pis_link) { 1217 if (pis->pis_handle == handle) 1218 return pis; 1219 } 1220 pis = kmem_zalloc(sizeof(*pis), KM_SLEEP); 1221 pq3pci_intr_source_setup(sc, pis, handle); 1222 return pis; 1223} 1224 1225static pci_intr_handle_t 1226pq3pci_intr_handle_lookup(struct pq3pci_softc *sc, 1227 const struct pci_attach_args *pa) 1228{ 1229 prop_dictionary_t entry; 1230 1231 if (sc->sc_pcie) do { 1232 pcireg_t msictl; 1233 int msioff; 1234 if (!pci_get_capability(pa->pa_pc, pa->pa_tag, PCI_CAP_MSI, 1235 &msioff, &msictl)) 1236 break; 1237 msictl = pci_conf_read(pa->pa_pc, pa->pa_tag, msioff); 1238 msictl &= ~PCI_MSI_CTL_MSI_ENABLE; 1239 msictl &= ~PCI_MSI_CTL_MME_MASK; 1240 int rmsi = __SHIFTOUT(msictl, PCI_MSI_CTL_MMC_MASK); 1241 pci_conf_write(pa->pa_pc, pa->pa_tag, msioff, msictl); 1242 pci_intr_handle_t handle = pq3pci_msi_alloc(IPL_VM, rmsi); 1243 struct pq3pci_msihand * const msih = pq3pci_msi_lookup(handle); 1244 msih->msih_tag = pa->pa_tag; 1245 msih->msih_msioff = msioff; 1246 return handle; 1247 } while (false); 1248 1249 1250 if (sc->sc_intrmask == 0) { 1251 entry = prop_dictionary_get(sc->sc_intrmap, "000000"); 1252 } else { 1253 char prop_name[8]; 1254 u_int intrinc = __LOWEST_SET_BIT(sc->sc_intrmask); 1255 pcitag_t tag = (pa->pa_intrpin - PCI_INTERRUPT_PIN_A) * intrinc; 1256 1257 snprintf(prop_name, sizeof(prop_name), "%06x", 1258 tag & sc->sc_intrmask); 1259 1260#if 0 1261 printf("%s: %#x %#x %u (%u) -> %#x & %#x -> %#x <%s>\n", 1262 __func__, pa->pa_tag, pa->pa_intrtag, pa->pa_intrpin, pa->pa_rawintrpin, 1263 tag, sc->sc_intrmask, tag & sc->sc_intrmask, prop_name); 1264#endif 1265 1266 entry = prop_dictionary_get(sc->sc_intrmap, prop_name); 1267 } 1268 KASSERT(entry != NULL); 1269 KASSERT(prop_object_type(entry) == PROP_TYPE_DICTIONARY); 1270 1271 prop_number_t pn_irq = prop_dictionary_get(entry, "interrupt"); 1272 KASSERT(pn_irq != NULL); 1273 KASSERT(prop_object_type(pn_irq) == PROP_TYPE_NUMBER); 1274 int irq = prop_number_unsigned_integer_value(pn_irq); 1275 prop_number_t pn_ist = prop_dictionary_get(entry, "type"); 1276 KASSERT(pn_ist != NULL); 1277 KASSERT(prop_object_type(pn_ist) == PROP_TYPE_NUMBER); 1278 int ist = prop_number_unsigned_integer_value(pn_ist); 1279 1280 return PIH_MAKE(irq, ist, 0); 1281} 1282 1283static int 1284pq3pci_intr_map(const struct pci_attach_args *pa, pci_intr_handle_t *handlep) 1285{ 1286 struct pq3pci_softc * const sc = pa->pa_pc->pc_intr_v; 1287 1288 if (pa->pa_intrpin == PCI_INTERRUPT_PIN_NONE) 1289 return ENOENT; 1290 1291 *handlep = pq3pci_intr_handle_lookup(sc, pa); 1292 1293 return 0; 1294} 1295 1296static const char * 1297pq3pci_intr_string(void *v, pci_intr_handle_t handle, char *buf, size_t len) 1298{ 1299 if (PIH_IST(handle) == IST_MSI) { 1300 const char (*intr_names)[8] = msi_intr_names[0]; 1301 strlcpy(buf, intr_names[PIH_IRQ(handle)], len); 1302 return buf; 1303 } 1304 1305 return intr_string(PIH_IRQ(handle), PIH_IST(handle), buf, len); 1306} 1307 1308static const struct evcnt * 1309pq3pci_intr_evcnt(void *v, pci_intr_handle_t handle) 1310{ 1311 struct pq3pci_softc * const sc = v; 1312 struct pq3pci_intrsource * const pis = 1313 pq3pci_intr_source_lookup(sc, handle); 1314 1315 KASSERT(pis != NULL); 1316 1317 return &pis->pis_ev; 1318} 1319 1320static void * 1321pq3pci_intr_establish(void *v, pci_intr_handle_t handle, int ipl, 1322 int (*func)(void *), void *arg) 1323{ 1324 struct pq3pci_softc * const sc = v; 1325 1326 if (0) { 1327 struct pq3pci_callhand * const pch = 1328 kmem_zalloc(sizeof(*pch), KM_SLEEP); 1329 KASSERT(pch); 1330 pch->pch_ih.ih_arg = arg; 1331 pch->pch_ih.ih_func = func; 1332 pch->pch_ih.ih_sc = sc; 1333 pch->pch_ipl = ipl; 1334 1335 callout_init(&pch->pch_callout, 0); 1336 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch); 1337 1338 return pch; 1339 } 1340 1341 const int ist = PIH_IST(handle); 1342 1343 if (ist == IST_MSI) { 1344 pci_chipset_tag_t pc = &sc->sc_pc; 1345 struct pq3pci_msihand * const msih = pq3pci_msi_claim(handle); 1346 pcireg_t cmdsts, msictl; 1347 1348 if (msih == NULL) 1349 return NULL; 1350 1351 struct pq3pci_msigroup * const msig = msih->msih_group; 1352 const pcitag_t tag = msih->msih_tag; 1353 1354 mutex_spin_enter(msig->msig_lock); 1355 msih->msih_ih.ih_class = IH_MSI; 1356 msih->msih_ih.ih_arg = arg; 1357 msih->msih_ih.ih_func = func; 1358 msih->msih_ih.ih_sc = sc; 1359 1360 int off = msih->msih_msioff; 1361 msictl = pci_conf_read(pc, tag, off); 1362 1363 /* 1364 * The PCSRBAR has already been setup as a 1:1 BAR so we point 1365 * MSIs at the MSII register in the OpenPIC. 1366 */ 1367 off += 4; 1368 pci_conf_write(pc, tag, off, 1369 sc->sc_bst->pbs_offset + OPENPIC_BASE + OPENPIC_MSIIR); 1370 1371 /* 1372 * Upper address is going to be 0. 1373 */ 1374 if (msictl & PCI_MSI_CTL_64BIT_ADDR) { 1375 off += 4; 1376 pci_conf_write(pc, tag, off, 0); 1377 } 1378 1379 /* 1380 * Set the magic value. Since PCI writes this to the least 1381 * significant byte of AD[31:0], let's hope the bridge byte 1382 * swaps to so it's the most significant bytes or nothing is 1383 * going to happen. 1384 */ 1385 off += 4; 1386 pci_conf_write(pc, tag, off, PIH_IRQ(handle)); 1387 1388 /* 1389 * Should the driver do this? How would it know to do it? 1390 */ 1391 if (msictl & PCI_MSI_CTL_PERVEC_MASK) { 1392 off += 4; 1393 pci_conf_write(pc, tag, off, 0); 1394 } 1395 1396 /* 1397 * Let's make sure he won't raise any INTx. Technically 1398 * setting MSI enable will prevent that as well but might 1399 * as well be as safe as possible. 1400 */ 1401 cmdsts = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 1402 cmdsts |= PCI_COMMAND_INTERRUPT_DISABLE; 1403 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, cmdsts); 1404 1405#if 1 1406 /* 1407 * Now we can enable the MSI 1408 */ 1409 msictl |= PCI_MSI_CTL_MSI_ENABLE; 1410 pci_conf_write(pc, tag, msih->msih_msioff, msictl); 1411#endif 1412 1413 mutex_spin_exit(msig->msig_lock); 1414 1415#if 0 1416 struct pq3pci_callhand * const pch = 1417 kmem_zalloc(sizeof(*pch), KM_SLEEP); 1418 KASSERT(pch); 1419 1420 pch->pch_ih.ih_arg = msig; 1421 pch->pch_ih.ih_func = pq3pci_msi_intr; 1422#if 1 1423 pch->pch_ih.ih_arg = arg; 1424 pch->pch_ih.ih_func = func; 1425#endif 1426 pch->pch_ih.ih_sc = sc; 1427 pch->pch_ipl = ipl; 1428 1429 callout_init(&pch->pch_callout, 0); 1430 callout_reset(&pch->pch_callout, 1, pq3pci_pch_callout, pch); 1431 1432#if 1 1433 return pch; 1434#endif 1435#endif 1436 1437 return msih; 1438 } else { 1439 struct pq3pci_intrsource * const pis = 1440 pq3pci_intr_source_lookup(sc, handle); 1441 KASSERT(pis != NULL); 1442 1443 struct pq3pci_intrhand * const pih = 1444 kmem_zalloc(sizeof(*pih), KM_SLEEP); 1445 1446 if (pih == NULL) 1447 return NULL; 1448 1449 pih->pih_ih.ih_class = IH_INTX; 1450 pih->pih_ih.ih_func = func; 1451 pih->pih_ih.ih_arg = arg; 1452 pih->pih_ih.ih_sc = sc; 1453 pih->pih_ipl = ipl; 1454 pih->pih_source = pis; 1455 1456 mutex_spin_enter(pis->pis_lock); 1457 SIMPLEQ_INSERT_TAIL(&pis->pis_ihands, pih, pih_link); 1458 mutex_spin_exit(pis->pis_lock); 1459 1460 return pih; 1461 } 1462} 1463 1464static void 1465pq3pci_intr_disestablish(void *v, void *ih) 1466{ 1467 struct pq3pci_genihand * const gih = ih; 1468 1469 if (gih->ih_class == IH_INTX) { 1470 struct pq3pci_intrhand * const pih = ih; 1471 struct pq3pci_intrsource * const pis = pih->pih_source; 1472 1473 mutex_spin_enter(pis->pis_lock); 1474 SIMPLEQ_REMOVE(&pis->pis_ihands, pih, pq3pci_intrhand, pih_link); 1475 mutex_spin_exit(pis->pis_lock); 1476 1477 kmem_free(pih, sizeof(*pih)); 1478 return; 1479 } 1480 struct pq3pci_msihand * const msih = ih; 1481 struct pq3pci_msigroup * const msig = msih->msih_group; 1482 struct genppc_pci_chipset * const pc = &msih->msih_ih.ih_sc->sc_pc; 1483 const pcitag_t tag = msih->msih_tag; 1484 1485 mutex_spin_enter(msig->msig_lock); 1486 1487 /* 1488 * disable the MSI 1489 */ 1490 pcireg_t msictl = pci_conf_read(pc, tag, msih->msih_msioff); 1491 msictl &= ~PCI_MSI_CTL_MSI_ENABLE; 1492 pci_conf_write(pc, tag, msih->msih_msioff, msictl); 1493 1494 msih->msih_ih.ih_func = pq3pci_msi_spurious_intr; 1495 msih->msih_ih.ih_arg = msig; 1496 msih->msih_ih.ih_sc = NULL; 1497 msih->msih_tag = 0; 1498 msih->msih_msioff = 0; 1499 mutex_spin_exit(msig->msig_lock); 1500} 1501 1502static void 1503pq3pci_conf_interrupt(void *v, int bus, int dev, int pin, int swiz, int *iline) 1504{ 1505} 1506 1507static pci_chipset_tag_t 1508pq3pci_pci_chipset_init(struct pq3pci_softc *sc) 1509{ 1510 struct genppc_pci_chipset * const pc = &sc->sc_pc; 1511 1512 pc->pc_conf_v = sc; 1513 pc->pc_attach_hook = pq3pci_attach_hook; 1514 pc->pc_bus_maxdevs = pq3pci_bus_maxdevs; 1515 pc->pc_make_tag = pq3pci_make_tag; 1516 pc->pc_conf_read = pq3pci_conf_read; 1517 pc->pc_conf_write = pq3pci_conf_write; 1518#ifdef PCI_NETBSD_CONFIGURE 1519 pc->pc_conf_hook = pq3pci_conf_hook; 1520#endif 1521 1522 pc->pc_intr_v = sc; 1523 pc->pc_intr_map = pq3pci_intr_map; 1524 pc->pc_intr_string = pq3pci_intr_string; 1525 pc->pc_intr_evcnt = pq3pci_intr_evcnt; 1526 pc->pc_intr_establish = pq3pci_intr_establish; 1527 pc->pc_intr_disestablish = pq3pci_intr_disestablish; 1528 pc->pc_conf_interrupt = pq3pci_conf_interrupt; 1529 1530 pc->pc_msi_v = sc; 1531 genppc_pci_chipset_msi_init(pc); 1532#if 0 1533 pc->pc_msi_request = pq3pci_msi_request; 1534 pc->pc_msi_available = pq3pci_msi_available; 1535 pc->pc_msi_type = pq3pci_msi_type; 1536 pc->pc_msi_string = pq3pci_msi_string; 1537 pc->pc_msi_evcnt = genppc_pci_msi_evcnt; 1538 pc->pc_msi_establish = pq3pci_msi_establish; 1539 pc->pc_msix_establish = pq3pci_msix_establish; 1540 pc->pc_msi_disestablish = pq3pci_msi_disestablish; 1541 pc->pc_msi_release = pq3pci_msi_release; 1542 pc->pc_msi_free = pq3pci_msi_free; 1543#endif 1544 1545 pc->pc_decompose_tag = pq3pci_decompose_tag; 1546 pc->pc_conf_hook = pq3pci_conf_hook; 1547 1548 /* 1549 * This is a horrible kludge but it makes life easier. 1550 */ 1551 pc->pc_addr = (void *)(sc->sc_bsh + PEX_CONFIG_ADDR); 1552 pc->pc_data = (void *)(sc->sc_bsh + PEX_CONFIG_DATA); 1553 pc->pc_bus = 0; 1554 pc->pc_memt = &sc->sc_pci_mem_bst.bs_tag; 1555 pc->pc_iot = &sc->sc_pci_io_bst.bs_tag; 1556 1557 SIMPLEQ_INIT(&pc->pc_pbi); 1558 1559 return pc; 1560} 1561