Deleted Added
full compact
psycho.c (116659) psycho.c (117119)
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org>
3 * All rights reserved.
4 * All rights reserved.
4 * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. 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
12 * notice, this list of conditions and the following disclaimer in the

--- 10 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
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 *
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
12 * notice, this list of conditions and the following disclaimer in the

--- 10 unchanged lines hidden (view full) ---

23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
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 * $FreeBSD: head/sys/sparc64/pci/psycho.c 116659 2003-06-22 01:26:08Z jmg $
31 * $FreeBSD: head/sys/sparc64/pci/psycho.c 117119 2003-07-01 14:52:47Z tmm $
32 */
33
34/*
35 * Support for `psycho' and `psycho+' UPA to PCI bridge and
36 * UltraSPARC IIi and IIe `sabre' PCI controllers.
37 */
38
32 */
33
34/*
35 * Support for `psycho' and `psycho+' UPA to PCI bridge and
36 * UltraSPARC IIi and IIe `sabre' PCI controllers.
37 */
38
39#include "opt_ofw_pci.h"
39#include "opt_psycho.h"
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/bus.h>
44#include <sys/kernel.h>
45#include <sys/malloc.h>
46#include <sys/pcpu.h>
47
48#include <ofw/openfirm.h>
49#include <ofw/ofw_pci.h>
50
51#include <machine/bus.h>
52#include <machine/bus_private.h>
53#include <machine/iommureg.h>
54#include <machine/bus_common.h>
55#include <machine/frame.h>
56#include <machine/intr_machdep.h>
57#include <machine/nexusvar.h>
40#include "opt_psycho.h"
41
42#include <sys/param.h>
43#include <sys/systm.h>
44#include <sys/bus.h>
45#include <sys/kernel.h>
46#include <sys/malloc.h>
47#include <sys/pcpu.h>
48
49#include <ofw/openfirm.h>
50#include <ofw/ofw_pci.h>
51
52#include <machine/bus.h>
53#include <machine/bus_private.h>
54#include <machine/iommureg.h>
55#include <machine/bus_common.h>
56#include <machine/frame.h>
57#include <machine/intr_machdep.h>
58#include <machine/nexusvar.h>
59#include <machine/ofw_bus.h>
58#include <machine/ofw_upa.h>
59#include <machine/resource.h>
60#include <machine/cpu.h>
61
62#include <sys/rman.h>
63
64#include <machine/iommuvar.h>
65
66#include <pci/pcivar.h>
67#include <pci/pcireg.h>
68
69#include <sparc64/pci/ofw_pci.h>
70#include <sparc64/pci/psychoreg.h>
71#include <sparc64/pci/psychovar.h>
72
73#include "pcib_if.h"
60#include <machine/ofw_upa.h>
61#include <machine/resource.h>
62#include <machine/cpu.h>
63
64#include <sys/rman.h>
65
66#include <machine/iommuvar.h>
67
68#include <pci/pcivar.h>
69#include <pci/pcireg.h>
70
71#include <sparc64/pci/ofw_pci.h>
72#include <sparc64/pci/psychoreg.h>
73#include <sparc64/pci/psychovar.h>
74
75#include "pcib_if.h"
74#include "sparcbus_if.h"
75
76static void psycho_get_ranges(phandle_t, struct upa_ranges **, int *);
77static void psycho_set_intr(struct psycho_softc *, int, device_t, bus_addr_t,
78 int, driver_intr_t);
79static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *,
80 bus_addr_t *, u_long *);
81static void psycho_intr_stub(void *);
82static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int);
76
77static void psycho_get_ranges(phandle_t, struct upa_ranges **, int *);
78static void psycho_set_intr(struct psycho_softc *, int, device_t, bus_addr_t,
79 int, driver_intr_t);
80static int psycho_find_intrmap(struct psycho_softc *, int, bus_addr_t *,
81 bus_addr_t *, u_long *);
82static void psycho_intr_stub(void *);
83static bus_space_tag_t psycho_alloc_bus_tag(struct psycho_softc *, int);
84#ifndef OFW_NEWPCI
85static ofw_pci_binit_t psycho_binit;
86#endif
83
87
84
85/* Interrupt handlers */
86static void psycho_ue(void *);
87static void psycho_ce(void *);
88static void psycho_bus_a(void *);
89static void psycho_bus_b(void *);
90static void psycho_powerfail(void *);
91#ifdef PSYCHO_MAP_WAKEUP
92static void psycho_wakeup(void *);
93#endif
94
95/* IOMMU support */
96static void psycho_iommu_init(struct psycho_softc *, int);
88/* Interrupt handlers */
89static void psycho_ue(void *);
90static void psycho_ce(void *);
91static void psycho_bus_a(void *);
92static void psycho_bus_b(void *);
93static void psycho_powerfail(void *);
94#ifdef PSYCHO_MAP_WAKEUP
95static void psycho_wakeup(void *);
96#endif
97
98/* IOMMU support */
99static void psycho_iommu_init(struct psycho_softc *, int);
97static ofw_pci_binit_t psycho_binit;
98
99/*
100
101/*
100 * autoconfiguration
102 * Methods.
101 */
103 */
102static int psycho_probe(device_t);
103static int psycho_attach(device_t);
104static int psycho_read_ivar(device_t, device_t, int, u_long *);
105static int psycho_setup_intr(device_t, device_t, struct resource *, int,
106 driver_intr_t *, void *, void **);
107static int psycho_teardown_intr(device_t, device_t, struct resource *, void *);
108static struct resource *psycho_alloc_resource(device_t, device_t, int, int *,
109 u_long, u_long, u_long, u_int);
110static int psycho_activate_resource(device_t, device_t, int, int,
111 struct resource *);
112static int psycho_deactivate_resource(device_t, device_t, int, int,
113 struct resource *);
114static int psycho_release_resource(device_t, device_t, int, int,
115 struct resource *);
116static int psycho_maxslots(device_t);
117static u_int32_t psycho_read_config(device_t, u_int, u_int, u_int, u_int, int);
118static void psycho_write_config(device_t, u_int, u_int, u_int, u_int, u_int32_t,
119 int);
120static int psycho_route_interrupt(device_t, device_t, int);
121static int psycho_intr_pending(device_t, int);
122static u_int32_t psycho_guess_ino(device_t, phandle_t, u_int, u_int);
123static bus_space_handle_t psycho_get_bus_handle(device_t dev, enum sbbt_id id,
124 bus_space_handle_t childhdl, bus_space_tag_t *tag);
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 pcib_maxslots_t psycho_maxslots;
114static pcib_read_config_t psycho_read_config;
115static pcib_write_config_t psycho_write_config;
116static pcib_route_interrupt_t psycho_route_interrupt;
117static ofw_pci_intr_pending_t psycho_intr_pending;
118#ifndef OFW_NEWPCI
119static ofw_pci_guess_ino_t psycho_guess_ino;
120#endif
121static ofw_pci_get_bus_handle_t psycho_get_bus_handle;
122#ifdef OFW_NEWPCI
123static ofw_pci_get_node_t psycho_get_node;
124static ofw_pci_adjust_busrange_t psycho_adjust_busrange;
125#endif
125
126static device_method_t psycho_methods[] = {
127 /* Device interface */
128 DEVMETHOD(device_probe, psycho_probe),
129 DEVMETHOD(device_attach, psycho_attach),
130
131 /* Bus interface */
132 DEVMETHOD(bus_print_child, bus_generic_print_child),

--- 6 unchanged lines hidden (view full) ---

139 DEVMETHOD(bus_release_resource, psycho_release_resource),
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
126
127static device_method_t psycho_methods[] = {
128 /* Device interface */
129 DEVMETHOD(device_probe, psycho_probe),
130 DEVMETHOD(device_attach, psycho_attach),
131
132 /* Bus interface */
133 DEVMETHOD(bus_print_child, bus_generic_print_child),

--- 6 unchanged lines hidden (view full) ---

140 DEVMETHOD(bus_release_resource, psycho_release_resource),
141
142 /* pcib interface */
143 DEVMETHOD(pcib_maxslots, psycho_maxslots),
144 DEVMETHOD(pcib_read_config, psycho_read_config),
145 DEVMETHOD(pcib_write_config, psycho_write_config),
146 DEVMETHOD(pcib_route_interrupt, psycho_route_interrupt),
147
147 /* sparcbus interface */
148 DEVMETHOD(sparcbus_intr_pending, psycho_intr_pending),
149 DEVMETHOD(sparcbus_guess_ino, psycho_guess_ino),
150 DEVMETHOD(sparcbus_get_bus_handle, psycho_get_bus_handle),
148 /* ofw_pci interface */
149 DEVMETHOD(ofw_pci_intr_pending, psycho_intr_pending),
150#ifndef OFW_NEWPCI
151 DEVMETHOD(ofw_pci_guess_ino, psycho_guess_ino),
152#endif
153 DEVMETHOD(ofw_pci_get_bus_handle, psycho_get_bus_handle),
154#ifdef OFW_NEWPCI
155 DEVMETHOD(ofw_pci_get_node, psycho_get_node),
156 DEVMETHOD(ofw_pci_adjust_busrange, psycho_adjust_busrange),
157#endif
151
152 { 0, 0 }
153};
154
155static driver_t psycho_driver = {
156 "pcib",
157 psycho_methods,
158 sizeof(struct psycho_softc),

--- 150 unchanged lines hidden (view full) ---

309 */
310static int
311psycho_attach(device_t dev)
312{
313 struct psycho_softc *sc;
314 struct psycho_softc *osc = NULL;
315 struct psycho_softc *asc;
316 struct upa_regs *reg;
158
159 { 0, 0 }
160};
161
162static driver_t psycho_driver = {
163 "pcib",
164 psycho_methods,
165 sizeof(struct psycho_softc),

--- 150 unchanged lines hidden (view full) ---

316 */
317static int
318psycho_attach(device_t dev)
319{
320 struct psycho_softc *sc;
321 struct psycho_softc *osc = NULL;
322 struct psycho_softc *asc;
323 struct upa_regs *reg;
324#ifndef OFW_NEWPCI
317 struct ofw_pci_bdesc obd;
325 struct ofw_pci_bdesc obd;
326#endif
318 struct psycho_desc *desc;
319 phandle_t node;
320 u_int64_t csr;
321 u_long mlen;
322 int psycho_br[2];
323 int n, i, nreg, rid;
324#ifdef PSYCHO_DEBUG
325 bus_addr_t map, clr;

--- 256 unchanged lines hidden (view full) ---

582 * the inital bus number, and cannot be trusted on all machines.
583 */
584 n = OF_getprop(node, "bus-range", (void *)psycho_br, sizeof(psycho_br));
585 if (n == -1)
586 panic("could not get psycho bus-range");
587 if (n != sizeof(psycho_br))
588 panic("broken psycho bus-range (%d)", n);
589
327 struct psycho_desc *desc;
328 phandle_t node;
329 u_int64_t csr;
330 u_long mlen;
331 int psycho_br[2];
332 int n, i, nreg, rid;
333#ifdef PSYCHO_DEBUG
334 bus_addr_t map, clr;

--- 256 unchanged lines hidden (view full) ---

591 * the inital bus number, and cannot be trusted on all machines.
592 */
593 n = OF_getprop(node, "bus-range", (void *)psycho_br, sizeof(psycho_br));
594 if (n == -1)
595 panic("could not get psycho bus-range");
596 if (n != sizeof(psycho_br))
597 panic("broken psycho bus-range (%d)", n);
598
590 sc->sc_busno = ofw_pci_alloc_busno(sc->sc_node);
591 obd.obd_bus = psycho_br[0];
592 obd.obd_secbus = obd.obd_subbus = sc->sc_busno;
599 sc->sc_secbus = sc->sc_subbus = ofw_pci_alloc_busno(sc->sc_node);
600 /*
601 * Program the bus range registers.
602 * NOTE: the psycho, the second write changes the bus number the
603 * psycho itself uses for it's configuration space, so these
604 * writes must be kept in this order!
605 * The sabre always uses bus 0, but there only can be one sabre per
606 * machine.
607 */
608 PCIB_WRITE_CONFIG(dev, psycho_br[0], PCS_DEVICE, PCS_FUNC, PCSR_SUBBUS,
609 sc->sc_subbus, 1);
610 PCIB_WRITE_CONFIG(dev, psycho_br[0], PCS_DEVICE, PCS_FUNC, PCSR_SECBUS,
611 sc->sc_secbus, 1);
612
613#ifdef OFW_NEWPCI
614 ofw_bus_setup_iinfo(node, &sc->sc_iinfo, sizeof(ofw_pci_intr_t));
615#else
616 obd.obd_bus = obd.obd_secbus = sc->sc_secbus;
617 obd.obd_subbus = sc->sc_subbus;
593 obd.obd_slot = PCS_DEVICE;
594 obd.obd_func = PCS_FUNC;
595 obd.obd_init = psycho_binit;
596 obd.obd_super = NULL;
618 obd.obd_slot = PCS_DEVICE;
619 obd.obd_func = PCS_FUNC;
620 obd.obd_init = psycho_binit;
621 obd.obd_super = NULL;
597 /* Initial setup. */
598 psycho_binit(dev, &obd);
599 /* Update the bus number to what was just programmed. */
600 obd.obd_bus = obd.obd_secbus;
622
601 /*
602 * Initialize the interrupt registers of all devices hanging from
603 * the host bridge directly or indirectly via PCI-PCI bridges.
604 * The MI code (and the PCI spec) assume that this is done during
605 * system initialization, however the firmware does not do this
606 * at least on some models, and we probably shouldn't trust that
607 * the firmware uses the same model as this driver if it does.
608 * Additionally, set up the bus numbers and ranges.
609 */
610 ofw_pci_init(dev, sc->sc_node, sc->sc_ign, &obd);
623 /*
624 * Initialize the interrupt registers of all devices hanging from
625 * the host bridge directly or indirectly via PCI-PCI bridges.
626 * The MI code (and the PCI spec) assume that this is done during
627 * system initialization, however the firmware does not do this
628 * at least on some models, and we probably shouldn't trust that
629 * the firmware uses the same model as this driver if it does.
630 * Additionally, set up the bus numbers and ranges.
631 */
632 ofw_pci_init(dev, sc->sc_node, sc->sc_ign, &obd);
633#endif /* OFW_NEWPCI */
611
634
612 device_add_child(dev, "pci", device_get_unit(dev));
635 device_add_child(dev, "pci", sc->sc_secbus);
613 return (bus_generic_attach(dev));
614}
615
616static void
617psycho_set_intr(struct psycho_softc *sc, int index,
618 device_t dev, bus_addr_t map, int iflags, driver_intr_t handler)
619{
620 int rid, vec;

--- 100 unchanged lines hidden (view full) ---

721{
722 struct psycho_softc *sc = (struct psycho_softc *)arg;
723 u_int64_t afar, afsr;
724
725 PSYCHO_WRITE8(sc, PSR_CE_INT_CLR, 0);
726 afar = PSYCHO_READ8(sc, PSR_CE_AFA);
727 afsr = PSYCHO_READ8(sc, PSR_CE_AFS);
728 /* It's correctable. Dump the regs and continue. */
636 return (bus_generic_attach(dev));
637}
638
639static void
640psycho_set_intr(struct psycho_softc *sc, int index,
641 device_t dev, bus_addr_t map, int iflags, driver_intr_t handler)
642{
643 int rid, vec;

--- 100 unchanged lines hidden (view full) ---

744{
745 struct psycho_softc *sc = (struct psycho_softc *)arg;
746 u_int64_t afar, afsr;
747
748 PSYCHO_WRITE8(sc, PSR_CE_INT_CLR, 0);
749 afar = PSYCHO_READ8(sc, PSR_CE_AFA);
750 afsr = PSYCHO_READ8(sc, PSR_CE_AFS);
751 /* It's correctable. Dump the regs and continue. */
729 printf("%s: correctable DMA error AFAR %#lx AFSR %#lx\n",
730 device_get_name(sc->sc_dev), (u_long)afar, (u_long)afsr);
752 device_printf(sc->sc_dev, "correctable DMA error AFAR %#lx "
753 "AFSR %#lx\n", (u_long)afar, (u_long)afsr);
731}
732
733static void
734psycho_bus_a(void *arg)
735{
736 struct psycho_softc *sc = (struct psycho_softc *)arg;
737 u_int64_t afar, afsr;
738

--- 36 unchanged lines hidden (view full) ---

775#ifdef PSYCHO_MAP_WAKEUP
776static void
777psycho_wakeup(void *arg)
778{
779 struct psycho_softc *sc = (struct psycho_softc *)arg;
780
781 PSYCHO_WRITE8(sc, PSR_PWRMGT_INT_CLR, 0);
782 /* Gee, we don't really have a framework to deal with this properly. */
754}
755
756static void
757psycho_bus_a(void *arg)
758{
759 struct psycho_softc *sc = (struct psycho_softc *)arg;
760 u_int64_t afar, afsr;
761

--- 36 unchanged lines hidden (view full) ---

798#ifdef PSYCHO_MAP_WAKEUP
799static void
800psycho_wakeup(void *arg)
801{
802 struct psycho_softc *sc = (struct psycho_softc *)arg;
803
804 PSYCHO_WRITE8(sc, PSR_PWRMGT_INT_CLR, 0);
805 /* Gee, we don't really have a framework to deal with this properly. */
783 printf("%s: power management wakeup\n", device_get_name(sc->sc_dev));
806 device_printf(sc->sc_dev, "power management wakeup\n");
784}
785#endif /* PSYCHO_MAP_WAKEUP */
786
787/* initialise the IOMMU... */
788void
789psycho_iommu_init(struct psycho_softc *sc, int tsbsize)
790{
791 char *name;

--- 13 unchanged lines hidden (view full) ---

805 name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
806 if (name == 0)
807 panic("couldn't malloc iommu name");
808 snprintf(name, 32, "%s dvma", device_get_name(sc->sc_dev));
809
810 iommu_init(name, is, tsbsize, sc->sc_dvmabase, 0);
811}
812
807}
808#endif /* PSYCHO_MAP_WAKEUP */
809
810/* initialise the IOMMU... */
811void
812psycho_iommu_init(struct psycho_softc *sc, int tsbsize)
813{
814 char *name;

--- 13 unchanged lines hidden (view full) ---

828 name = (char *)malloc(32, M_DEVBUF, M_NOWAIT);
829 if (name == 0)
830 panic("couldn't malloc iommu name");
831 snprintf(name, 32, "%s dvma", device_get_name(sc->sc_dev));
832
833 iommu_init(name, is, tsbsize, sc->sc_dvmabase, 0);
834}
835
836#ifndef OFW_NEWPCI
813static void
814psycho_binit(device_t busdev, struct ofw_pci_bdesc *obd)
815{
816
817#ifdef PSYCHO_DEBUG
818 printf("psycho at %u/%u/%u: setting bus #s to %u/%u/%u\n",
819 obd->obd_bus, obd->obd_slot, obd->obd_func, obd->obd_bus,
820 obd->obd_secbus, obd->obd_subbus);
821#endif /* PSYCHO_DEBUG */
837static void
838psycho_binit(device_t busdev, struct ofw_pci_bdesc *obd)
839{
840
841#ifdef PSYCHO_DEBUG
842 printf("psycho at %u/%u/%u: setting bus #s to %u/%u/%u\n",
843 obd->obd_bus, obd->obd_slot, obd->obd_func, obd->obd_bus,
844 obd->obd_secbus, obd->obd_subbus);
845#endif /* PSYCHO_DEBUG */
822 /*
823 * NOTE: this must be kept in this order, since the last write will
824 * change the config space address of the psycho.
825 */
826 PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
827 PCSR_SUBBUS, obd->obd_subbus, 1);
846 PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
847 PCSR_SUBBUS, obd->obd_subbus, 1);
828 PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
829 PCSR_SECBUS, obd->obd_secbus, 1);
830}
848}
849#endif
831
832static int
833psycho_maxslots(device_t dev)
834{
835
850
851static int
852psycho_maxslots(device_t dev)
853{
854
836 /*
837 * XXX: is this correct? At any rate, a number that is too high
838 * shouldn't do any harm, if only because of the way things are
839 * handled in psycho_read_config.
840 */
841 return (31);
855 /* XXX: is this correct? */
856 return (PCI_SLOTMAX);
842}
843
857}
858
859#ifndef OFW_NEWPCI
844/*
845 * Keep a table of quirky PCI devices that need fixups before the MI PCI code
846 * creates the resource lists. This needs to be moved around once other bus
847 * drivers are added. Moving it to the MI code should maybe be reconsidered
848 * if one of these devices appear in non-sparc64 boxen. It's likely that not
849 * all BIOSes/firmwares can deal with them.
850 */
851struct psycho_dquirk {

--- 5 unchanged lines hidden (view full) ---

857#define DQT_BAD_INTPIN 1 /* Intpin reg 0, but intpin used */
858
859static struct psycho_dquirk dquirks[] = {
860 { 0x1001108e, DQT_BAD_INTPIN }, /* Sun HME (PCIO func. 1) */
861 { 0x1101108e, DQT_BAD_INTPIN }, /* Sun GEM (PCIO2 func. 1) */
862 { 0x1102108e, DQT_BAD_INTPIN }, /* Sun FireWire ctl. (PCIO2 func. 2) */
863 { 0x1103108e, DQT_BAD_INTPIN }, /* Sun USB ctl. (PCIO2 func. 3) */
864};
860/*
861 * Keep a table of quirky PCI devices that need fixups before the MI PCI code
862 * creates the resource lists. This needs to be moved around once other bus
863 * drivers are added. Moving it to the MI code should maybe be reconsidered
864 * if one of these devices appear in non-sparc64 boxen. It's likely that not
865 * all BIOSes/firmwares can deal with them.
866 */
867struct psycho_dquirk {

--- 5 unchanged lines hidden (view full) ---

873#define DQT_BAD_INTPIN 1 /* Intpin reg 0, but intpin used */
874
875static struct psycho_dquirk dquirks[] = {
876 { 0x1001108e, DQT_BAD_INTPIN }, /* Sun HME (PCIO func. 1) */
877 { 0x1101108e, DQT_BAD_INTPIN }, /* Sun GEM (PCIO2 func. 1) */
878 { 0x1102108e, DQT_BAD_INTPIN }, /* Sun FireWire ctl. (PCIO2 func. 2) */
879 { 0x1103108e, DQT_BAD_INTPIN }, /* Sun USB ctl. (PCIO2 func. 3) */
880};
881#endif /* !OFW_NEWPCI */
865
866#define NDQUIRKS (sizeof(dquirks) / sizeof(dquirks[0]))
867
868static u_int32_t
869psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
870 int width)
871{
872 struct psycho_softc *sc;
873 bus_space_handle_t bh;
874 u_long offset = 0;
882
883#define NDQUIRKS (sizeof(dquirks) / sizeof(dquirks[0]))
884
885static u_int32_t
886psycho_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg,
887 int width)
888{
889 struct psycho_softc *sc;
890 bus_space_handle_t bh;
891 u_long offset = 0;
875 u_int32_t r, devid;
892#ifndef OFW_NEWPCI
893 u_int32_t devid;
894#endif
876 u_int8_t byte;
877 u_int16_t shrt;
878 u_int32_t wrd;
895 u_int8_t byte;
896 u_int16_t shrt;
897 u_int32_t wrd;
898 u_int32_t r;
879 int i;
880
881 sc = (struct psycho_softc *)device_get_softc(dev);
882 offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
883 bh = sc->sc_bh[PCI_CS_CONFIG];
884 switch (width) {
885 case 1:
886 i = bus_space_peek_1(sc->sc_cfgt, bh, offset, &byte);

--- 14 unchanged lines hidden (view full) ---

901 if (i) {
902#ifdef PSYCHO_DEBUG
903 printf("psycho read data error reading: %d.%d.%d: 0x%x\n",
904 bus, slot, func, reg);
905#endif
906 r = -1;
907 }
908
899 int i;
900
901 sc = (struct psycho_softc *)device_get_softc(dev);
902 offset = PSYCHO_CONF_OFF(bus, slot, func, reg);
903 bh = sc->sc_bh[PCI_CS_CONFIG];
904 switch (width) {
905 case 1:
906 i = bus_space_peek_1(sc->sc_cfgt, bh, offset, &byte);

--- 14 unchanged lines hidden (view full) ---

921 if (i) {
922#ifdef PSYCHO_DEBUG
923 printf("psycho read data error reading: %d.%d.%d: 0x%x\n",
924 bus, slot, func, reg);
925#endif
926 r = -1;
927 }
928
929#ifndef OFW_NEWPCI
909 if (reg == PCIR_INTPIN && r == 0) {
910 /* Check for DQT_BAD_INTPIN quirk. */
911 devid = psycho_read_config(dev, bus, slot, func,
912 PCIR_DEVVENDOR, 4);
913 for (i = 0; i < NDQUIRKS; i++) {
914 if (dquirks[i].dq_devid == devid) {
915 /*
916 * Need to set the intpin to a value != 0 so

--- 5 unchanged lines hidden (view full) ---

922 * matter.
923 */
924 if ((dquirks[i].dq_quirk & DQT_BAD_INTPIN) != 0)
925 r = 1;
926 break;
927 }
928 }
929 }
930 if (reg == PCIR_INTPIN && r == 0) {
931 /* Check for DQT_BAD_INTPIN quirk. */
932 devid = psycho_read_config(dev, bus, slot, func,
933 PCIR_DEVVENDOR, 4);
934 for (i = 0; i < NDQUIRKS; i++) {
935 if (dquirks[i].dq_devid == devid) {
936 /*
937 * Need to set the intpin to a value != 0 so

--- 5 unchanged lines hidden (view full) ---

943 * matter.
944 */
945 if ((dquirks[i].dq_quirk & DQT_BAD_INTPIN) != 0)
946 r = 1;
947 break;
948 }
949 }
950 }
951#endif /* !OFW_NEWPCI */
930 return (r);
931}
932
933static void
934psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
935 u_int reg, u_int32_t val, int width)
936{
937 struct psycho_softc *sc;

--- 14 unchanged lines hidden (view full) ---

952 bus_space_write_4(sc->sc_cfgt, bh, offset, val);
953 break;
954 default:
955 panic("psycho_write_config: bad width");
956 }
957}
958
959static int
952 return (r);
953}
954
955static void
956psycho_write_config(device_t dev, u_int bus, u_int slot, u_int func,
957 u_int reg, u_int32_t val, int width)
958{
959 struct psycho_softc *sc;

--- 14 unchanged lines hidden (view full) ---

974 bus_space_write_4(sc->sc_cfgt, bh, offset, val);
975 break;
976 default:
977 panic("psycho_write_config: bad width");
978 }
979}
980
981static int
960psycho_route_interrupt(device_t bus, device_t dev, int pin)
982psycho_route_interrupt(device_t bridge, device_t dev, int pin)
961{
983{
984#ifdef OFW_NEWPCI
985 struct psycho_softc *sc = device_get_softc(bridge);
986 struct ofw_pci_register reg;
987 bus_addr_t intrmap;
988 phandle_t node = ofw_pci_get_node(dev);
989 ofw_pci_intr_t pintr, mintr;
990 u_int8_t maskbuf[sizeof(reg) + sizeof(pintr)];
962
991
992 pintr = pin;
993 if (ofw_bus_lookup_imap(node, &sc->sc_iinfo, &reg, sizeof(reg),
994 &pintr, sizeof(pintr), &mintr, sizeof(mintr), maskbuf))
995 return (mintr);
963 /*
996 /*
997 * If this is outside of the range for an intpin, it's likely a full
998 * INO, and no mapping is required at all; this happens on the u30,
999 * where there's no interrupt map at the psycho node. Fortunately,
1000 * there seem to be no INOs in the intpin range on this boxen, so
1001 * this easy heuristics will do.
1002 */
1003 if (pin > 4)
1004 return (pin);
1005 /*
1006 * Guess the INO; we always assume that this is a non-OBIO
1007 * device, and that pin is a "real" intpin number. Determine
1008 * the mapping register to be used by the slot number.
1009 * We only need to do this on e450s, it seems; here, the slot numbers
1010 * for bus A are one-based, while those for bus B seemingly have an
1011 * offset of 2 (hence the factor of 3 below).
1012 */
1013 intrmap = PSR_PCIA0_INT_MAP +
1014 8 * (pci_get_slot(dev) - 1 + 3 * sc->sc_half);
1015 mintr = INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1;
1016 device_printf(bridge, "guessing interrupt %d for device %d/%d pin %d\n",
1017 (int)mintr, pci_get_slot(dev), pci_get_function(dev), pin);
1018 return (mintr);
1019#else
1020 /*
964 * XXX: ugly loathsome hack:
965 * We can't use ofw_pci_route_intr() here; the device passed may be
966 * the one of a bridge, so the original device can't be recovered.
967 *
968 * We need to use the firmware to route interrupts, however it has
969 * no interface which could be used to interpret intpins; instead,
970 * all assignments are done by device.
971 *
972 * The MI pci code will try to reroute interrupts of 0, although they
973 * are correct; all other interrupts are preinitialized, so if we
974 * get here, the intline is either 0 (so return 0), or we hit a
975 * device which was not preinitialized (e.g. hotplugged stuff), in
976 * which case we are lost.
977 */
978 return (0);
1021 * XXX: ugly loathsome hack:
1022 * We can't use ofw_pci_route_intr() here; the device passed may be
1023 * the one of a bridge, so the original device can't be recovered.
1024 *
1025 * We need to use the firmware to route interrupts, however it has
1026 * no interface which could be used to interpret intpins; instead,
1027 * all assignments are done by device.
1028 *
1029 * The MI pci code will try to reroute interrupts of 0, although they
1030 * are correct; all other interrupts are preinitialized, so if we
1031 * get here, the intline is either 0 (so return 0), or we hit a
1032 * device which was not preinitialized (e.g. hotplugged stuff), in
1033 * which case we are lost.
1034 */
1035 return (0);
1036#endif /* OFW_NEWPCI */
979}
980
981static int
982psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
983{
984 struct psycho_softc *sc;
985
986 sc = (struct psycho_softc *)device_get_softc(dev);
987 switch (which) {
988 case PCIB_IVAR_BUS:
1037}
1038
1039static int
1040psycho_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
1041{
1042 struct psycho_softc *sc;
1043
1044 sc = (struct psycho_softc *)device_get_softc(dev);
1045 switch (which) {
1046 case PCIB_IVAR_BUS:
989 *result = sc->sc_busno;
1047 *result = sc->sc_secbus;
990 return (0);
991 }
992 return (ENOENT);
993}
994
995/* Write to the correct clr register, and call the actual handler. */
996static void
997psycho_intr_stub(void *arg)

--- 29 unchanged lines hidden (view full) ---

1027 * XXX We only compare INOs rather than IGNs since the firmware may
1028 * not provide the IGN and the IGN is constant for all device on that
1029 * PCI controller. This could cause problems for the FFB/external
1030 * interrupt which has a full vector that can be set arbitrarily.
1031 */
1032 ino = INTINO(vec);
1033
1034 if (!psycho_find_intrmap(sc, ino, &intrmapptr, &intrclrptr, NULL)) {
1048 return (0);
1049 }
1050 return (ENOENT);
1051}
1052
1053/* Write to the correct clr register, and call the actual handler. */
1054static void
1055psycho_intr_stub(void *arg)

--- 29 unchanged lines hidden (view full) ---

1085 * XXX We only compare INOs rather than IGNs since the firmware may
1086 * not provide the IGN and the IGN is constant for all device on that
1087 * PCI controller. This could cause problems for the FFB/external
1088 * interrupt which has a full vector that can be set arbitrarily.
1089 */
1090 ino = INTINO(vec);
1091
1092 if (!psycho_find_intrmap(sc, ino, &intrmapptr, &intrclrptr, NULL)) {
1035 printf("Cannot find interrupt vector %lx\n", vec);
1093 device_printf(dev, "Cannot find interrupt vector %lx\n", vec);
1036 free(pc, M_DEVBUF);
1037 return (NULL);
1038 }
1039
1040#ifdef PSYCHO_DEBUG
1041 device_printf(dev, "psycho_setup_intr: INO %d, map %#lx, clr %#lx\n",
1042 ino, (u_long)intrmapptr, (u_long)intrclrptr);
1043#endif

--- 155 unchanged lines hidden (view full) ---

1199 error = bus_deactivate_resource(child, type, rid, r);
1200 if (error)
1201 return error;
1202 }
1203 return (rman_release_resource(r));
1204}
1205
1206static int
1094 free(pc, M_DEVBUF);
1095 return (NULL);
1096 }
1097
1098#ifdef PSYCHO_DEBUG
1099 device_printf(dev, "psycho_setup_intr: INO %d, map %#lx, clr %#lx\n",
1100 ino, (u_long)intrmapptr, (u_long)intrclrptr);
1101#endif

--- 155 unchanged lines hidden (view full) ---

1257 error = bus_deactivate_resource(child, type, rid, r);
1258 if (error)
1259 return error;
1260 }
1261 return (rman_release_resource(r));
1262}
1263
1264static int
1207psycho_intr_pending(device_t dev, int intr)
1265psycho_intr_pending(device_t dev, ofw_pci_intr_t intr)
1208{
1209 struct psycho_softc *sc;
1210 u_long diag;
1211
1212 sc = (struct psycho_softc *)device_get_softc(dev);
1213 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) {
1266{
1267 struct psycho_softc *sc;
1268 u_long diag;
1269
1270 sc = (struct psycho_softc *)device_get_softc(dev);
1271 if (!psycho_find_intrmap(sc, intr, NULL, NULL, &diag)) {
1214 printf("psycho_intr_pending: mapping not found for %d\n", intr);
1272 device_printf(dev, "psycho_intr_pending: mapping not found for"
1273 " %d\n", intr);
1215 return (0);
1216 }
1217 return (diag != 0);
1218}
1219
1274 return (0);
1275 }
1276 return (diag != 0);
1277}
1278
1220static u_int32_t
1279#ifndef OFW_NEWPCI
1280static ofw_pci_intr_t
1221psycho_guess_ino(device_t dev, phandle_t node, u_int slot, u_int pin)
1222{
1223 struct psycho_softc *sc = (struct psycho_softc *)device_get_softc(dev);
1224 bus_addr_t intrmap;
1225
1226 /*
1227 * If this is not for one of our direct children (i.e. we are mapping
1228 * at our node), tell the interrupt mapper to go on - we need the
1229 * slot number of the device or it's topmost parent bridge to guess
1230 * the INO.
1231 */
1232 if (node != sc->sc_node)
1281psycho_guess_ino(device_t dev, phandle_t node, u_int slot, u_int pin)
1282{
1283 struct psycho_softc *sc = (struct psycho_softc *)device_get_softc(dev);
1284 bus_addr_t intrmap;
1285
1286 /*
1287 * If this is not for one of our direct children (i.e. we are mapping
1288 * at our node), tell the interrupt mapper to go on - we need the
1289 * slot number of the device or it's topmost parent bridge to guess
1290 * the INO.
1291 */
1292 if (node != sc->sc_node)
1233 return (255);
1293 return (PCI_INVALID_IRQ);
1234 /*
1235 * Actually guess the INO. We always assume that this is a non-OBIO
1236 * device, and use from the slot number to determine it.
1237 * We only need to do this on e450s, it seems; here, the slot numbers
1238 * for bus A are one-based, while those for bus B seemingly have an
1239 * offset of 2 (hence the factor of 3 below).
1240 */
1241 intrmap = PSR_PCIA0_INT_MAP + 8 * (slot - 1 + 3 * sc->sc_half);
1242 return (INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1);
1243}
1294 /*
1295 * Actually guess the INO. We always assume that this is a non-OBIO
1296 * device, and use from the slot number to determine it.
1297 * We only need to do this on e450s, it seems; here, the slot numbers
1298 * for bus A are one-based, while those for bus B seemingly have an
1299 * offset of 2 (hence the factor of 3 below).
1300 */
1301 intrmap = PSR_PCIA0_INT_MAP + 8 * (slot - 1 + 3 * sc->sc_half);
1302 return (INTINO(PSYCHO_READ8(sc, intrmap)) + pin - 1);
1303}
1304#endif /* !OFW_NEWPCI */
1244
1245static bus_space_handle_t
1305
1306static bus_space_handle_t
1246psycho_get_bus_handle(device_t dev, enum sbbt_id id,
1247 bus_space_handle_t childhdl, bus_space_tag_t *tag)
1307psycho_get_bus_handle(device_t dev, int type, bus_space_handle_t childhdl,
1308 bus_space_tag_t *tag)
1248{
1249 struct psycho_softc *sc;
1250
1251 sc = (struct psycho_softc *)device_get_softc(dev);
1309{
1310 struct psycho_softc *sc;
1311
1312 sc = (struct psycho_softc *)device_get_softc(dev);
1252 switch(id) {
1253 case SBBT_IO:
1313 switch (type) {
1314 case SYS_RES_IOPORT:
1254 *tag = sc->sc_iot;
1255 return (sc->sc_bh[PCI_CS_IO] + childhdl);
1315 *tag = sc->sc_iot;
1316 return (sc->sc_bh[PCI_CS_IO] + childhdl);
1256 case SBBT_MEM:
1317 case SYS_RES_MEMORY:
1257 *tag = sc->sc_memt;
1258 return (sc->sc_bh[PCI_CS_MEM32] + childhdl);
1259 default:
1260 panic("psycho_get_bus_handle: illegal space\n");
1261 }
1262}
1263
1318 *tag = sc->sc_memt;
1319 return (sc->sc_bh[PCI_CS_MEM32] + childhdl);
1320 default:
1321 panic("psycho_get_bus_handle: illegal space\n");
1322 }
1323}
1324
1325#ifdef OFW_NEWPCI
1326static phandle_t
1327psycho_get_node(device_t bus, device_t dev)
1328{
1329 struct psycho_softc *sc = device_get_softc(bus);
1330
1331 /* We only have one child, the PCI bus, which needs our own node. */
1332 return (sc->sc_node);
1333}
1334
1335static void
1336psycho_adjust_busrange(device_t dev, u_int subbus)
1337{
1338 struct psycho_softc *sc = device_get_softc(dev);
1339
1340 /* If necessary, adjust the subordinate bus number register. */
1341 if (subbus > sc->sc_subbus) {
1342#ifdef PSYCHO_DEBUG
1343 device_printf(dev,
1344 "adjusting secondary bus number from %d to %d\n",
1345 sc->sc_subbus, subbus);
1346#endif
1347 sc->sc_subbus = subbus;
1348 PCIB_WRITE_CONFIG(dev, sc->sc_secbus, PCS_DEVICE, PCS_FUNC,
1349 PCSR_SUBBUS, subbus, 1);
1350 }
1351}
1352#endif
1353
1264/*
1265 * below here is bus space and bus dma support
1266 */
1267static bus_space_tag_t
1268psycho_alloc_bus_tag(struct psycho_softc *sc, int type)
1269{
1270 bus_space_tag_t bt;
1271
1272 bt = (bus_space_tag_t)malloc(sizeof(struct bus_space_tag), M_DEVBUF,
1273 M_NOWAIT | M_ZERO);
1274 if (bt == NULL)
1275 panic("psycho_alloc_bus_tag: out of memory");
1276
1277 bzero(bt, sizeof *bt);
1278 bt->bst_cookie = sc;
1279 bt->bst_parent = sc->sc_bustag;
1280 bt->bst_type = type;
1281 return (bt);
1282}
1354/*
1355 * below here is bus space and bus dma support
1356 */
1357static bus_space_tag_t
1358psycho_alloc_bus_tag(struct psycho_softc *sc, int type)
1359{
1360 bus_space_tag_t bt;
1361
1362 bt = (bus_space_tag_t)malloc(sizeof(struct bus_space_tag), M_DEVBUF,
1363 M_NOWAIT | M_ZERO);
1364 if (bt == NULL)
1365 panic("psycho_alloc_bus_tag: out of memory");
1366
1367 bzero(bt, sizeof *bt);
1368 bt->bst_cookie = sc;
1369 bt->bst_parent = sc->sc_bustag;
1370 bt->bst_type = type;
1371 return (bt);
1372}