Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sparc64/dev implement U2P PCI support in psycho_ini...
details: https://anonhg.NetBSD.org/src/rev/2bd36f3e1ef2
branches: trunk
changeset: 485802:2bd36f3e1ef2
user: mrg <mrg%NetBSD.org@localhost>
date: Sat May 06 04:15:35 2000 +0000
description:
implement U2P PCI support in psycho_init. this is completely untested.
diffstat:
sys/arch/sparc64/dev/psycho.c | 122 +++++++++++++++++++++++++++++++++++++----
1 files changed, 110 insertions(+), 12 deletions(-)
diffs (174 lines):
diff -r 9651efad1e1a -r 2bd36f3e1ef2 sys/arch/sparc64/dev/psycho.c
--- a/sys/arch/sparc64/dev/psycho.c Sat May 06 02:41:32 2000 +0000
+++ b/sys/arch/sparc64/dev/psycho.c Sat May 06 04:15:35 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: psycho.c,v 1.7 2000/04/22 17:06:03 mrg Exp $ */
+/* $NetBSD: psycho.c,v 1.8 2000/05/06 04:15:35 mrg Exp $ */
/*
* Copyright (c) 1999, 2000 Matthew R. Green
@@ -73,6 +73,8 @@
#include <sparc64/dev/psychovar.h>
#include <sparc64/sparc64/cache.h>
+#include "ioconf.h"
+
static pci_chipset_tag_t psycho_alloc_chipset __P((struct psycho_pbm *, int,
pci_chipset_tag_t));
static void psycho_get_bus_range __P((int, int *));
@@ -301,13 +303,12 @@
if (simba_br[0] == 1) { /* PCI B */
pp = sc->sc_simba_b;
- pp->pp_pcictl = &sc->sc_regs->psy_pcictl[1];
who = 'b';
} else { /* PCI A */
pp = sc->sc_simba_a;
- pp->pp_pcictl = &sc->sc_regs->psy_pcictl[0];
who = 'a';
}
+ pp->pp_pcictl = &sc->sc_regs->psy_pcictl[0];
/* link us in .. */
pp->pp_sc = sc;
@@ -381,9 +382,14 @@
struct psycho_softc *sc;
struct pcibus_attach_args *pba;
{
-#if 1
- panic("can't do SUNW,psycho yet");
-#else
+ struct psycho_softc *osc = NULL;
+ struct psycho_pbm *pp;
+ bus_space_handle_t bh;
+ u_int64_t csr;
+ int psycho_br[2], n;
+ char who;
+
+ printf("psycho: ");
/*
* OK, so the deal here is:
@@ -394,7 +400,8 @@
* - otherwise, we are doing the hard slog.
*/
for (n = 0; n < psycho_cd.cd_ndevs; n++) {
- psycho_softc *osc = &psycho_cd.cd_devs[n];
+
+ osc = (struct psycho_softc *)&psycho_cd.cd_devs[n];
/*
* I am not myself.
@@ -404,16 +411,107 @@
/*
* OK, so we found a matching regs that wasn't me,
- * so that must make me partly attached. Finish it.
+ * so that means my IOMMU is setup.
*/
+
+ /* who? said a voice, incredulous */
+ sc->sc_mode = PSYCHO_MODE_PSYCHO_B; /* XXX */
+ who = 'b';
+ break;
+ }
+
+ if (sc->sc_mode != PSYCHO_MODE_PSYCHO_B) {
+ sc->sc_mode = PSYCHO_MODE_PSYCHO_A; /* XXX */
+ who = 'a';
}
/* Oh, dear. OK, lets get started */
- /* who? said a voice, incredulous */
- sc->sc_mode = PSYCHO_MODE_PSYCHO_A;
- printf("psycho: ");
-#endif
+ /* XXX: check this is OK for real psycho */
+ /* setup the PCI control register */
+ csr = bus_space_read_8(sc->sc_bustag, (bus_space_handle_t)(u_long)&sc->sc_regs->psy_pcictl[0].pci_csr, 0);
+ csr |= PCICTL_MRLM |
+ PCICTL_ARB_PARK |
+ PCICTL_ERRINTEN |
+ PCICTL_4ENABLE;
+ csr &= ~(PCICTL_SERR |
+ PCICTL_CPU_PRIO |
+ PCICTL_ARB_PRIO |
+ PCICTL_RTRYWAIT);
+ bus_space_write_8(sc->sc_bustag, &sc->sc_regs->psy_pcictl[0].pci_csr, 0, csr);
+
+ /* allocate our psycho_pbm */
+ sc->sc_psycho_this = malloc(sizeof *pp, M_DEVBUF, M_NOWAIT);
+ if (sc->sc_psycho_this == NULL)
+ panic("could not allocate psycho pbm");
+ if (osc) {
+ sc->sc_psycho_other = osc->sc_psycho_this;
+ osc->sc_psycho_other = sc->sc_psycho_this;
+ }
+
+ memset(sc->sc_psycho_this, 0, sizeof *pp);
+
+ /* grab the psycho ranges */
+ psycho_get_ranges(sc->sc_node, &sc->sc_psycho_this->pp_range,
+ &sc->sc_psycho_this->pp_nrange);
+
+ /* get the bus-range for the psycho */
+ psycho_get_bus_range(sc->sc_node, psycho_br);
+
+ pba->pba_bus = psycho_br[0];
+
+ printf("bus range %u to %u", psycho_br[0], psycho_br[1]);
+ printf("; simba %c, PCI bus %d", who, psycho_br[0]);
+
+ pp->pp_pcictl = &sc->sc_regs->psy_pcictl[0];
+
+ /* grab the psycho registers, interrupt map and map mask */
+ psycho_get_registers(sc->sc_node, &pp->pp_regs, &pp->pp_nregs);
+ psycho_get_intmap(sc->sc_node, &pp->pp_intmap, &pp->pp_nintmap);
+ psycho_get_intmapmask(sc->sc_node, &pp->pp_intmapmask);
+
+ /* allocate our tags */
+ pp->pp_memt = psycho_alloc_mem_tag(pp);
+ pp->pp_iot = psycho_alloc_io_tag(pp);
+ pp->pp_dmat = psycho_alloc_dma_tag(pp);
+ pp->pp_flags = (pp->pp_memt ? PCI_FLAGS_MEM_ENABLED : 0) |
+ (pp->pp_iot ? PCI_FLAGS_IO_ENABLED : 0);
+
+ /* allocate a chipset for this */
+ pp->pp_pc = psycho_alloc_chipset(pp, sc->sc_node, &_sparc_pci_chipset);
+
+ /* setup the rest of the psycho pbm */
+ pp->pp_sc = sc;
+ pba->pba_pc = psycho_alloc_chipset(pp, sc->sc_node,
+ sc->sc_psycho_this->pp_pc);
+
+ printf("\n");
+
+ /*
+ * and finally, if we a a psycho A, start up the IOMMU and
+ * get us a config space tag, and punch in the physical address
+ * of the PCI configuration space. note that we use unmapped
+ * access to PCI configuration space, relying on the bus space
+ * macros to provide the proper ASI based on the bus tag.
+ */
+ if (sc->sc_mode == PSYCHO_MODE_PSYCHO_A) {
+ psycho_iommu_init(sc);
+
+ sc->sc_configtag = psycho_alloc_config_tag(sc->sc_psycho_this);
+ if (bus_space_map2(sc->sc_bustag,
+ PCI_CONFIG_BUS_SPACE,
+ sc->sc_basepaddr + 0x01000000,
+ 0x0100000,
+ 0,
+ 0,
+ &bh))
+ panic("could not map sabre PCI configuration space");
+ sc->sc_configaddr = (paddr_t)bh;
+ } else {
+ /* for psycho B, we just copy the config tag and address */
+ sc->sc_configtag = osc->sc_configtag;
+ sc->sc_configaddr = osc->sc_configaddr;
+ }
}
/*
Home |
Main Index |
Thread Index |
Old Index