schizo.c revision 225931
1316722Sdelphij/*- 2275970Scy * Copyright (c) 1999, 2000 Matthew R. Green 3275970Scy * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> 4275970Scy * Copyright (c) 2005 - 2011 by Marius Strobl <marius@FreeBSD.org> 5275970Scy * All rights reserved. 6316722Sdelphij * 7275970Scy * Redistribution and use in source and binary forms, with or without 8275970Scy * modification, are permitted provided that the following conditions 9275970Scy * are met: 10275970Scy * 1. Redistributions of source code must retain the above copyright 11275970Scy * notice, this list of conditions and the following disclaimer. 12275970Scy * 2. Redistributions in binary form must reproduce the above copyright 13275970Scy * notice, this list of conditions and the following disclaimer in the 14275970Scy * documentation and/or other materials provided with the distribution. 15275970Scy * 3. The name of the author may not be used to endorse or promote products 16275970Scy * derived from this software without specific prior written permission. 17275970Scy * 18275970Scy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19275970Scy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20275970Scy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21275970Scy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22275970Scy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 23275970Scy * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24275970Scy * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 25275970Scy * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26275970Scy * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27275970Scy * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28275970Scy * SUCH DAMAGE. 29275970Scy * 30275970Scy * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 31275970Scy * from: FreeBSD: psycho.c 183152 2008-09-18 19:45:22Z marius 32275970Scy */ 33275970Scy 34275970Scy#include <sys/cdefs.h> 35275970Scy__FBSDID("$FreeBSD: head/sys/sparc64/pci/schizo.c 225931 2011-10-02 23:22:38Z marius $"); 36275970Scy 37275970Scy/* 38275970Scy * Driver for `Schizo' Fireplane/Safari to PCI 2.1, `Tomatillo' JBus to 39275970Scy * PCI 2.2 and `XMITS' Fireplane/Safari to PCI-X bridges 40275970Scy */ 41275970Scy 42275970Scy#include "opt_ofw_pci.h" 43275970Scy#include "opt_schizo.h" 44275970Scy 45275970Scy#include <sys/param.h> 46275970Scy#include <sys/systm.h> 47275970Scy#include <sys/bus.h> 48275970Scy#include <sys/kernel.h> 49275970Scy#include <sys/lock.h> 50275970Scy#include <sys/malloc.h> 51275970Scy#include <sys/module.h> 52275970Scy#include <sys/mutex.h> 53275970Scy#include <sys/pcpu.h> 54275970Scy#include <sys/rman.h> 55275970Scy#include <sys/sysctl.h> 56275970Scy#include <sys/time.h> 57275970Scy#include <sys/timetc.h> 58275970Scy 59275970Scy#include <dev/ofw/ofw_bus.h> 60285612Sdelphij#include <dev/ofw/ofw_pci.h> 61285612Sdelphij#include <dev/ofw/openfirm.h> 62275970Scy 63275970Scy#include <machine/bus.h> 64275970Scy#include <machine/bus_common.h> 65275970Scy#include <machine/bus_private.h> 66275970Scy#include <machine/fsr.h> 67275970Scy#include <machine/iommureg.h> 68275970Scy#include <machine/iommuvar.h> 69275970Scy#include <machine/resource.h> 70275970Scy 71275970Scy#include <dev/pci/pcireg.h> 72275970Scy#include <dev/pci/pcivar.h> 73275970Scy 74275970Scy#include <sparc64/pci/ofw_pci.h> 75275970Scy#include <sparc64/pci/schizoreg.h> 76275970Scy#include <sparc64/pci/schizovar.h> 77275970Scy 78275970Scy#include "pcib_if.h" 79275970Scy 80275970Scystatic const struct schizo_desc *schizo_get_desc(device_t); 81275970Scystatic void schizo_set_intr(struct schizo_softc *, u_int, u_int, 82275970Scy driver_filter_t); 83275970Scystatic void schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, 84275970Scy bus_dmasync_op_t op); 85275970Scystatic void ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, 86275970Scy bus_dmasync_op_t op); 87275970Scystatic void schizo_intr_enable(void *); 88275970Scystatic void schizo_intr_disable(void *); 89275970Scystatic void schizo_intr_assign(void *); 90275970Scystatic void schizo_intr_clear(void *); 91275970Scystatic int schizo_intr_register(struct schizo_softc *sc, u_int ino); 92275970Scystatic int schizo_get_intrmap(struct schizo_softc *, u_int, 93275970Scy bus_addr_t *, bus_addr_t *); 94275970Scystatic timecounter_get_t schizo_get_timecount; 95275970Scy 96275970Scy/* Interrupt handlers */ 97275970Scystatic driver_filter_t schizo_pci_bus; 98275970Scystatic driver_filter_t schizo_ue; 99275970Scystatic driver_filter_t schizo_ce; 100275970Scystatic driver_filter_t schizo_host_bus; 101275970Scystatic driver_filter_t schizo_cdma; 102275970Scy 103275970Scy/* IOMMU support */ 104275970Scystatic void schizo_iommu_init(struct schizo_softc *, int, uint32_t); 105275970Scy 106275970Scy/* 107275970Scy * Methods 108275970Scy */ 109275970Scystatic device_probe_t schizo_probe; 110275970Scystatic device_attach_t schizo_attach; 111275970Scystatic bus_read_ivar_t schizo_read_ivar; 112275970Scystatic bus_setup_intr_t schizo_setup_intr; 113275970Scystatic bus_alloc_resource_t schizo_alloc_resource; 114275970Scystatic bus_activate_resource_t schizo_activate_resource; 115275970Scystatic bus_adjust_resource_t schizo_adjust_resource; 116275970Scystatic bus_get_dma_tag_t schizo_get_dma_tag; 117275970Scystatic pcib_maxslots_t schizo_maxslots; 118275970Scystatic pcib_read_config_t schizo_read_config; 119275970Scystatic pcib_write_config_t schizo_write_config; 120275970Scystatic pcib_route_interrupt_t schizo_route_interrupt; 121275970Scystatic ofw_bus_get_node_t schizo_get_node; 122275970Scystatic ofw_pci_setup_device_t schizo_setup_device; 123275970Scy 124275970Scystatic device_method_t schizo_methods[] = { 125275970Scy /* Device interface */ 126275970Scy DEVMETHOD(device_probe, schizo_probe), 127275970Scy DEVMETHOD(device_attach, schizo_attach), 128275970Scy DEVMETHOD(device_shutdown, bus_generic_shutdown), 129275970Scy DEVMETHOD(device_suspend, bus_generic_suspend), 130275970Scy DEVMETHOD(device_resume, bus_generic_resume), 131275970Scy 132275970Scy /* Bus interface */ 133275970Scy DEVMETHOD(bus_print_child, bus_generic_print_child), 134275970Scy DEVMETHOD(bus_read_ivar, schizo_read_ivar), 135275970Scy DEVMETHOD(bus_setup_intr, schizo_setup_intr), 136275970Scy DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 137275970Scy DEVMETHOD(bus_alloc_resource, schizo_alloc_resource), 138275970Scy DEVMETHOD(bus_activate_resource, schizo_activate_resource), 139275970Scy DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 140275970Scy DEVMETHOD(bus_adjust_resource, schizo_adjust_resource), 141275970Scy DEVMETHOD(bus_release_resource, bus_generic_release_resource), 142275970Scy DEVMETHOD(bus_get_dma_tag, schizo_get_dma_tag), 143275970Scy 144275970Scy /* pcib interface */ 145275970Scy DEVMETHOD(pcib_maxslots, schizo_maxslots), 146275970Scy DEVMETHOD(pcib_read_config, schizo_read_config), 147275970Scy DEVMETHOD(pcib_write_config, schizo_write_config), 148275970Scy DEVMETHOD(pcib_route_interrupt, schizo_route_interrupt), 149275970Scy 150275970Scy /* ofw_bus interface */ 151275970Scy DEVMETHOD(ofw_bus_get_node, schizo_get_node), 152275970Scy 153275970Scy /* ofw_pci interface */ 154275970Scy DEVMETHOD(ofw_pci_setup_device, schizo_setup_device), 155275970Scy 156275970Scy KOBJMETHOD_END 157275970Scy}; 158275970Scy 159275970Scystatic devclass_t schizo_devclass; 160275970Scy 161275970ScyDEFINE_CLASS_0(pcib, schizo_driver, schizo_methods, 162275970Scy sizeof(struct schizo_softc)); 163275970ScyEARLY_DRIVER_MODULE(schizo, nexus, schizo_driver, schizo_devclass, 0, 0, 164275970Scy BUS_PASS_BUS); 165275970Scy 166280849Scystatic SLIST_HEAD(, schizo_softc) schizo_softcs = 167280849Scy SLIST_HEAD_INITIALIZER(schizo_softcs); 168280849Scy 169275970Scystatic const struct intr_controller schizo_ic = { 170275970Scy schizo_intr_enable, 171275970Scy schizo_intr_disable, 172275970Scy schizo_intr_assign, 173275970Scy schizo_intr_clear 174275970Scy}; 175275970Scy 176275970Scystruct schizo_icarg { 177275970Scy struct schizo_softc *sica_sc; 178275970Scy bus_addr_t sica_map; 179275970Scy bus_addr_t sica_clr; 180275970Scy}; 181275970Scy 182275970Scy#define SCHIZO_PERF_CNT_QLTY 100 183275970Scy 184275970Scy#define SCHIZO_SPC_BARRIER(spc, sc, offs, len, flags) \ 185275970Scy bus_barrier((sc)->sc_mem_res[(spc)], (offs), (len), (flags)) 186275970Scy#define SCHIZO_SPC_READ_8(spc, sc, offs) \ 187275970Scy bus_read_8((sc)->sc_mem_res[(spc)], (offs)) 188275970Scy#define SCHIZO_SPC_WRITE_8(spc, sc, offs, v) \ 189275970Scy bus_write_8((sc)->sc_mem_res[(spc)], (offs), (v)) 190275970Scy 191275970Scy#ifndef SCHIZO_DEBUG 192275970Scy#define SCHIZO_SPC_SET(spc, sc, offs, reg, v) \ 193275970Scy SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v)) 194275970Scy#else 195275970Scy#define SCHIZO_SPC_SET(spc, sc, offs, reg, v) do { \ 196275970Scy device_printf((sc)->sc_dev, reg " 0x%016llx -> 0x%016llx\n", \ 197275970Scy (unsigned long long)SCHIZO_SPC_READ_8((spc), (sc), (offs)), \ 198275970Scy (unsigned long long)(v)); \ 199275970Scy SCHIZO_SPC_WRITE_8((spc), (sc), (offs), (v)); \ 200275970Scy } while (0) 201275970Scy#endif 202275970Scy 203275970Scy#define SCHIZO_PCI_READ_8(sc, offs) \ 204275970Scy SCHIZO_SPC_READ_8(STX_PCI, (sc), (offs)) 205275970Scy#define SCHIZO_PCI_WRITE_8(sc, offs, v) \ 206275970Scy SCHIZO_SPC_WRITE_8(STX_PCI, (sc), (offs), (v)) 207275970Scy#define SCHIZO_CTRL_READ_8(sc, offs) \ 208275970Scy SCHIZO_SPC_READ_8(STX_CTRL, (sc), (offs)) 209275970Scy#define SCHIZO_CTRL_WRITE_8(sc, offs, v) \ 210275970Scy SCHIZO_SPC_WRITE_8(STX_CTRL, (sc), (offs), (v)) 211275970Scy#define SCHIZO_PCICFG_READ_8(sc, offs) \ 212275970Scy SCHIZO_SPC_READ_8(STX_PCICFG, (sc), (offs)) 213275970Scy#define SCHIZO_PCICFG_WRITE_8(sc, offs, v) \ 214310419Sdelphij SCHIZO_SPC_WRITE_8(STX_PCICFG, (sc), (offs), (v)) 215275970Scy#define SCHIZO_ICON_READ_8(sc, offs) \ 216275970Scy SCHIZO_SPC_READ_8(STX_ICON, (sc), (offs)) 217275970Scy#define SCHIZO_ICON_WRITE_8(sc, offs, v) \ 218275970Scy SCHIZO_SPC_WRITE_8(STX_ICON, (sc), (offs), (v)) 219275970Scy 220275970Scy#define SCHIZO_PCI_SET(sc, offs, v) \ 221275970Scy SCHIZO_SPC_SET(STX_PCI, (sc), (offs), # offs, (v)) 222275970Scy#define SCHIZO_CTRL_SET(sc, offs, v) \ 223275970Scy SCHIZO_SPC_SET(STX_CTRL, (sc), (offs), # offs, (v)) 224275970Scy 225275970Scystruct schizo_desc { 226275970Scy const char *sd_string; 227275970Scy int sd_mode; 228275970Scy const char *sd_name; 229275970Scy}; 230275970Scy 231275970Scystatic const struct schizo_desc const schizo_compats[] = { 232275970Scy { "pci108e,8001", SCHIZO_MODE_SCZ, "Schizo" }, 233275970Scy#if 0 234275970Scy { "pci108e,8002", SCHIZO_MODE_XMS, "XMITS" }, 235275970Scy#endif 236275970Scy { "pci108e,a801", SCHIZO_MODE_TOM, "Tomatillo" }, 237275970Scy { NULL, 0, NULL } 238275970Scy}; 239275970Scy 240275970Scystatic const struct schizo_desc * 241275970Scyschizo_get_desc(device_t dev) 242275970Scy{ 243275970Scy const struct schizo_desc *desc; 244275970Scy const char *compat; 245275970Scy 246275970Scy compat = ofw_bus_get_compat(dev); 247275970Scy if (compat == NULL) 248275970Scy return (NULL); 249275970Scy for (desc = schizo_compats; desc->sd_string != NULL; desc++) 250275970Scy if (strcmp(desc->sd_string, compat) == 0) 251275970Scy return (desc); 252275970Scy return (NULL); 253275970Scy} 254275970Scy 255275970Scystatic int 256275970Scyschizo_probe(device_t dev) 257280849Scy{ 258275970Scy const char *dtype; 259275970Scy 260275970Scy dtype = ofw_bus_get_type(dev); 261275970Scy if (dtype != NULL && strcmp(dtype, OFW_TYPE_PCI) == 0 && 262275970Scy schizo_get_desc(dev) != NULL) { 263280849Scy device_set_desc(dev, "Sun Host-PCI bridge"); 264280849Scy return (0); 265280849Scy } 266280849Scy return (ENXIO); 267280849Scy} 268280849Scy 269280849Scystatic int 270280849Scyschizo_attach(device_t dev) 271280849Scy{ 272280849Scy struct ofw_pci_ranges *range; 273280849Scy const struct schizo_desc *desc; 274280849Scy struct schizo_softc *asc, *sc, *osc; 275280849Scy struct timecounter *tc; 276280849Scy uint64_t ino_bitmap, reg; 277280849Scy phandle_t node; 278275970Scy uint32_t prop, prop_array[2]; 279275970Scy int i, j, mode, rid, tsbsize; 280275970Scy 281275970Scy sc = device_get_softc(dev); 282275970Scy node = ofw_bus_get_node(dev); 283275970Scy desc = schizo_get_desc(dev); 284275970Scy mode = desc->sd_mode; 285275970Scy 286275970Scy sc->sc_dev = dev; 287275970Scy sc->sc_node = node; 288275970Scy sc->sc_mode = mode; 289275970Scy sc->sc_flags = 0; 290275970Scy 291275970Scy /* 292275970Scy * The Schizo has three register banks: 293275970Scy * (0) per-PBM PCI configuration and status registers, but for bus B 294275970Scy * shared with the UPA64s interrupt mapping register banks 295275970Scy * (1) shared Schizo controller configuration and status registers 296275970Scy * (2) per-PBM PCI configuration space 297275970Scy * 298275970Scy * The Tomatillo has four register banks: 299275970Scy * (0) per-PBM PCI configuration and status registers 300275970Scy * (1) per-PBM Tomatillo controller configuration registers, but on 301275970Scy * machines having the `jbusppm' device shared with its Estar 302275970Scy * register bank for bus A 303275970Scy * (2) per-PBM PCI configuration space 304275970Scy * (3) per-PBM interrupt concentrator registers 305275970Scy */ 306316722Sdelphij sc->sc_half = (bus_get_resource_start(dev, SYS_RES_MEMORY, STX_PCI) >> 307275970Scy 20) & 1; 308275970Scy for (i = 0; i < (mode == SCHIZO_MODE_SCZ ? SCZ_NREG : TOM_NREG); 309275970Scy i++) { 310275970Scy rid = i; 311275970Scy sc->sc_mem_res[i] = bus_alloc_resource_any(dev, 312275970Scy SYS_RES_MEMORY, &rid, 313 (((mode == SCHIZO_MODE_SCZ && ((sc->sc_half == 1 && 314 i == STX_PCI) || i == STX_CTRL)) || 315 (mode == SCHIZO_MODE_TOM && sc->sc_half == 0 && 316 i == STX_CTRL)) ? RF_SHAREABLE : 0) | RF_ACTIVE); 317 if (sc->sc_mem_res[i] == NULL) 318 panic("%s: could not allocate register bank %d", 319 __func__, i); 320 } 321 322 /* 323 * Match other Schizos that are already configured against 324 * the controller base physical address. This will be the 325 * same for a pair of devices that share register space. 326 */ 327 osc = NULL; 328 SLIST_FOREACH(asc, &schizo_softcs, sc_link) { 329 if (rman_get_start(asc->sc_mem_res[STX_CTRL]) == 330 rman_get_start(sc->sc_mem_res[STX_CTRL])) { 331 /* Found partner. */ 332 osc = asc; 333 break; 334 } 335 } 336 if (osc == NULL) { 337 sc->sc_mtx = malloc(sizeof(*sc->sc_mtx), M_DEVBUF, 338 M_NOWAIT | M_ZERO); 339 if (sc->sc_mtx == NULL) 340 panic("%s: could not malloc mutex", __func__); 341 mtx_init(sc->sc_mtx, "pcib_mtx", NULL, MTX_SPIN); 342 } else { 343 if (sc->sc_mode != SCHIZO_MODE_SCZ) 344 panic("%s: no partner expected", __func__); 345 if (mtx_initialized(osc->sc_mtx) == 0) 346 panic("%s: mutex not initialized", __func__); 347 sc->sc_mtx = osc->sc_mtx; 348 } 349 350 if (OF_getprop(node, "portid", &sc->sc_ign, sizeof(sc->sc_ign)) == -1) 351 panic("%s: could not determine IGN", __func__); 352 if (OF_getprop(node, "version#", &sc->sc_ver, sizeof(sc->sc_ver)) == 353 -1) 354 panic("%s: could not determine version", __func__); 355 if (mode == SCHIZO_MODE_XMS && OF_getprop(node, "module-revision#", 356 &sc->sc_mrev, sizeof(sc->sc_mrev)) == -1) 357 panic("%s: could not determine module-revision", __func__); 358 if (OF_getprop(node, "clock-frequency", &prop, sizeof(prop)) == -1) 359 prop = 33000000; 360 361 if (mode == SCHIZO_MODE_XMS && (SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL) & 362 XMS_PCI_CTRL_X_MODE) != 0) { 363 if (sc->sc_mrev < 1) 364 panic("PCI-X mode unsupported"); 365 sc->sc_flags |= SCHIZO_FLAGS_XMODE; 366 } 367 368 device_printf(dev, "%s, version %d, ", desc->sd_name, sc->sc_ver); 369 if (mode == SCHIZO_MODE_XMS) 370 printf("module-revision %d, ", sc->sc_mrev); 371 printf("IGN %#x, bus %c, PCI%s mode, %dMHz\n", sc->sc_ign, 372 'A' + sc->sc_half, (sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ? 373 "-X" : "", prop / 1000 / 1000); 374 375 /* Set up the PCI interrupt retry timer. */ 376 SCHIZO_PCI_SET(sc, STX_PCI_INTR_RETRY_TIM, 5); 377 378 /* Set up the PCI control register. */ 379 reg = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL); 380 reg &= ~(TOM_PCI_CTRL_DTO_IEN | STX_PCI_CTRL_ARB_PARK | 381 STX_PCI_CTRL_ARB_MASK); 382 reg |= STX_PCI_CTRL_MMU_IEN | STX_PCI_CTRL_SBH_IEN | 383 STX_PCI_CTRL_ERR_IEN; 384 if (OF_getproplen(node, "no-bus-parking") < 0) 385 reg |= STX_PCI_CTRL_ARB_PARK; 386 if (mode == SCHIZO_MODE_XMS && sc->sc_mrev == 1) 387 reg |= XMS_PCI_CTRL_XMITS10_ARB_MASK; 388 else 389 reg |= STX_PCI_CTRL_ARB_MASK; 390 if (mode == SCHIZO_MODE_TOM) { 391 reg |= TOM_PCI_CTRL_PRM | TOM_PCI_CTRL_PRO | TOM_PCI_CTRL_PRL; 392 if (sc->sc_ver <= 1) /* revision <= 2.0 */ 393 reg |= TOM_PCI_CTRL_DTO_IEN; 394 else 395 reg |= STX_PCI_CTRL_PTO; 396 } else if (mode == SCHIZO_MODE_XMS) { 397 SCHIZO_PCI_SET(sc, XMS_PCI_PARITY_DETECT, 0x3fff); 398 SCHIZO_PCI_SET(sc, XMS_PCI_UPPER_RETRY_COUNTER, 0x3e8); 399 reg |= XMS_PCI_CTRL_X_ERRINT_EN; 400 } 401 SCHIZO_PCI_SET(sc, STX_PCI_CTRL, reg); 402 403 /* Set up the PCI diagnostic register. */ 404 reg = SCHIZO_PCI_READ_8(sc, STX_PCI_DIAG); 405 reg &= ~(SCZ_PCI_DIAG_RTRYARB_DIS | STX_PCI_DIAG_RETRY_DIS | 406 STX_PCI_DIAG_INTRSYNC_DIS); 407 SCHIZO_PCI_SET(sc, STX_PCI_DIAG, reg); 408 409 /* 410 * Enable DMA write parity error interrupts of version >= 7 (i.e. 411 * revision >= 2.5) Schizo and XMITS (enabling it on XMITS < 3.0 has 412 * no effect though). 413 */ 414 if ((mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 7) || 415 mode == SCHIZO_MODE_XMS) { 416 reg = SCHIZO_PCI_READ_8(sc, SX_PCI_CFG_ICD); 417 reg |= SX_PCI_CFG_ICD_DMAW_PERR_IEN; 418 SCHIZO_PCI_SET(sc, SX_PCI_CFG_ICD, reg); 419 } 420 421 /* 422 * On Tomatillo clear the I/O prefetch lengths (workaround for a 423 * Jalapeno bug). 424 */ 425 if (mode == SCHIZO_MODE_TOM) 426 SCHIZO_PCI_SET(sc, TOM_PCI_IOC_CSR, TOM_PCI_IOC_PW | 427 (1 << TOM_PCI_IOC_PREF_OFF_SHIFT) | TOM_PCI_IOC_CPRM | 428 TOM_PCI_IOC_CPRO | TOM_PCI_IOC_CPRL); 429 430 /* 431 * Hunt through all the interrupt mapping regs and register 432 * the interrupt controller for our interrupt vectors. We do 433 * this early in order to be able to catch stray interrupts. 434 * This is complicated by the fact that a pair of Schizo PBMs 435 * shares one IGN. 436 */ 437 i = OF_getprop(node, "ino-bitmap", (void *)prop_array, 438 sizeof(prop_array)); 439 if (i != -1) 440 ino_bitmap = ((uint64_t)prop_array[1] << 32) | prop_array[0]; 441 else { 442 /* 443 * If the ino-bitmap property is missing, just provide the 444 * default set of interrupts for this controller and let 445 * schizo_setup_intr() take care of child interrupts. 446 */ 447 if (sc->sc_half == 0) 448 ino_bitmap = (1ULL << STX_UE_INO) | 449 (1ULL << STX_CE_INO) | 450 (1ULL << STX_PCIERR_A_INO) | 451 (1ULL << STX_BUS_INO); 452 else 453 ino_bitmap = 1ULL << STX_PCIERR_B_INO; 454 } 455 for (i = 0; i <= STX_MAX_INO; i++) { 456 if ((ino_bitmap & (1ULL << i)) == 0) 457 continue; 458 if (i == STX_FB0_INO || i == STX_FB1_INO) 459 /* Leave for upa(4). */ 460 continue; 461 j = schizo_intr_register(sc, i); 462 if (j != 0) 463 device_printf(dev, "could not register interrupt " 464 "controller for INO %d (%d)\n", i, j); 465 } 466 467 /* 468 * Setup Safari/JBus performance counter 0 in bus cycle counting 469 * mode as timecounter. Unfortunately, this is broken with at 470 * least the version 4 Tomatillos found in Fire V120 and Blade 471 * 1500, which apparently actually count some different event at 472 * ~0.5 and 3MHz respectively instead (also when running in full 473 * power mode). Besides, one counter seems to be shared by a 474 * "pair" of Tomatillos, too. 475 */ 476 if (sc->sc_half == 0) { 477 SCHIZO_CTRL_SET(sc, STX_CTRL_PERF, 478 (STX_CTRL_PERF_DIS << STX_CTRL_PERF_CNT1_SHIFT) | 479 (STX_CTRL_PERF_BUSCYC << STX_CTRL_PERF_CNT0_SHIFT)); 480 tc = malloc(sizeof(*tc), M_DEVBUF, M_NOWAIT | M_ZERO); 481 if (tc == NULL) 482 panic("%s: could not malloc timecounter", __func__); 483 tc->tc_get_timecount = schizo_get_timecount; 484 tc->tc_counter_mask = STX_CTRL_PERF_CNT_MASK; 485 if (OF_getprop(OF_peer(0), "clock-frequency", &prop, 486 sizeof(prop)) == -1) 487 panic("%s: could not determine clock frequency", 488 __func__); 489 tc->tc_frequency = prop; 490 tc->tc_name = strdup(device_get_nameunit(dev), M_DEVBUF); 491 if (mode == SCHIZO_MODE_SCZ) 492 tc->tc_quality = SCHIZO_PERF_CNT_QLTY; 493 else 494 tc->tc_quality = -SCHIZO_PERF_CNT_QLTY; 495 tc->tc_priv = sc; 496 tc_init(tc); 497 } 498 499 /* 500 * Set up the IOMMU. Schizo, Tomatillo and XMITS all have 501 * one per PBM. Schizo and XMITS additionally have a streaming 502 * buffer, in Schizo version < 5 (i.e. revision < 2.3) it's 503 * affected by several errata though. However, except for context 504 * flushes, taking advantage of it should be okay even with those. 505 */ 506 memcpy(&sc->sc_dma_methods, &iommu_dma_methods, 507 sizeof(sc->sc_dma_methods)); 508 sc->sc_is.sis_sc = sc; 509 sc->sc_is.sis_is.is_flags = IOMMU_PRESERVE_PROM; 510 sc->sc_is.sis_is.is_pmaxaddr = IOMMU_MAXADDR(STX_IOMMU_BITS); 511 sc->sc_is.sis_is.is_sb[0] = sc->sc_is.sis_is.is_sb[1] = 0; 512 if (OF_getproplen(node, "no-streaming-cache") < 0) 513 sc->sc_is.sis_is.is_sb[0] = STX_PCI_STRBUF; 514 515#define TSBCASE(x) \ 516 case (IOTSB_BASESZ << (x)) << (IO_PAGE_SHIFT - IOTTE_SHIFT): \ 517 tsbsize = (x); \ 518 break; \ 519 520 i = OF_getprop(node, "virtual-dma", (void *)prop_array, 521 sizeof(prop_array)); 522 if (i == -1 || i != sizeof(prop_array)) 523 schizo_iommu_init(sc, 7, -1); 524 else { 525 switch (prop_array[1]) { 526 TSBCASE(1); 527 TSBCASE(2); 528 TSBCASE(3); 529 TSBCASE(4); 530 TSBCASE(5); 531 TSBCASE(6); 532 TSBCASE(7); 533 TSBCASE(8); 534 default: 535 panic("%s: unsupported DVMA size 0x%x", 536 __func__, prop_array[1]); 537 /* NOTREACHED */ 538 } 539 schizo_iommu_init(sc, tsbsize, prop_array[0]); 540 } 541 542#undef TSBCASE 543 544 /* Initialize memory and I/O rmans. */ 545 sc->sc_pci_io_rman.rm_type = RMAN_ARRAY; 546 sc->sc_pci_io_rman.rm_descr = "Schizo PCI I/O Ports"; 547 if (rman_init(&sc->sc_pci_io_rman) != 0 || 548 rman_manage_region(&sc->sc_pci_io_rman, 0, STX_IO_SIZE) != 0) 549 panic("%s: failed to set up I/O rman", __func__); 550 sc->sc_pci_mem_rman.rm_type = RMAN_ARRAY; 551 sc->sc_pci_mem_rman.rm_descr = "Schizo PCI Memory"; 552 if (rman_init(&sc->sc_pci_mem_rman) != 0 || 553 rman_manage_region(&sc->sc_pci_mem_rman, 0, STX_MEM_SIZE) != 0) 554 panic("%s: failed to set up memory rman", __func__); 555 556 i = OF_getprop_alloc(node, "ranges", sizeof(*range), (void **)&range); 557 /* 558 * Make sure that the expected ranges are present. The 559 * OFW_PCI_CS_MEM64 one is not currently used though. 560 */ 561 if (i != STX_NRANGE) 562 panic("%s: unsupported number of ranges", __func__); 563 /* 564 * Find the addresses of the various bus spaces. 565 * There should not be multiple ones of one kind. 566 * The physical start addresses of the ranges are the configuration, 567 * memory and I/O handles. 568 */ 569 for (i = 0; i < STX_NRANGE; i++) { 570 j = OFW_PCI_RANGE_CS(&range[i]); 571 if (sc->sc_pci_bh[j] != 0) 572 panic("%s: duplicate range for space %d", 573 __func__, j); 574 sc->sc_pci_bh[j] = OFW_PCI_RANGE_PHYS(&range[i]); 575 } 576 free(range, M_OFWPROP); 577 578 /* Register the softc, this is needed for paired Schizos. */ 579 SLIST_INSERT_HEAD(&schizo_softcs, sc, sc_link); 580 581 /* Allocate our tags. */ 582 sc->sc_pci_iot = sparc64_alloc_bus_tag(NULL, rman_get_bustag( 583 sc->sc_mem_res[STX_PCI]), PCI_IO_BUS_SPACE, NULL); 584 if (sc->sc_pci_iot == NULL) 585 panic("%s: could not allocate PCI I/O tag", __func__); 586 sc->sc_pci_cfgt = sparc64_alloc_bus_tag(NULL, rman_get_bustag( 587 sc->sc_mem_res[STX_PCI]), PCI_CONFIG_BUS_SPACE, NULL); 588 if (sc->sc_pci_cfgt == NULL) 589 panic("%s: could not allocate PCI configuration space tag", 590 __func__); 591 if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, 592 sc->sc_is.sis_is.is_pmaxaddr, ~0, NULL, NULL, 593 sc->sc_is.sis_is.is_pmaxaddr, 0xff, 0xffffffff, 0, NULL, NULL, 594 &sc->sc_pci_dmat) != 0) 595 panic("%s: could not create PCI DMA tag", __func__); 596 /* Customize the tag. */ 597 sc->sc_pci_dmat->dt_cookie = &sc->sc_is; 598 sc->sc_pci_dmat->dt_mt = &sc->sc_dma_methods; 599 600 /* 601 * Get the bus range from the firmware. 602 * NB: Tomatillos don't support PCI bus reenumeration. 603 */ 604 i = OF_getprop(node, "bus-range", (void *)prop_array, 605 sizeof(prop_array)); 606 if (i == -1) 607 panic("%s: could not get bus-range", __func__); 608 if (i != sizeof(prop_array)) 609 panic("%s: broken bus-range (%d)", __func__, i); 610 sc->sc_pci_secbus = prop_array[0]; 611 sc->sc_pci_subbus = prop_array[1]; 612 if (bootverbose) 613 device_printf(dev, "bus range %u to %u; PCI bus %d\n", 614 sc->sc_pci_secbus, sc->sc_pci_subbus, sc->sc_pci_secbus); 615 616 /* Clear any pending PCI error bits. */ 617 PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, 618 PCIR_STATUS, PCIB_READ_CONFIG(dev, sc->sc_pci_secbus, 619 STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2), 2); 620 SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL)); 621 SCHIZO_PCI_SET(sc, STX_PCI_AFSR, SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR)); 622 623 /* 624 * Establish handlers for interesting interrupts... 625 * Someone at Sun clearly was smoking crack; with Schizos PCI 626 * bus error interrupts for one PBM can be routed to the other 627 * PBM though we obviously need to use the softc of the former 628 * as the argument for the interrupt handler and the softc of 629 * the latter as the argument for the interrupt controller. 630 */ 631 if (sc->sc_half == 0) { 632 if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 || 633 (osc != NULL && ((struct schizo_icarg *)intr_vectors[ 634 INTMAP_VEC(sc->sc_ign, STX_PCIERR_A_INO)].iv_icarg)-> 635 sica_sc == osc)) 636 /* 637 * We are the driver for PBM A and either also 638 * registered the interrupt controller for us or 639 * the driver for PBM B has probed first and 640 * registered it for us. 641 */ 642 schizo_set_intr(sc, 0, STX_PCIERR_A_INO, 643 schizo_pci_bus); 644 if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 && 645 osc != NULL) 646 /* 647 * We are the driver for PBM A but registered 648 * the interrupt controller for PBM B, i.e. the 649 * driver for PBM B attached first but couldn't 650 * set up a handler for PBM B. 651 */ 652 schizo_set_intr(osc, 0, STX_PCIERR_B_INO, 653 schizo_pci_bus); 654 } else { 655 if ((ino_bitmap & (1ULL << STX_PCIERR_B_INO)) != 0 || 656 (osc != NULL && ((struct schizo_icarg *)intr_vectors[ 657 INTMAP_VEC(sc->sc_ign, STX_PCIERR_B_INO)].iv_icarg)-> 658 sica_sc == osc)) 659 /* 660 * We are the driver for PBM B and either also 661 * registered the interrupt controller for us or 662 * the driver for PBM A has probed first and 663 * registered it for us. 664 */ 665 schizo_set_intr(sc, 0, STX_PCIERR_B_INO, 666 schizo_pci_bus); 667 if ((ino_bitmap & (1ULL << STX_PCIERR_A_INO)) != 0 && 668 osc != NULL) 669 /* 670 * We are the driver for PBM B but registered 671 * the interrupt controller for PBM A, i.e. the 672 * driver for PBM A attached first but couldn't 673 * set up a handler for PBM A. 674 */ 675 schizo_set_intr(osc, 0, STX_PCIERR_A_INO, 676 schizo_pci_bus); 677 } 678 if ((ino_bitmap & (1ULL << STX_UE_INO)) != 0) 679 schizo_set_intr(sc, 1, STX_UE_INO, schizo_ue); 680 if ((ino_bitmap & (1ULL << STX_CE_INO)) != 0) 681 schizo_set_intr(sc, 2, STX_CE_INO, schizo_ce); 682 if ((ino_bitmap & (1ULL << STX_BUS_INO)) != 0) 683 schizo_set_intr(sc, 3, STX_BUS_INO, schizo_host_bus); 684 685 /* 686 * According to the Schizo Errata I-13, consistent DMA flushing/ 687 * syncing is FUBAR in version < 5 (i.e. revision < 2.3) bridges, 688 * so we can't use it and need to live with the consequences. With 689 * Schizo version >= 5, CDMA flushing/syncing is usable but requires 690 * the workaround described in Schizo Errata I-23. With Tomatillo 691 * and XMITS, CDMA flushing/syncing works as expected, Tomatillo 692 * version <= 4 (i.e. revision <= 2.3) bridges additionally require 693 * a block store after a write to TOMXMS_PCI_DMA_SYNC_PEND though. 694 */ 695 if ((sc->sc_mode == SCHIZO_MODE_SCZ && sc->sc_ver >= 5) || 696 sc->sc_mode == SCHIZO_MODE_TOM || 697 sc->sc_mode == SCHIZO_MODE_XMS) { 698 if (sc->sc_mode == SCHIZO_MODE_SCZ) { 699 sc->sc_dma_methods.dm_dmamap_sync = 700 schizo_dmamap_sync; 701 sc->sc_cdma_state = SCHIZO_CDMA_STATE_IDLE; 702 /* 703 * Some firmware versions include the CDMA interrupt 704 * at RID 4 but most don't. With the latter we add 705 * it ourselves at the spare RID 5. 706 */ 707 i = INTINO(bus_get_resource_start(dev, SYS_RES_IRQ, 708 4)); 709 if (i == STX_CDMA_A_INO || i == STX_CDMA_B_INO) { 710 (void)schizo_get_intrmap(sc, i, NULL, 711 &sc->sc_cdma_clr); 712 schizo_set_intr(sc, 4, i, schizo_cdma); 713 } else { 714 i = STX_CDMA_A_INO + sc->sc_half; 715 if (bus_set_resource(dev, SYS_RES_IRQ, 5, 716 INTMAP_VEC(sc->sc_ign, i), 1) != 0) 717 panic("%s: failed to add CDMA " 718 "interrupt", __func__); 719 j = schizo_intr_register(sc, i); 720 if (j != 0) 721 panic("%s: could not register " 722 "interrupt controller for CDMA " 723 "(%d)", __func__, j); 724 (void)schizo_get_intrmap(sc, i, NULL, 725 &sc->sc_cdma_clr); 726 schizo_set_intr(sc, 5, i, schizo_cdma); 727 } 728 } else { 729 if (sc->sc_mode == SCHIZO_MODE_XMS) 730 mtx_init(&sc->sc_sync_mtx, "pcib_sync_mtx", 731 NULL, MTX_SPIN); 732 sc->sc_sync_val = 1ULL << (STX_PCIERR_A_INO + 733 sc->sc_half); 734 sc->sc_dma_methods.dm_dmamap_sync = 735 ichip_dmamap_sync; 736 } 737 if (sc->sc_mode == SCHIZO_MODE_TOM && sc->sc_ver <= 4) 738 sc->sc_flags |= SCHIZO_FLAGS_BSWAR; 739 } 740 741 /* 742 * Set the latency timer register as this isn't always done by the 743 * firmware. 744 */ 745 PCIB_WRITE_CONFIG(dev, sc->sc_pci_secbus, STX_CS_DEVICE, STX_CS_FUNC, 746 PCIR_LATTIMER, OFW_PCI_LATENCY, 1); 747 748 ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(ofw_pci_intr_t)); 749 750#define SCHIZO_SYSCTL_ADD_UINT(name, arg, desc) \ 751 SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev), \ 752 SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, \ 753 (name), CTLFLAG_RD, (arg), 0, (desc)) 754 755 SCHIZO_SYSCTL_ADD_UINT("dma_ce", &sc->sc_stats_dma_ce, 756 "DMA correctable errors"); 757 SCHIZO_SYSCTL_ADD_UINT("pci_non_fatal", &sc->sc_stats_pci_non_fatal, 758 "PCI bus non-fatal errors"); 759 760#undef SCHIZO_SYSCTL_ADD_UINT 761 762 device_add_child(dev, "pci", -1); 763 return (bus_generic_attach(dev)); 764} 765 766static void 767schizo_set_intr(struct schizo_softc *sc, u_int index, u_int ino, 768 driver_filter_t handler) 769{ 770 u_long vec; 771 int rid; 772 773 rid = index; 774 sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, 775 SYS_RES_IRQ, &rid, RF_ACTIVE); 776 if (sc->sc_irq_res[index] == NULL || 777 INTINO(vec = rman_get_start(sc->sc_irq_res[index])) != ino || 778 INTIGN(vec) != sc->sc_ign || 779 intr_vectors[vec].iv_ic != &schizo_ic || 780 bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 781 INTR_TYPE_MISC | INTR_BRIDGE, handler, NULL, sc, 782 &sc->sc_ihand[index]) != 0) 783 panic("%s: failed to set up interrupt %d", __func__, index); 784} 785 786static int 787schizo_intr_register(struct schizo_softc *sc, u_int ino) 788{ 789 struct schizo_icarg *sica; 790 bus_addr_t intrclr, intrmap; 791 int error; 792 793 if (schizo_get_intrmap(sc, ino, &intrmap, &intrclr) == 0) 794 return (ENXIO); 795 sica = malloc(sizeof(*sica), M_DEVBUF, M_NOWAIT); 796 if (sica == NULL) 797 return (ENOMEM); 798 sica->sica_sc = sc; 799 sica->sica_map = intrmap; 800 sica->sica_clr = intrclr; 801#ifdef SCHIZO_DEBUG 802 device_printf(sc->sc_dev, "intr map (INO %d) %#lx: %#lx, clr: %#lx\n", 803 ino, (u_long)intrmap, (u_long)SCHIZO_PCI_READ_8(sc, intrmap), 804 (u_long)intrclr); 805#endif 806 error = (intr_controller_register(INTMAP_VEC(sc->sc_ign, ino), 807 &schizo_ic, sica)); 808 if (error != 0) 809 free(sica, M_DEVBUF); 810 return (error); 811} 812 813static int 814schizo_get_intrmap(struct schizo_softc *sc, u_int ino, 815 bus_addr_t *intrmapptr, bus_addr_t *intrclrptr) 816{ 817 bus_addr_t intrclr, intrmap; 818 uint64_t mr; 819 820 /* 821 * XXX we only look for INOs rather than INRs since the firmware 822 * may not provide the IGN and the IGN is constant for all devices 823 * on that PCI controller. 824 */ 825 826 if (ino > STX_MAX_INO) { 827 device_printf(sc->sc_dev, "out of range INO %d requested\n", 828 ino); 829 return (0); 830 } 831 832 intrmap = STX_PCI_IMAP_BASE + (ino << 3); 833 intrclr = STX_PCI_ICLR_BASE + (ino << 3); 834 mr = SCHIZO_PCI_READ_8(sc, intrmap); 835 if (INTINO(mr) != ino) { 836 device_printf(sc->sc_dev, 837 "interrupt map entry does not match INO (%d != %d)\n", 838 (int)INTINO(mr), ino); 839 return (0); 840 } 841 842 if (intrmapptr != NULL) 843 *intrmapptr = intrmap; 844 if (intrclrptr != NULL) 845 *intrclrptr = intrclr; 846 return (1); 847} 848 849/* 850 * Interrupt handlers 851 */ 852static int 853schizo_pci_bus(void *arg) 854{ 855 struct schizo_softc *sc = arg; 856 uint64_t afar, afsr, csr, iommu, xstat; 857 uint32_t status; 858 u_int fatal; 859 860 fatal = 0; 861 862 mtx_lock_spin(sc->sc_mtx); 863 864 afar = SCHIZO_PCI_READ_8(sc, STX_PCI_AFAR); 865 afsr = SCHIZO_PCI_READ_8(sc, STX_PCI_AFSR); 866 csr = SCHIZO_PCI_READ_8(sc, STX_PCI_CTRL); 867 iommu = SCHIZO_PCI_READ_8(sc, STX_PCI_IOMMU); 868 if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0) 869 xstat = SCHIZO_PCI_READ_8(sc, XMS_PCI_X_ERR_STAT); 870 else 871 xstat = 0; 872 status = PCIB_READ_CONFIG(sc->sc_dev, sc->sc_pci_secbus, 873 STX_CS_DEVICE, STX_CS_FUNC, PCIR_STATUS, 2); 874 875 /* 876 * IOMMU errors are only fatal on Tomatillo and there also only if 877 * target abort was not signaled. 878 */ 879 if ((csr & STX_PCI_CTRL_MMU_ERR) != 0 && 880 (iommu & TOM_PCI_IOMMU_ERR) != 0 && 881 ((status & PCIM_STATUS_STABORT) == 0 || 882 ((iommu & TOM_PCI_IOMMU_ERRMASK) != TOM_PCI_IOMMU_INVALID_ERR && 883 (iommu & TOM_PCI_IOMMU_ERR_ILLTSBTBW) == 0 && 884 (iommu & TOM_PCI_IOMMU_ERR_BAD_VA) == 0))) 885 fatal = 1; 886 else if ((status & PCIM_STATUS_STABORT) != 0) 887 fatal = 1; 888 if ((status & (PCIM_STATUS_PERR | PCIM_STATUS_SERR | 889 PCIM_STATUS_RMABORT | PCIM_STATUS_RTABORT | 890 PCIM_STATUS_MDPERR)) != 0 || 891 (csr & (SCZ_PCI_CTRL_BUS_UNUS | TOM_PCI_CTRL_DTO_ERR | 892 STX_PCI_CTRL_TTO_ERR | STX_PCI_CTRL_RTRY_ERR | 893 SCZ_PCI_CTRL_SBH_ERR | STX_PCI_CTRL_SERR)) != 0 || 894 (afsr & (STX_PCI_AFSR_P_MA | STX_PCI_AFSR_P_TA | 895 STX_PCI_AFSR_P_RTRY | STX_PCI_AFSR_P_PERR | STX_PCI_AFSR_P_TTO | 896 STX_PCI_AFSR_P_UNUS)) != 0) 897 fatal = 1; 898 if (xstat & (XMS_PCI_X_ERR_STAT_P_SC_DSCRD | 899 XMS_PCI_X_ERR_STAT_P_SC_TTO | XMS_PCI_X_ERR_STAT_P_SDSTAT | 900 XMS_PCI_X_ERR_STAT_P_SMMU | XMS_PCI_X_ERR_STAT_P_CDSTAT | 901 XMS_PCI_X_ERR_STAT_P_CMMU | XMS_PCI_X_ERR_STAT_PERR_RCV)) 902 fatal = 1; 903 if (fatal == 0) 904 sc->sc_stats_pci_non_fatal++; 905 906 device_printf(sc->sc_dev, "PCI bus %c error AFAR %#llx AFSR %#llx " 907 "PCI CSR %#llx IOMMU %#llx PCI-X %#llx STATUS %#x\n", 908 'A' + sc->sc_half, (unsigned long long)afar, 909 (unsigned long long)afsr, (unsigned long long)csr, 910 (unsigned long long)iommu, (unsigned long long)xstat, status); 911 912 /* Clear the error bits that we caught. */ 913 PCIB_WRITE_CONFIG(sc->sc_dev, sc->sc_pci_secbus, STX_CS_DEVICE, 914 STX_CS_FUNC, PCIR_STATUS, status, 2); 915 SCHIZO_PCI_WRITE_8(sc, STX_PCI_CTRL, csr); 916 SCHIZO_PCI_WRITE_8(sc, STX_PCI_AFSR, afsr); 917 SCHIZO_PCI_WRITE_8(sc, STX_PCI_IOMMU, iommu); 918 if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0) 919 SCHIZO_PCI_WRITE_8(sc, XMS_PCI_X_ERR_STAT, xstat); 920 921 mtx_unlock_spin(sc->sc_mtx); 922 923 if (fatal != 0) 924 panic("%s: fatal PCI bus error", 925 device_get_nameunit(sc->sc_dev)); 926 return (FILTER_HANDLED); 927} 928 929static int 930schizo_ue(void *arg) 931{ 932 struct schizo_softc *sc = arg; 933 uint64_t afar, afsr; 934 int i; 935 936 afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFAR); 937 for (i = 0; i < 1000; i++) 938 if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) & 939 STX_CTRL_CE_AFSR_ERRPNDG) == 0) 940 break; 941 panic("%s: uncorrectable DMA error AFAR %#llx AFSR %#llx", 942 device_get_nameunit(sc->sc_dev), (unsigned long long)afar, 943 (unsigned long long)afsr); 944 return (FILTER_HANDLED); 945} 946 947static int 948schizo_ce(void *arg) 949{ 950 struct schizo_softc *sc = arg; 951 uint64_t afar, afsr; 952 int i; 953 954 mtx_lock_spin(sc->sc_mtx); 955 956 afar = SCHIZO_CTRL_READ_8(sc, STX_CTRL_CE_AFAR); 957 for (i = 0; i < 1000; i++) 958 if (((afsr = SCHIZO_CTRL_READ_8(sc, STX_CTRL_UE_AFSR)) & 959 STX_CTRL_CE_AFSR_ERRPNDG) == 0) 960 break; 961 sc->sc_stats_dma_ce++; 962 device_printf(sc->sc_dev, 963 "correctable DMA error AFAR %#llx AFSR %#llx\n", 964 (unsigned long long)afar, (unsigned long long)afsr); 965 966 /* Clear the error bits that we caught. */ 967 SCHIZO_CTRL_WRITE_8(sc, STX_CTRL_UE_AFSR, afsr); 968 969 mtx_unlock_spin(sc->sc_mtx); 970 971 return (FILTER_HANDLED); 972} 973 974static int 975schizo_host_bus(void *arg) 976{ 977 struct schizo_softc *sc = arg; 978 uint64_t errlog; 979 980 errlog = SCHIZO_CTRL_READ_8(sc, STX_CTRL_BUS_ERRLOG); 981 panic("%s: %s error %#llx", device_get_nameunit(sc->sc_dev), 982 sc->sc_mode == SCHIZO_MODE_TOM ? "JBus" : "Safari", 983 (unsigned long long)errlog); 984 return (FILTER_HANDLED); 985} 986 987static int 988schizo_cdma(void *arg) 989{ 990 struct schizo_softc *sc = arg; 991 992 atomic_store_rel_32(&sc->sc_cdma_state, SCHIZO_CDMA_STATE_RECEIVED); 993 return (FILTER_HANDLED); 994} 995 996static void 997schizo_iommu_init(struct schizo_softc *sc, int tsbsize, uint32_t dvmabase) 998{ 999 1000 /* Punch in our copies. */ 1001 sc->sc_is.sis_is.is_bustag = rman_get_bustag(sc->sc_mem_res[STX_PCI]); 1002 sc->sc_is.sis_is.is_bushandle = 1003 rman_get_bushandle(sc->sc_mem_res[STX_PCI]); 1004 sc->sc_is.sis_is.is_iommu = STX_PCI_IOMMU; 1005 sc->sc_is.sis_is.is_dtag = STX_PCI_IOMMU_TLB_TAG_DIAG; 1006 sc->sc_is.sis_is.is_ddram = STX_PCI_IOMMU_TLB_DATA_DIAG; 1007 sc->sc_is.sis_is.is_dqueue = STX_PCI_IOMMU_QUEUE_DIAG; 1008 sc->sc_is.sis_is.is_dva = STX_PCI_IOMMU_SVADIAG; 1009 sc->sc_is.sis_is.is_dtcmp = STX_PCI_IOMMU_TLB_CMP_DIAG; 1010 1011 iommu_init(device_get_nameunit(sc->sc_dev), 1012 (struct iommu_state *)&sc->sc_is, tsbsize, dvmabase, 0); 1013} 1014 1015static int 1016schizo_maxslots(device_t dev) 1017{ 1018 struct schizo_softc *sc; 1019 1020 sc = device_get_softc(dev); 1021 if (sc->sc_mode == SCHIZO_MODE_SCZ) 1022 return (sc->sc_half == 0 ? 4 : 6); 1023 1024 /* XXX: is this correct? */ 1025 return (PCI_SLOTMAX); 1026} 1027 1028static uint32_t 1029schizo_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 1030 int width) 1031{ 1032 struct schizo_softc *sc; 1033 bus_space_handle_t bh; 1034 u_long offset = 0; 1035 uint32_t r, wrd; 1036 int i; 1037 uint16_t shrt; 1038 uint8_t byte; 1039 1040 sc = device_get_softc(dev); 1041 if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || 1042 slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) 1043 return (-1); 1044 1045 /* 1046 * The Schizo bridges contain a dupe of their header at 0x80. 1047 */ 1048 if (sc->sc_mode == SCHIZO_MODE_SCZ && bus == sc->sc_pci_secbus && 1049 slot == STX_CS_DEVICE && func == STX_CS_FUNC && 1050 reg + width > 0x80) 1051 return (0); 1052 1053 offset = STX_CONF_OFF(bus, slot, func, reg); 1054 bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; 1055 switch (width) { 1056 case 1: 1057 i = bus_space_peek_1(sc->sc_pci_cfgt, bh, offset, &byte); 1058 r = byte; 1059 break; 1060 case 2: 1061 i = bus_space_peek_2(sc->sc_pci_cfgt, bh, offset, &shrt); 1062 r = shrt; 1063 break; 1064 case 4: 1065 i = bus_space_peek_4(sc->sc_pci_cfgt, bh, offset, &wrd); 1066 r = wrd; 1067 break; 1068 default: 1069 panic("%s: bad width", __func__); 1070 /* NOTREACHED */ 1071 } 1072 1073 if (i) { 1074#ifdef SCHIZO_DEBUG 1075 printf("%s: read data error reading: %d.%d.%d: 0x%x\n", 1076 __func__, bus, slot, func, reg); 1077#endif 1078 r = -1; 1079 } 1080 return (r); 1081} 1082 1083static void 1084schizo_write_config(device_t dev, u_int bus, u_int slot, u_int func, 1085 u_int reg, uint32_t val, int width) 1086{ 1087 struct schizo_softc *sc; 1088 bus_space_handle_t bh; 1089 u_long offset = 0; 1090 1091 sc = device_get_softc(dev); 1092 if (bus < sc->sc_pci_secbus || bus > sc->sc_pci_subbus || 1093 slot > PCI_SLOTMAX || func > PCI_FUNCMAX || reg > PCI_REGMAX) 1094 return; 1095 1096 offset = STX_CONF_OFF(bus, slot, func, reg); 1097 bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; 1098 switch (width) { 1099 case 1: 1100 bus_space_write_1(sc->sc_pci_cfgt, bh, offset, val); 1101 break; 1102 case 2: 1103 bus_space_write_2(sc->sc_pci_cfgt, bh, offset, val); 1104 break; 1105 case 4: 1106 bus_space_write_4(sc->sc_pci_cfgt, bh, offset, val); 1107 break; 1108 default: 1109 panic("%s: bad width", __func__); 1110 /* NOTREACHED */ 1111 } 1112} 1113 1114static int 1115schizo_route_interrupt(device_t bridge, device_t dev, int pin) 1116{ 1117 struct schizo_softc *sc; 1118 struct ofw_pci_register reg; 1119 ofw_pci_intr_t pintr, mintr; 1120 uint8_t maskbuf[sizeof(reg) + sizeof(pintr)]; 1121 1122 sc = device_get_softc(bridge); 1123 pintr = pin; 1124 if (ofw_bus_lookup_imap(ofw_bus_get_node(dev), &sc->sc_pci_iinfo, 1125 ®, sizeof(reg), &pintr, sizeof(pintr), &mintr, sizeof(mintr), 1126 NULL, maskbuf)) 1127 return (mintr); 1128 1129 device_printf(bridge, "could not route pin %d for device %d.%d\n", 1130 pin, pci_get_slot(dev), pci_get_function(dev)); 1131 return (PCI_INVALID_IRQ); 1132} 1133 1134static int 1135schizo_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 1136{ 1137 struct schizo_softc *sc; 1138 1139 sc = device_get_softc(dev); 1140 switch (which) { 1141 case PCIB_IVAR_DOMAIN: 1142 *result = device_get_unit(dev); 1143 return (0); 1144 case PCIB_IVAR_BUS: 1145 *result = sc->sc_pci_secbus; 1146 return (0); 1147 } 1148 return (ENOENT); 1149} 1150 1151static void 1152schizo_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) 1153{ 1154 struct timeval cur, end; 1155 struct schizo_iommu_state *sis = dt->dt_cookie; 1156 struct schizo_softc *sc = sis->sis_sc; 1157 int res; 1158 1159 if ((map->dm_flags & DMF_STREAMED) != 0) { 1160 iommu_dma_methods.dm_dmamap_sync(dt, map, op); 1161 return; 1162 } 1163 1164 if ((map->dm_flags & DMF_LOADED) == 0) 1165 return; 1166 1167 if ((op & BUS_DMASYNC_POSTREAD) != 0) { 1168 /* 1169 * Note that in order to allow this function to be called from 1170 * filters we would need to use a spin mutex for serialization 1171 * but given that these disable interrupts we have to emulate 1172 * one. 1173 */ 1174 for (; atomic_cmpset_acq_32(&sc->sc_cdma_state, 1175 SCHIZO_CDMA_STATE_IDLE, SCHIZO_CDMA_STATE_PENDING) == 0;) 1176 ; 1177 SCHIZO_PCI_WRITE_8(sc, sc->sc_cdma_clr, INTCLR_RECEIVED); 1178 microuptime(&cur); 1179 end.tv_sec = 1; 1180 end.tv_usec = 0; 1181 timevaladd(&end, &cur); 1182 for (; (res = atomic_cmpset_rel_32(&sc->sc_cdma_state, 1183 SCHIZO_CDMA_STATE_RECEIVED, SCHIZO_CDMA_STATE_IDLE)) == 1184 0 && timevalcmp(&cur, &end, <=);) 1185 microuptime(&cur); 1186 if (res == 0) 1187 panic("%s: DMA does not sync", __func__); 1188 } 1189 1190 if ((op & BUS_DMASYNC_PREWRITE) != 0) 1191 membar(Sync); 1192} 1193 1194#define VIS_BLOCKSIZE 64 1195 1196static void 1197ichip_dmamap_sync(bus_dma_tag_t dt, bus_dmamap_t map, bus_dmasync_op_t op) 1198{ 1199 static u_char buf[VIS_BLOCKSIZE] __aligned(VIS_BLOCKSIZE); 1200 struct timeval cur, end; 1201 struct schizo_iommu_state *sis = dt->dt_cookie; 1202 struct schizo_softc *sc = sis->sis_sc; 1203 register_t reg, s; 1204 1205 if ((map->dm_flags & DMF_STREAMED) != 0) { 1206 iommu_dma_methods.dm_dmamap_sync(dt, map, op); 1207 return; 1208 } 1209 1210 if ((map->dm_flags & DMF_LOADED) == 0) 1211 return; 1212 1213 if ((op & BUS_DMASYNC_POSTREAD) != 0) { 1214 if (sc->sc_mode == SCHIZO_MODE_XMS) 1215 mtx_lock_spin(&sc->sc_sync_mtx); 1216 SCHIZO_PCI_WRITE_8(sc, TOMXMS_PCI_DMA_SYNC_PEND, 1217 sc->sc_sync_val); 1218 microuptime(&cur); 1219 end.tv_sec = 1; 1220 end.tv_usec = 0; 1221 timevaladd(&end, &cur); 1222 for (; ((reg = SCHIZO_PCI_READ_8(sc, 1223 TOMXMS_PCI_DMA_SYNC_PEND)) & sc->sc_sync_val) != 0 && 1224 timevalcmp(&cur, &end, <=);) 1225 microuptime(&cur); 1226 if ((reg & sc->sc_sync_val) != 0) 1227 panic("%s: DMA does not sync", __func__); 1228 if (sc->sc_mode == SCHIZO_MODE_XMS) 1229 mtx_unlock_spin(&sc->sc_sync_mtx); 1230 else if ((sc->sc_flags & SCHIZO_FLAGS_BSWAR) != 0) { 1231 s = intr_disable(); 1232 reg = rd(fprs); 1233 wr(fprs, reg | FPRS_FEF, 0); 1234 __asm __volatile("stda %%f0, [%0] %1" 1235 : : "r" (buf), "n" (ASI_BLK_COMMIT_S)); 1236 membar(Sync); 1237 wr(fprs, reg, 0); 1238 intr_restore(s); 1239 return; 1240 } 1241 } 1242 1243 if ((op & BUS_DMASYNC_PREWRITE) != 0) 1244 membar(Sync); 1245} 1246 1247static void 1248schizo_intr_enable(void *arg) 1249{ 1250 struct intr_vector *iv = arg; 1251 struct schizo_icarg *sica = iv->iv_icarg; 1252 1253 SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map, 1254 INTMAP_ENABLE(iv->iv_vec, iv->iv_mid)); 1255} 1256 1257static void 1258schizo_intr_disable(void *arg) 1259{ 1260 struct intr_vector *iv = arg; 1261 struct schizo_icarg *sica = iv->iv_icarg; 1262 1263 SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map, iv->iv_vec); 1264} 1265 1266static void 1267schizo_intr_assign(void *arg) 1268{ 1269 struct intr_vector *iv = arg; 1270 struct schizo_icarg *sica = iv->iv_icarg; 1271 1272 SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_map, INTMAP_TID( 1273 SCHIZO_PCI_READ_8(sica->sica_sc, sica->sica_map), iv->iv_mid)); 1274} 1275 1276static void 1277schizo_intr_clear(void *arg) 1278{ 1279 struct intr_vector *iv = arg; 1280 struct schizo_icarg *sica = iv->iv_icarg; 1281 1282 SCHIZO_PCI_WRITE_8(sica->sica_sc, sica->sica_clr, INTCLR_IDLE); 1283} 1284 1285static int 1286schizo_setup_intr(device_t dev, device_t child, struct resource *ires, 1287 int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, 1288 void **cookiep) 1289{ 1290 struct schizo_softc *sc; 1291 u_long vec; 1292 int error; 1293 1294 sc = device_get_softc(dev); 1295 /* 1296 * Make sure the vector is fully specified. 1297 */ 1298 vec = rman_get_start(ires); 1299 if (INTIGN(vec) != sc->sc_ign) { 1300 device_printf(dev, "invalid interrupt vector 0x%lx\n", vec); 1301 return (EINVAL); 1302 } 1303 1304 if (intr_vectors[vec].iv_ic == &schizo_ic) { 1305 /* 1306 * Ensure we use the right softc in case the interrupt 1307 * is routed to our companion PBM for some odd reason. 1308 */ 1309 sc = ((struct schizo_icarg *)intr_vectors[vec].iv_icarg)-> 1310 sica_sc; 1311 } else if (intr_vectors[vec].iv_ic == NULL) { 1312 /* 1313 * Work around broken firmware which misses entries in 1314 * the ino-bitmap. 1315 */ 1316 error = schizo_intr_register(sc, INTINO(vec)); 1317 if (error != 0) { 1318 device_printf(dev, "could not register interrupt " 1319 "controller for vector 0x%lx (%d)\n", vec, error); 1320 return (error); 1321 } 1322 if (bootverbose) 1323 device_printf(dev, "belatedly registered as " 1324 "interrupt controller for vector 0x%lx\n", vec); 1325 } else { 1326 device_printf(dev, 1327 "invalid interrupt controller for vector 0x%lx\n", vec); 1328 return (EINVAL); 1329 } 1330 return (bus_generic_setup_intr(dev, child, ires, flags, filt, intr, 1331 arg, cookiep)); 1332} 1333 1334static struct resource * 1335schizo_alloc_resource(device_t bus, device_t child, int type, int *rid, 1336 u_long start, u_long end, u_long count, u_int flags) 1337{ 1338 struct schizo_softc *sc; 1339 struct resource *rv; 1340 struct rman *rm; 1341 1342 sc = device_get_softc(bus); 1343 switch (type) { 1344 case SYS_RES_IRQ: 1345 /* 1346 * XXX: Don't accept blank ranges for now, only single 1347 * interrupts. The other case should not happen with 1348 * the MI PCI code... 1349 * XXX: This may return a resource that is out of the 1350 * range that was specified. Is this correct...? 1351 */ 1352 if (start != end) 1353 panic("%s: XXX: interrupt range", __func__); 1354 start = end = INTMAP_VEC(sc->sc_ign, end); 1355 return (bus_generic_alloc_resource(bus, child, type, rid, 1356 start, end, count, flags)); 1357 case SYS_RES_MEMORY: 1358 rm = &sc->sc_pci_mem_rman; 1359 break; 1360 case SYS_RES_IOPORT: 1361 rm = &sc->sc_pci_io_rman; 1362 break; 1363 default: 1364 return (NULL); 1365 } 1366 1367 rv = rman_reserve_resource(rm, start, end, count, flags & ~RF_ACTIVE, 1368 child); 1369 if (rv == NULL) 1370 return (NULL); 1371 rman_set_rid(rv, *rid); 1372 1373 if ((flags & RF_ACTIVE) != 0 && bus_activate_resource(child, type, 1374 *rid, rv) != 0) { 1375 rman_release_resource(rv); 1376 return (NULL); 1377 } 1378 return (rv); 1379} 1380 1381static int 1382schizo_activate_resource(device_t bus, device_t child, int type, int rid, 1383 struct resource *r) 1384{ 1385 struct schizo_softc *sc; 1386 struct bus_space_tag *tag; 1387 1388 sc = device_get_softc(bus); 1389 switch (type) { 1390 case SYS_RES_IRQ: 1391 return (bus_generic_activate_resource(bus, child, type, rid, 1392 r)); 1393 case SYS_RES_MEMORY: 1394 tag = sparc64_alloc_bus_tag(r, rman_get_bustag( 1395 sc->sc_mem_res[STX_PCI]), PCI_MEMORY_BUS_SPACE, NULL); 1396 if (tag == NULL) 1397 return (ENOMEM); 1398 rman_set_bustag(r, tag); 1399 rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_MEM32] + 1400 rman_get_start(r)); 1401 break; 1402 case SYS_RES_IOPORT: 1403 rman_set_bustag(r, sc->sc_pci_iot); 1404 rman_set_bushandle(r, sc->sc_pci_bh[OFW_PCI_CS_IO] + 1405 rman_get_start(r)); 1406 break; 1407 } 1408 return (rman_activate_resource(r)); 1409} 1410 1411static int 1412schizo_adjust_resource(device_t bus, device_t child, int type, 1413 struct resource *r, u_long start, u_long end) 1414{ 1415 struct schizo_softc *sc; 1416 struct rman *rm; 1417 1418 sc = device_get_softc(bus); 1419 switch (type) { 1420 case SYS_RES_IRQ: 1421 return (bus_generic_adjust_resource(bus, child, type, r, 1422 start, end)); 1423 case SYS_RES_MEMORY: 1424 rm = &sc->sc_pci_mem_rman; 1425 break; 1426 case SYS_RES_IOPORT: 1427 rm = &sc->sc_pci_io_rman; 1428 break; 1429 default: 1430 return (EINVAL); 1431 } 1432 if (rman_is_region_manager(r, rm) == 0) 1433 return (EINVAL); 1434 return (rman_adjust_resource(r, start, end)); 1435} 1436 1437static bus_dma_tag_t 1438schizo_get_dma_tag(device_t bus, device_t child __unused) 1439{ 1440 struct schizo_softc *sc; 1441 1442 sc = device_get_softc(bus); 1443 return (sc->sc_pci_dmat); 1444} 1445 1446static phandle_t 1447schizo_get_node(device_t bus, device_t child __unused) 1448{ 1449 struct schizo_softc *sc; 1450 1451 sc = device_get_softc(bus); 1452 /* We only have one child, the PCI bus, which needs our own node. */ 1453 return (sc->sc_node); 1454} 1455 1456static void 1457schizo_setup_device(device_t bus, device_t child) 1458{ 1459 struct schizo_softc *sc; 1460 uint64_t reg; 1461 int capreg; 1462 1463 sc = device_get_softc(bus); 1464 /* 1465 * Disable bus parking in order to work around a bus hang caused by 1466 * Casinni/Skyhawk combinations. 1467 */ 1468 if (OF_getproplen(ofw_bus_get_node(child), "pci-req-removal") >= 0) 1469 SCHIZO_PCI_SET(sc, STX_PCI_CTRL, SCHIZO_PCI_READ_8(sc, 1470 STX_PCI_CTRL) & ~STX_PCI_CTRL_ARB_PARK); 1471 1472 if (sc->sc_mode == SCHIZO_MODE_XMS) { 1473 /* XMITS NCPQ WAR: set outstanding split transactions to 1. */ 1474 if ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 && 1475 (pci_read_config(child, PCIR_HDRTYPE, 1) & 1476 PCIM_HDRTYPE) != PCIM_HDRTYPE_BRIDGE && 1477 pci_find_cap(child, PCIY_PCIX, &capreg) == 0) 1478 pci_write_config(child, capreg + PCIXR_COMMAND, 1479 pci_read_config(child, capreg + PCIXR_COMMAND, 1480 2) & 0x7c, 2); 1481 /* XMITS 3.x WAR: set BUGCNTL iff value is unexpected. */ 1482 if (sc->sc_mrev >= 4) { 1483 reg = ((sc->sc_flags & SCHIZO_FLAGS_XMODE) != 0 ? 1484 0xa0UL : 0xffUL) << XMS_PCI_X_DIAG_BUGCNTL_SHIFT; 1485 if ((SCHIZO_PCI_READ_8(sc, XMS_PCI_X_DIAG) & 1486 XMS_PCI_X_DIAG_BUGCNTL_MASK) != reg) 1487 SCHIZO_PCI_SET(sc, XMS_PCI_X_DIAG, reg); 1488 } 1489 } 1490} 1491 1492static u_int 1493schizo_get_timecount(struct timecounter *tc) 1494{ 1495 struct schizo_softc *sc; 1496 1497 sc = tc->tc_priv; 1498 return ((SCHIZO_CTRL_READ_8(sc, STX_CTRL_PERF_CNT) & 1499 (STX_CTRL_PERF_CNT_MASK << STX_CTRL_PERF_CNT_CNT0_SHIFT)) >> 1500 STX_CTRL_PERF_CNT_CNT0_SHIFT); 1501} 1502