psycho.c (166901) | psycho.c (167308) |
---|---|
1/*- 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> | 1/*- 2 * Copyright (c) 1999, 2000 Matthew R. Green 3 * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org> |
4 * Copyright (c) 2005 - 2006 Marius Strobl <marius@FreeBSD.org> |
|
4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright --- 13 unchanged lines hidden (view full) --- 25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 30 */ 31 32#include <sys/cdefs.h> | 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright --- 13 unchanged lines hidden (view full) --- 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 * from: NetBSD: psycho.c,v 1.39 2001/10/07 20:30:41 eeh Exp 31 */ 32 33#include <sys/cdefs.h> |
33__FBSDID("$FreeBSD: head/sys/sparc64/pci/psycho.c 166901 2007-02-23 12:19:07Z piso $"); | 34__FBSDID("$FreeBSD: head/sys/sparc64/pci/psycho.c 167308 2007-03-07 21:13:51Z marius $"); |
34 35/* 36 * Support for `Hummingbird' (UltraSPARC IIe), `Psycho' and `Psycho+' 37 * (UltraSPARC II) and `Sabre' (UltraSPARC IIi) UPA to PCI bridges. 38 */ 39 40#include "opt_ofw_pci.h" 41#include "opt_psycho.h" 42 43#include <sys/param.h> 44#include <sys/systm.h> 45#include <sys/bus.h> 46#include <sys/kdb.h> 47#include <sys/kernel.h> | 35 36/* 37 * Support for `Hummingbird' (UltraSPARC IIe), `Psycho' and `Psycho+' 38 * (UltraSPARC II) and `Sabre' (UltraSPARC IIi) UPA to PCI bridges. 39 */ 40 41#include "opt_ofw_pci.h" 42#include "opt_psycho.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/bus.h> 47#include <sys/kdb.h> 48#include <sys/kernel.h> |
48#include <sys/module.h> | |
49#include <sys/malloc.h> | 49#include <sys/malloc.h> |
50#include <sys/module.h> |
|
50#include <sys/pcpu.h> 51#include <sys/reboot.h> 52 53#include <dev/ofw/ofw_bus.h> 54#include <dev/ofw/ofw_pci.h> 55#include <dev/ofw/openfirm.h> 56 57#include <machine/bus.h> | 51#include <sys/pcpu.h> 52#include <sys/reboot.h> 53 54#include <dev/ofw/ofw_bus.h> 55#include <dev/ofw/ofw_pci.h> 56#include <dev/ofw/openfirm.h> 57 58#include <machine/bus.h> |
58#include <machine/bus_private.h> | |
59#include <machine/bus_common.h> | 59#include <machine/bus_common.h> |
60#include <machine/bus_private.h> |
|
60#include <machine/iommureg.h> | 61#include <machine/iommureg.h> |
61#include <machine/nexusvar.h> | 62#include <machine/iommuvar.h> |
62#include <machine/ofw_bus.h> | 63#include <machine/ofw_bus.h> |
63#include <machine/ofw_upa.h> | |
64#include <machine/resource.h> 65#include <machine/ver.h> 66 67#include <sys/rman.h> 68 | 64#include <machine/resource.h> 65#include <machine/ver.h> 66 67#include <sys/rman.h> 68 |
69#include <machine/iommuvar.h> 70 | |
71#include <dev/pci/pcireg.h> 72#include <dev/pci/pcivar.h> 73 74#include <sparc64/pci/ofw_pci.h> 75#include <sparc64/pci/psychoreg.h> 76#include <sparc64/pci/psychovar.h> 77 78#include "pcib_if.h" 79 80static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *, 81 const char *); | 69#include <dev/pci/pcireg.h> 70#include <dev/pci/pcivar.h> 71 72#include <sparc64/pci/ofw_pci.h> 73#include <sparc64/pci/psychoreg.h> 74#include <sparc64/pci/psychovar.h> 75 76#include "pcib_if.h" 77 78static const struct psycho_desc *psycho_find_desc(const struct psycho_desc *, 79 const char *); |
82static const struct psycho_desc *psycho_get_desc(phandle_t, const char *); | 80static const struct psycho_desc *psycho_get_desc(device_t); |
83static void psycho_set_intr(struct psycho_softc *, int, bus_addr_t, int, 84 driver_filter_t); 85static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *, 86 bus_addr_t *, u_long *); | 81static void psycho_set_intr(struct psycho_softc *, int, bus_addr_t, int, 82 driver_filter_t); 83static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *, 84 bus_addr_t *, u_long *); |
87static int psycho_intr_stub(void *); | 85static driver_filter_t psycho_intr_stub; |
88static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int); 89 90/* Interrupt handlers */ | 86static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int); 87 88/* Interrupt handlers */ |
91static int psycho_ue(void *); 92static int psycho_ce(void *); 93static int psycho_pci_bus(void *); 94static int psycho_powerfail(void *); 95static int psycho_overtemp(void *); | 89static driver_filter_t psycho_ue; 90static driver_filter_t psycho_ce; 91static driver_filter_t psycho_pci_bus; 92static driver_filter_t psycho_powerfail; 93static driver_filter_t psycho_overtemp; |
96#ifdef PSYCHO_MAP_WAKEUP | 94#ifdef PSYCHO_MAP_WAKEUP |
97static int psycho_wakeup(void *); | 95static driver_filter_t psycho_wakeup; |
98#endif 99 100/* IOMMU support */ 101static void psycho_iommu_init(struct psycho_softc *, int, uint32_t); 102 103/* 104 * Methods 105 */ 106static device_probe_t psycho_probe; 107static device_attach_t psycho_attach; 108static bus_read_ivar_t psycho_read_ivar; 109static bus_setup_intr_t psycho_setup_intr; 110static bus_teardown_intr_t psycho_teardown_intr; 111static bus_alloc_resource_t psycho_alloc_resource; 112static bus_activate_resource_t psycho_activate_resource; 113static bus_deactivate_resource_t psycho_deactivate_resource; 114static bus_release_resource_t psycho_release_resource; | 96#endif 97 98/* IOMMU support */ 99static void psycho_iommu_init(struct psycho_softc *, int, uint32_t); 100 101/* 102 * Methods 103 */ 104static device_probe_t psycho_probe; 105static device_attach_t psycho_attach; 106static bus_read_ivar_t psycho_read_ivar; 107static bus_setup_intr_t psycho_setup_intr; 108static bus_teardown_intr_t psycho_teardown_intr; 109static bus_alloc_resource_t psycho_alloc_resource; 110static bus_activate_resource_t psycho_activate_resource; 111static bus_deactivate_resource_t psycho_deactivate_resource; 112static bus_release_resource_t psycho_release_resource; |
113static bus_get_dma_tag_t psycho_get_dma_tag; |
|
115static pcib_maxslots_t psycho_maxslots; 116static pcib_read_config_t psycho_read_config; 117static pcib_write_config_t psycho_write_config; 118static pcib_route_interrupt_t psycho_route_interrupt; 119static ofw_pci_intr_pending_t psycho_intr_pending; 120static ofw_bus_get_node_t psycho_get_node; 121static ofw_pci_adjust_busrange_t psycho_adjust_busrange; 122 --- 9 unchanged lines hidden (view full) --- 132 DEVMETHOD(bus_print_child, bus_generic_print_child), 133 DEVMETHOD(bus_read_ivar, psycho_read_ivar), 134 DEVMETHOD(bus_setup_intr, psycho_setup_intr), 135 DEVMETHOD(bus_teardown_intr, psycho_teardown_intr), 136 DEVMETHOD(bus_alloc_resource, psycho_alloc_resource), 137 DEVMETHOD(bus_activate_resource, psycho_activate_resource), 138 DEVMETHOD(bus_deactivate_resource, psycho_deactivate_resource), 139 DEVMETHOD(bus_release_resource, psycho_release_resource), | 114static pcib_maxslots_t psycho_maxslots; 115static pcib_read_config_t psycho_read_config; 116static pcib_write_config_t psycho_write_config; 117static pcib_route_interrupt_t psycho_route_interrupt; 118static ofw_pci_intr_pending_t psycho_intr_pending; 119static ofw_bus_get_node_t psycho_get_node; 120static ofw_pci_adjust_busrange_t psycho_adjust_busrange; 121 --- 9 unchanged lines hidden (view full) --- 131 DEVMETHOD(bus_print_child, bus_generic_print_child), 132 DEVMETHOD(bus_read_ivar, psycho_read_ivar), 133 DEVMETHOD(bus_setup_intr, psycho_setup_intr), 134 DEVMETHOD(bus_teardown_intr, psycho_teardown_intr), 135 DEVMETHOD(bus_alloc_resource, psycho_alloc_resource), 136 DEVMETHOD(bus_activate_resource, psycho_activate_resource), 137 DEVMETHOD(bus_deactivate_resource, psycho_deactivate_resource), 138 DEVMETHOD(bus_release_resource, psycho_release_resource), |
139 DEVMETHOD(bus_get_dma_tag, psycho_get_dma_tag), |
|
140 141 /* pcib interface */ 142 DEVMETHOD(pcib_maxslots, psycho_maxslots), 143 DEVMETHOD(pcib_read_config, psycho_read_config), 144 DEVMETHOD(pcib_write_config, psycho_write_config), 145 DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt), 146 147 /* ofw_bus interface */ --- 98 unchanged lines hidden (view full) --- 246 { NULL, 0, NULL } 247}; 248 249static const struct psycho_desc * 250psycho_find_desc(const struct psycho_desc *table, const char *string) 251{ 252 const struct psycho_desc *desc; 253 | 140 141 /* pcib interface */ 142 DEVMETHOD(pcib_maxslots, psycho_maxslots), 143 DEVMETHOD(pcib_read_config, psycho_read_config), 144 DEVMETHOD(pcib_write_config, psycho_write_config), 145 DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt), 146 147 /* ofw_bus interface */ --- 98 unchanged lines hidden (view full) --- 246 { NULL, 0, NULL } 247}; 248 249static const struct psycho_desc * 250psycho_find_desc(const struct psycho_desc *table, const char *string) 251{ 252 const struct psycho_desc *desc; 253 |
254 for (desc = table; desc->pd_string != NULL; desc++) { | 254 if (string == NULL) 255 return (NULL); 256 for (desc = table; desc->pd_string != NULL; desc++) |
255 if (strcmp(desc->pd_string, string) == 0) 256 return (desc); | 257 if (strcmp(desc->pd_string, string) == 0) 258 return (desc); |
257 } | |
258 return (NULL); 259} 260 261static const struct psycho_desc * | 259 return (NULL); 260} 261 262static const struct psycho_desc * |
262psycho_get_desc(phandle_t node, const char *model) | 263psycho_get_desc(device_t dev) |
263{ 264 const struct psycho_desc *rv; | 264{ 265 const struct psycho_desc *rv; |
265 char compat[32]; | |
266 | 266 |
267 rv = NULL; 268 if (model != NULL) 269 rv = psycho_find_desc(psycho_models, model); 270 if (rv == NULL && 271 OF_getprop(node, "compatible", compat, sizeof(compat)) != -1) 272 rv = psycho_find_desc(psycho_compats, compat); | 267 rv = psycho_find_desc(psycho_models, ofw_bus_get_model(dev)); 268 if (rv == NULL) 269 rv = psycho_find_desc(psycho_compats, ofw_bus_get_compat(dev)); |
273 return (rv); 274} 275 276static int 277psycho_probe(device_t dev) 278{ 279 const char *dtype; 280 | 270 return (rv); 271} 272 273static int 274psycho_probe(device_t dev) 275{ 276 const char *dtype; 277 |
281 dtype = nexus_get_device_type(dev); 282 if (nexus_get_reg(dev) != NULL && dtype != NULL && 283 strcmp(dtype, OFW_PCI_TYPE) == 0 && 284 psycho_get_desc(nexus_get_node(dev), 285 nexus_get_model(dev)) != NULL) { | 278 dtype = ofw_bus_get_type(dev); 279 if (dtype != NULL && strcmp(dtype, OFW_PCI_TYPE) == 0 && 280 psycho_get_desc(dev) != NULL) { |
286 device_set_desc(dev, "U2P UPA-PCI bridge"); 287 return (0); 288 } 289 290 return (ENXIO); 291} 292 293static int 294psycho_attach(device_t dev) 295{ 296 char name[sizeof("pci108e,1000")]; 297 struct psycho_softc *asc, *sc, *osc; 298 struct ofw_pci_ranges *range; | 281 device_set_desc(dev, "U2P UPA-PCI bridge"); 282 return (0); 283 } 284 285 return (ENXIO); 286} 287 288static int 289psycho_attach(device_t dev) 290{ 291 char name[sizeof("pci108e,1000")]; 292 struct psycho_softc *asc, *sc, *osc; 293 struct ofw_pci_ranges *range; |
299 struct upa_regs *reg; | |
300 const struct psycho_desc *desc; 301 phandle_t child, node; 302 uint64_t csr, dr; 303 uint32_t dvmabase, psycho_br[2]; 304 int32_t rev; | 294 const struct psycho_desc *desc; 295 phandle_t child, node; 296 uint64_t csr, dr; 297 uint32_t dvmabase, psycho_br[2]; 298 int32_t rev; |
305 u_long mlen; | |
306 u_int ver; | 299 u_int ver; |
307 int n, i, nrange, nreg, rid; | 300 int i, n, nrange, rid; |
308#ifdef PSYCHO_DEBUG 309 bus_addr_t map, clr; 310 uint64_t mr; 311#endif 312 | 301#ifdef PSYCHO_DEBUG 302 bus_addr_t map, clr; 303 uint64_t mr; 304#endif 305 |
313 node = nexus_get_node(dev); | 306 node = ofw_bus_get_node(dev); |
314 sc = device_get_softc(dev); | 307 sc = device_get_softc(dev); |
315 desc = psycho_get_desc(node, nexus_get_model(dev)); | 308 desc = psycho_get_desc(dev); |
316 317 sc->sc_node = node; 318 sc->sc_dev = dev; 319 sc->sc_mode = desc->pd_mode; 320 321 /* 322 * The Psycho gets three register banks: 323 * (0) per-PBM configuration and status registers 324 * (1) per-PBM PCI configuration space, containing only the 325 * PBM 256-byte PCI header 326 * (2) the shared Psycho configuration registers 327 */ | 309 310 sc->sc_node = node; 311 sc->sc_dev = dev; 312 sc->sc_mode = desc->pd_mode; 313 314 /* 315 * The Psycho gets three register banks: 316 * (0) per-PBM configuration and status registers 317 * (1) per-PBM PCI configuration space, containing only the 318 * PBM 256-byte PCI header 319 * (2) the shared Psycho configuration registers 320 */ |
328 reg = nexus_get_reg(dev); 329 nreg = nexus_get_nreg(dev); | |
330 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { | 321 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) { |
331 if (nreg <= 2) 332 panic("%s: %d not enough registers", __func__, nreg); 333 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[2]); 334 mlen = UPA_REG_SIZE(®[2]); 335 sc->sc_pcictl = UPA_REG_PHYS(®[0]) - sc->sc_basepaddr; | 322 rid = 2; 323 sc->sc_pcictl = 324 bus_get_resource_start(dev, SYS_RES_MEMORY, 0) - 325 bus_get_resource_start(dev, SYS_RES_MEMORY, 2); |
336 switch (sc->sc_pcictl) { 337 case PSR_PCICTL0: 338 sc->sc_half = 0; 339 break; 340 case PSR_PCICTL1: 341 sc->sc_half = 1; 342 break; 343 default: 344 panic("%s: bogus PCI control register location", 345 __func__); 346 } 347 } else { | 326 switch (sc->sc_pcictl) { 327 case PSR_PCICTL0: 328 sc->sc_half = 0; 329 break; 330 case PSR_PCICTL1: 331 sc->sc_half = 1; 332 break; 333 default: 334 panic("%s: bogus PCI control register location", 335 __func__); 336 } 337 } else { |
348 if (nreg <= 0) 349 panic("%s: %d not enough registers", __func__, nreg); 350 sc->sc_basepaddr = (vm_paddr_t)UPA_REG_PHYS(®[0]); 351 mlen = UPA_REG_SIZE(reg); | 338 rid = 0; |
352 sc->sc_pcictl = PSR_PCICTL0; 353 sc->sc_half = 0; 354 } | 339 sc->sc_pcictl = PSR_PCICTL0; 340 sc->sc_half = 0; 341 } |
342 sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 343 (sc->sc_mode == PSYCHO_MODE_PSYCHO ? RF_SHAREABLE : 0) | 344 RF_ACTIVE); 345 if (sc->sc_mem_res == NULL) 346 panic("%s: could not allocate registers", __func__); 347 sc->sc_bustag = rman_get_bustag(sc->sc_mem_res); 348 sc->sc_bushandle = rman_get_bushandle(sc->sc_mem_res); |
|
355 356 /* 357 * Match other Psycho's that are already configured against 358 * the base physical address. This will be the same for a 359 * pair of devices that share register space. 360 */ 361 osc = NULL; 362 SLIST_FOREACH(asc, &psycho_softcs, sc_link) { | 349 350 /* 351 * Match other Psycho's that are already configured against 352 * the base physical address. This will be the same for a 353 * pair of devices that share register space. 354 */ 355 osc = NULL; 356 SLIST_FOREACH(asc, &psycho_softcs, sc_link) { |
363 if (asc->sc_basepaddr == sc->sc_basepaddr) { | 357 if (rman_get_start(asc->sc_mem_res) == 358 rman_get_start(sc->sc_mem_res)) { |
364 /* Found partner. */ 365 osc = asc; 366 break; 367 } 368 } 369 | 359 /* Found partner. */ 360 osc = asc; 361 break; 362 } 363 } 364 |
370 if (osc == NULL) { 371 rid = 0; 372 sc->sc_mem_res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, 373 sc->sc_basepaddr, sc->sc_basepaddr + mlen - 1, mlen, 374 RF_ACTIVE); 375 if (sc->sc_mem_res == NULL || 376 rman_get_start(sc->sc_mem_res) != sc->sc_basepaddr) 377 panic("%s: could not allocate device memory", __func__); 378 sc->sc_bustag = rman_get_bustag(sc->sc_mem_res); 379 sc->sc_bushandle = rman_get_bushandle(sc->sc_mem_res); 380 } else { 381 /* 382 * There's another Psycho using the same register space. 383 * Copy the relevant stuff. 384 */ 385 sc->sc_mem_res = NULL; 386 sc->sc_bustag = osc->sc_bustag; 387 sc->sc_bushandle = osc->sc_bushandle; 388 } 389 | |
390 /* Clear PCI AFSR. */ 391 PCICTL_WRITE8(sc, PCR_AFS, PCIAFSR_ERRMASK); 392 393 csr = PSYCHO_READ8(sc, PSR_CS); 394 ver = PSYCHO_GCSR_VERS(csr); 395 sc->sc_ign = 0x7c0; /* Hummingbird/Sabre IGN is always 0x1f. */ 396 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 397 sc->sc_ign = PSYCHO_GCSR_IGN(csr) << INTMAP_IGN_SHIFT; --- 185 unchanged lines hidden (view full) --- 583 sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF; 584 iommu_reset(sc->sc_is); 585 } 586 587 /* Allocate our tags. */ 588 sc->sc_pci_memt = psycho_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); 589 sc->sc_pci_iot = psycho_alloc_bus_tag(sc, PCI_IO_BUS_SPACE); 590 sc->sc_pci_cfgt = psycho_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE); | 365 /* Clear PCI AFSR. */ 366 PCICTL_WRITE8(sc, PCR_AFS, PCIAFSR_ERRMASK); 367 368 csr = PSYCHO_READ8(sc, PSR_CS); 369 ver = PSYCHO_GCSR_VERS(csr); 370 sc->sc_ign = 0x7c0; /* Hummingbird/Sabre IGN is always 0x1f. */ 371 if (sc->sc_mode == PSYCHO_MODE_PSYCHO) 372 sc->sc_ign = PSYCHO_GCSR_IGN(csr) << INTMAP_IGN_SHIFT; --- 185 unchanged lines hidden (view full) --- 558 sc->sc_is->is_sb[1] = sc->sc_pcictl + PCR_STRBUF; 559 iommu_reset(sc->sc_is); 560 } 561 562 /* Allocate our tags. */ 563 sc->sc_pci_memt = psycho_alloc_bus_tag(sc, PCI_MEMORY_BUS_SPACE); 564 sc->sc_pci_iot = psycho_alloc_bus_tag(sc, PCI_IO_BUS_SPACE); 565 sc->sc_pci_cfgt = psycho_alloc_bus_tag(sc, PCI_CONFIG_BUS_SPACE); |
591 if (bus_dma_tag_create(nexus_get_dmatag(dev), 8, 1, 0, 0x3ffffffff, 592 NULL, NULL, 0x3ffffffff, 0xff, 0xffffffff, 0, NULL, NULL, | 566 if (bus_dma_tag_create(bus_get_dma_tag(dev), 8, 0, IOMMU_MAXADDR, ~0, 567 NULL, NULL, IOMMU_MAXADDR, 0xff, 0xffffffff, 0, NULL, NULL, |
593 &sc->sc_pci_dmat) != 0) 594 panic("%s: bus_dma_tag_create failed", __func__); 595 /* Customize the tag. */ 596 sc->sc_pci_dmat->dt_cookie = sc->sc_is; 597 sc->sc_pci_dmat->dt_mt = &iommu_dma_methods; | 568 &sc->sc_pci_dmat) != 0) 569 panic("%s: bus_dma_tag_create failed", __func__); 570 /* Customize the tag. */ 571 sc->sc_pci_dmat->dt_cookie = sc->sc_is; 572 sc->sc_pci_dmat->dt_mt = &iommu_dma_methods; |
598 /* XXX: register as root DMA tag (kludge). */ 599 sparc64_root_dma_tag = sc->sc_pci_dmat; | |
600 601#ifdef PSYCHO_DEBUG 602 /* 603 * Enable all interrupts and clear all interrupt states. 604 * This aids the debugging of interrupt routing problems. 605 */ 606 for (map = PSR_PCIA0_INT_MAP, clr = PSR_PCIA0_INT_CLR, n = 0; | 573 574#ifdef PSYCHO_DEBUG 575 /* 576 * Enable all interrupts and clear all interrupt states. 577 * This aids the debugging of interrupt routing problems. 578 */ 579 for (map = PSR_PCIA0_INT_MAP, clr = PSR_PCIA0_INT_CLR, n = 0; |
607 map <= PSR_PCIB3_INT_MAP; map += 8, clr += 32, n++) { | 580 map <= PSR_PCIB3_INT_MAP; map += 8, clr += 32, n++) { |
608 mr = PSYCHO_READ8(sc, map); 609 device_printf(dev, "intr map (pci) %d: %#lx\n", n, (u_long)mr); 610 PSYCHO_WRITE8(sc, map, mr & ~INTMAP_V); 611 for (i = 0; i < 4; i++) 612 PCICTL_WRITE8(sc, clr + i * 8, 0); 613 PSYCHO_WRITE8(sc, map, INTMAP_ENABLE(mr, PCPU_GET(mid))); 614 } 615 for (map = PSR_SCSI_INT_MAP, clr = PSR_SCSI_INT_CLR, n = 0; | 581 mr = PSYCHO_READ8(sc, map); 582 device_printf(dev, "intr map (pci) %d: %#lx\n", n, (u_long)mr); 583 PSYCHO_WRITE8(sc, map, mr & ~INTMAP_V); 584 for (i = 0; i < 4; i++) 585 PCICTL_WRITE8(sc, clr + i * 8, 0); 586 PSYCHO_WRITE8(sc, map, INTMAP_ENABLE(mr, PCPU_GET(mid))); 587 } 588 for (map = PSR_SCSI_INT_MAP, clr = PSR_SCSI_INT_CLR, n = 0; |
616 map <= PSR_SERIAL_INT_MAP; map += 8, clr += 8, n++) { | 589 map <= PSR_SERIAL_INT_MAP; map += 8, clr += 8, n++) { |
617 mr = PSYCHO_READ8(sc, map); 618 device_printf(dev, "intr map (obio) %d: %#lx, clr: %#lx\n", n, 619 (u_long)mr, (u_long)clr); 620 PSYCHO_WRITE8(sc, map, mr & ~INTMAP_V); 621 PSYCHO_WRITE8(sc, clr, 0); 622 PSYCHO_WRITE8(sc, map, INTMAP_ENABLE(mr, PCPU_GET(mid))); 623 } 624#endif /* PSYCHO_DEBUG */ --- 53 unchanged lines hidden (view full) --- 678 device_add_child(dev, "pci", sc->sc_pci_secbus); 679 return (bus_generic_attach(dev)); 680} 681 682static void 683psycho_set_intr(struct psycho_softc *sc, int index, bus_addr_t map, int iflags, 684 driver_filter_t handler) 685{ | 590 mr = PSYCHO_READ8(sc, map); 591 device_printf(dev, "intr map (obio) %d: %#lx, clr: %#lx\n", n, 592 (u_long)mr, (u_long)clr); 593 PSYCHO_WRITE8(sc, map, mr & ~INTMAP_V); 594 PSYCHO_WRITE8(sc, clr, 0); 595 PSYCHO_WRITE8(sc, map, INTMAP_ENABLE(mr, PCPU_GET(mid))); 596 } 597#endif /* PSYCHO_DEBUG */ --- 53 unchanged lines hidden (view full) --- 651 device_add_child(dev, "pci", sc->sc_pci_secbus); 652 return (bus_generic_attach(dev)); 653} 654 655static void 656psycho_set_intr(struct psycho_softc *sc, int index, bus_addr_t map, int iflags, 657 driver_filter_t handler) 658{ |
686 int rid, vec, res; | |
687 uint64_t mr; | 659 uint64_t mr; |
660 int res, rid; |
|
688 689 res = EINVAL; 690 rid = index; 691 mr = PSYCHO_READ8(sc, map); | 661 662 res = EINVAL; 663 rid = index; 664 mr = PSYCHO_READ8(sc, map); |
692 vec = INTVEC(mr); 693 sc->sc_irq_res[index] = bus_alloc_resource(sc->sc_dev, SYS_RES_IRQ, 694 &rid, vec, vec, 1, RF_ACTIVE); 695 if (sc->sc_irq_res[index] != NULL) { | 665 sc->sc_irq_res[index] = bus_alloc_resource_any(sc->sc_dev, SYS_RES_IRQ, 666 &rid, RF_ACTIVE); 667 if (sc->sc_irq_res[index] != NULL && 668 rman_get_start(sc->sc_irq_res[index]) == INTVEC(mr)) { |
696 if (iflags & FAST) { 697 iflags &= ~FAST; 698 res = bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 699 INTR_TYPE_MISC | iflags, handler, NULL, sc, 700 &sc->sc_ihand[index]); 701 } else 702 res = bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 703 INTR_TYPE_MISC | iflags, NULL, --- 13 unchanged lines hidden (view full) --- 717 uint64_t im; 718 u_long diag; 719 int found; 720 721 found = 0; 722 /* Hunt thru OBIO first. */ 723 diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG); 724 for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR; | 669 if (iflags & FAST) { 670 iflags &= ~FAST; 671 res = bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 672 INTR_TYPE_MISC | iflags, handler, NULL, sc, 673 &sc->sc_ihand[index]); 674 } else 675 res = bus_setup_intr(sc->sc_dev, sc->sc_irq_res[index], 676 INTR_TYPE_MISC | iflags, NULL, --- 13 unchanged lines hidden (view full) --- 690 uint64_t im; 691 u_long diag; 692 int found; 693 694 found = 0; 695 /* Hunt thru OBIO first. */ 696 diag = PSYCHO_READ8(sc, PSR_OBIO_INT_DIAG); 697 for (intrmap = PSR_SCSI_INT_MAP, intrclr = PSR_SCSI_INT_CLR; |
725 intrmap <= PSR_SERIAL_INT_MAP; intrmap += 8, intrclr += 8, 726 diag >>= 2) { | 698 intrmap <= PSR_SERIAL_INT_MAP; intrmap += 8, intrclr += 8, 699 diag >>= 2) { |
727 im = PSYCHO_READ8(sc, intrmap); 728 if (INTINO(im) == ino) { 729 diag &= 2; 730 found = 1; 731 break; 732 } 733 } 734 735 if (!found) { 736 diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG); 737 /* Now do PCI interrupts. */ 738 for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR; | 700 im = PSYCHO_READ8(sc, intrmap); 701 if (INTINO(im) == ino) { 702 diag &= 2; 703 found = 1; 704 break; 705 } 706 } 707 708 if (!found) { 709 diag = PSYCHO_READ8(sc, PSR_PCI_INT_DIAG); 710 /* Now do PCI interrupts. */ 711 for (intrmap = PSR_PCIA0_INT_MAP, intrclr = PSR_PCIA0_INT_CLR; |
739 intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32, 740 diag >>= 8) { | 712 intrmap <= PSR_PCIB3_INT_MAP; intrmap += 8, intrclr += 32, 713 diag >>= 8) { |
741 if (sc->sc_mode == PSYCHO_MODE_PSYCHO && 742 (intrmap == PSR_PCIA2_INT_MAP || | 714 if (sc->sc_mode == PSYCHO_MODE_PSYCHO && 715 (intrmap == PSR_PCIA2_INT_MAP || |
743 intrmap == PSR_PCIA3_INT_MAP)) | 716 intrmap == PSR_PCIA3_INT_MAP)) |
744 continue; 745 im = PSYCHO_READ8(sc, intrmap); 746 if (((im ^ ino) & 0x3c) == 0) { 747 intrclr += 8 * (ino & 3); 748 diag = (diag >> ((ino & 3) * 2)) & 2; 749 found = 1; 750 break; 751 } --- 173 unchanged lines hidden (view full) --- 925#endif 926 r = -1; 927 } 928 return (r); 929} 930 931static void 932psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, | 717 continue; 718 im = PSYCHO_READ8(sc, intrmap); 719 if (((im ^ ino) & 0x3c) == 0) { 720 intrclr += 8 * (ino & 3); 721 diag = (diag >> ((ino & 3) * 2)) & 2; 722 found = 1; 723 break; 724 } --- 173 unchanged lines hidden (view full) --- 898#endif 899 r = -1; 900 } 901 return (r); 902} 903 904static void 905psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, |
933 uint32_t val, int width) | 906 uint32_t val, int width) |
934{ 935 struct psycho_softc *sc; 936 bus_space_handle_t bh; 937 u_long offset = 0; 938 939 sc = device_get_softc(dev); 940 offset = PSYCHO_CONF_OFF(bus, slot, func, reg); 941 bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; --- 78 unchanged lines hidden (view full) --- 1020 } 1021 pc->pci_handler(pc->pci_arg); 1022 PSYCHO_WRITE8(pc->pci_sc, pc->pci_clr, 0); 1023 return (FILTER_HANDLED); 1024} 1025 1026static int 1027psycho_setup_intr(device_t dev, device_t child, struct resource *ires, | 907{ 908 struct psycho_softc *sc; 909 bus_space_handle_t bh; 910 u_long offset = 0; 911 912 sc = device_get_softc(dev); 913 offset = PSYCHO_CONF_OFF(bus, slot, func, reg); 914 bh = sc->sc_pci_bh[OFW_PCI_CS_CONFIG]; --- 78 unchanged lines hidden (view full) --- 993 } 994 pc->pci_handler(pc->pci_arg); 995 PSYCHO_WRITE8(pc->pci_sc, pc->pci_clr, 0); 996 return (FILTER_HANDLED); 997} 998 999static int 1000psycho_setup_intr(device_t dev, device_t child, struct resource *ires, |
1028 int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, | 1001 int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, |
1029 void **cookiep) 1030{ 1031 struct { 1032 int apb:1; 1033 int ppb:1; 1034 } found; 1035 devclass_t pci_devclass; 1036 device_t cdev, pdev, pcidev; --- 115 unchanged lines hidden (view full) --- 1152 * handler installed. 1153 */ 1154 PSYCHO_WRITE8(sc, intrmapptr, INTMAP_ENABLE(mr, PCPU_GET(mid))); 1155 return (error); 1156} 1157 1158static int 1159psycho_teardown_intr(device_t dev, device_t child, struct resource *vec, | 1002 void **cookiep) 1003{ 1004 struct { 1005 int apb:1; 1006 int ppb:1; 1007 } found; 1008 devclass_t pci_devclass; 1009 device_t cdev, pdev, pcidev; --- 115 unchanged lines hidden (view full) --- 1125 * handler installed. 1126 */ 1127 PSYCHO_WRITE8(sc, intrmapptr, INTMAP_ENABLE(mr, PCPU_GET(mid))); 1128 return (error); 1129} 1130 1131static int 1132psycho_teardown_intr(device_t dev, device_t child, struct resource *vec, |
1160 void *cookie) | 1133 void *cookie) |
1161{ 1162 struct psycho_clr *pc = cookie; 1163 int error; 1164 1165 error = BUS_TEARDOWN_INTR(device_get_parent(dev), child, vec, 1166 pc->pci_cookie); 1167 /* 1168 * Don't disable the interrupt for now, so that stray interupts get --- 116 unchanged lines hidden (view full) --- 1285 if (rman_get_flags(r) & RF_ACTIVE) { 1286 error = bus_deactivate_resource(child, type, rid, r); 1287 if (error) 1288 return error; 1289 } 1290 return (rman_release_resource(r)); 1291} 1292 | 1134{ 1135 struct psycho_clr *pc = cookie; 1136 int error; 1137 1138 error = BUS_TEARDOWN_INTR(device_get_parent(dev), child, vec, 1139 pc->pci_cookie); 1140 /* 1141 * Don't disable the interrupt for now, so that stray interupts get --- 116 unchanged lines hidden (view full) --- 1258 if (rman_get_flags(r) & RF_ACTIVE) { 1259 error = bus_deactivate_resource(child, type, rid, r); 1260 if (error) 1261 return error; 1262 } 1263 return (rman_release_resource(r)); 1264} 1265 |
1266static bus_dma_tag_t 1267psycho_get_dma_tag(device_t bus, device_t child) 1268{ 1269 struct psycho_softc *sc; 1270 1271 sc = device_get_softc(bus); 1272 return (sc->sc_pci_dmat); 1273} 1274 |
|
1293static int 1294psycho_intr_pending(device_t dev, ofw_pci_intr_t intr) 1295{ 1296 struct psycho_softc *sc; 1297 u_long diag; 1298 1299 sc = device_get_softc(dev); 1300 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) { --- 50 unchanged lines hidden --- | 1275static int 1276psycho_intr_pending(device_t dev, ofw_pci_intr_t intr) 1277{ 1278 struct psycho_softc *sc; 1279 u_long diag; 1280 1281 sc = device_get_softc(dev); 1282 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) { --- 50 unchanged lines hidden --- |