Deleted Added
sdiff udiff text old ( 116659 ) new ( 117119 )
full compact
1/*
2 * Copyright (c) 1999, 2000 Matthew R. Green
3 * 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 *
31 * $FreeBSD: head/sys/sparc64/pci/psycho.c 116659 2003-06-22 01:26:08Z jmg $
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_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>
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"
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);
83
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);
97static ofw_pci_binit_t psycho_binit;
98
99/*
100 * autoconfiguration
101 */
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);
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
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),
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;
317 struct ofw_pci_bdesc obd;
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
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;
593 obd.obd_slot = PCS_DEVICE;
594 obd.obd_func = PCS_FUNC;
595 obd.obd_init = psycho_binit;
596 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;
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);
611
612 device_add_child(dev, "pci", device_get_unit(dev));
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. */
729 printf("%s: correctable DMA error AFAR %#lx AFSR %#lx\n",
730 device_get_name(sc->sc_dev), (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. */
783 printf("%s: power management wakeup\n", device_get_name(sc->sc_dev));
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
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 */
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);
828 PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
829 PCSR_SECBUS, obd->obd_secbus, 1);
830}
831
832static int
833psycho_maxslots(device_t dev)
834{
835
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);
842}
843
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};
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;
875 u_int32_t r, devid;
876 u_int8_t byte;
877 u_int16_t shrt;
878 u_int32_t wrd;
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
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 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
960psycho_route_interrupt(device_t bus, device_t dev, int pin)
961{
962
963 /*
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);
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:
989 *result = sc->sc_busno;
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)) {
1035 printf("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
1207psycho_intr_pending(device_t dev, int 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)) {
1214 printf("psycho_intr_pending: mapping not found for %d\n", intr);
1215 return (0);
1216 }
1217 return (diag != 0);
1218}
1219
1220static u_int32_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)
1233 return (255);
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}
1244
1245static 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)
1248{
1249 struct psycho_softc *sc;
1250
1251 sc = (struct psycho_softc *)device_get_softc(dev);
1252 switch(id) {
1253 case SBBT_IO:
1254 *tag = sc->sc_iot;
1255 return (sc->sc_bh[PCI_CS_IO] + childhdl);
1256 case SBBT_MEM:
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
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}