Deleted Added
full compact
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(&reg[2]);
334 mlen = UPA_REG_SIZE(&reg[2]);
335 sc->sc_pcictl = UPA_REG_PHYS(&reg[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(&reg[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 ---