summaryrefslogtreecommitdiff
path: root/sys/arch/pmax/tc/tc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/pmax/tc/tc.c')
-rw-r--r--sys/arch/pmax/tc/tc.c300
1 files changed, 229 insertions, 71 deletions
diff --git a/sys/arch/pmax/tc/tc.c b/sys/arch/pmax/tc/tc.c
index 02cc6023f1d..f98d1783bc6 100644
--- a/sys/arch/pmax/tc/tc.c
+++ b/sys/arch/pmax/tc/tc.c
@@ -1,4 +1,4 @@
-/* $NetBSD: tc.c,v 1.6 1995/12/28 06:44:57 jonathan Exp $ */
+/* $NetBSD: tc.c,v 1.7 1996/01/03 20:39:10 jonathan Exp $ */
/*
* Copyright (c) 1994, 1995 Carnegie-Mellon University.
@@ -29,24 +29,56 @@
#include <sys/param.h>
#include <sys/device.h>
-
+#include <dev/cons.h>
+#include <dev/tc/tcvar.h>
#include <machine/autoconf.h>
#ifdef alpha
#include <machine/rpb.h>
-#include <alpha/tc/tc.h>
#endif
-#ifdef pmax
-#include <pmax/tc/tc.h>
-#endif
+/* Which TC framebuffers have drivers, for configuring a console device. */
+#include <cfb.h>
+#include <mfb.h>
+#include <sfb.h>
+
+extern int pmax_boardtype;
+
struct tc_softc {
struct device sc_dv;
+ int sc_nslots;
+ struct tc_slotdesc *sc_slots;
+
+ void (*sc_intr_establish) __P((struct device *, void *,
+ tc_intrlevel_t, int (*)(void *), void *));
+ void (*sc_intr_disestablish) __P((struct device *, void *));
+#ifndef goneverysoon
struct abus sc_bus;
struct tc_cpu_desc *sc_desc;
+#endif /* goneverysoon */
};
+/*
+ * Old-style model-specific autoconfiguration description.
+ */
+struct tc_cpu_desc {
+ struct tc_slotdesc *tcd_slots;
+ long tcd_nslots;
+ struct confargs *tcd_devs;
+ long tcd_ndevs;
+ void (*tc_intr_setup) __P((void));
+ void (*tc_intr_establish) __P((struct device *dev, void *cookie,
+ int level, intr_handler_t handler, void *arg));
+ void (*tc_intr_disestablish) __P((struct device *, void *));
+ int (*tc_iointr) __P((u_int mask, u_int pc,
+ u_int statusReg, u_int causeReg));
+};
+
+/* Return the appropriate tc_cpu_desc for a given cputype */
+extern struct tc_cpu_desc * cpu_tcdesc __P ((int cputype));
+
+
/* Definition of the driver for autoconfig. */
int tcmatch(struct device *, void *, void *);
void tcattach(struct device *, struct device *, void *);
@@ -54,13 +86,17 @@ int tcprint(void *, char *);
struct cfdriver tccd =
{ NULL, "tc", tcmatch, tcattach, DV_DULL, sizeof (struct tc_softc) };
-void tc_intr_establish __P((struct confargs *, intr_handler_t handler,
- intr_arg_t));
-void tc_intr_disestablish __P((struct confargs *));
+void tc_intr_establish __P((struct device *, void *, tc_intrlevel_t,
+ intr_handler_t handler, intr_arg_t arg));
+void tc_intr_disestablish __P((struct device *dev, void *cookie));
caddr_t tc_cvtaddr __P((struct confargs *));
int tc_matchname __P((struct confargs *, char *));
extern int cputype;
+extern int tc_findconsole __P((int prom_slot));
+
+/* Forward declarations */
+int consprobeslot __P((int slot));
/*XXX*/ /* should be in separate source file */
@@ -82,13 +118,15 @@ extern int cputype;
#include <pmax/pmax/turbochannel.h>
-#include <pmax/pmax/nameglue.h>
+/*#include <pmax/pmax/nameglue.h>*/
+#define KV(x) ((tc_addr_t)MACH_PHYS_TO_UNCACHED(x))
+
void tc_ds_ioasic_intr_setup __P((void));
-void tc_ds_ioasic_intr_establish
- __P((struct confargs *, intr_handler_t, void *));
-void tc_ds_ioasic_intr_disestablish __P((struct confargs *));
+void tc_ds_ioasic_intr_establish __P((struct device *dev, void *cookie,
+ int level, intr_handler_t handler, void *arg));
+void tc_ds_ioasic_intr_disestablish __P((struct device *, void *));
void tc_ds_ioasic_iointr __P((void *, int));
int tc_ds_ioasic_getdev __P((struct confargs *));
@@ -111,36 +149,12 @@ extern void xine_enable_intr __P ((u_int slot, tc_handler_t,
void *intr_arg, int on));
/*
- * configuration tables for the four models of
+ * Configuration tables for the four models of
* Decstation that have turbochannels.
* None of the four are the same.
*/
#include "ds-tc-conf.c"
-
-/*
- * Mapping from CPU type to a tc_cpu_desc for that CPU type.
- * (Alpha-specific.)
- */
-struct tc_cpu_desc *tc_cpu_devs[] = {
- NULL, /* Unused */
- NULL, /* ST_ADU */
- NULL, /* ST_DEC_4000 */
- NULL, /* ST_DEC_7000 */
-#ifdef DEC_3000_500
- &dec_3000_500_cpu, /* ST_DEC_3000_500 */
-#else
- NULL,
-#endif
- NULL, /* Unused */
- NULL, /* ST_DEC_2000_300 */
-#ifdef DEC_3000_300
- &dec_3000_300_cpu, /* ST_DEC_3000_300 */
-#else
- NULL,
-#endif
-};
-int ntc_cpu_devs = sizeof tc_cpu_devs / sizeof tc_cpu_devs[0];
/*
* Function to map from a CPU code to a tc_cpu_desc.
@@ -151,8 +165,6 @@ struct tc_cpu_desc *
cpu_tcdesc(cpu)
int cpu;
{
- /*XXX*/
-#ifdef pmax
if (cpu == DS_3MAXPLUS) {
tc_enable_interrupt = kn03_enable_intr;
return &kn03_tc_desc;
@@ -160,27 +172,60 @@ cpu_tcdesc(cpu)
tc_enable_interrupt = kn02_enable_intr;
return &kn02_tc_desc;
} else if (cpu == DS_3MIN) {
- DPRINTF(("tcattach: 3MIN Turbochannel\n"));
tc_enable_interrupt = kmin_enable_intr;
return &kmin_tc_desc;
} else if (cpu == DS_MAXINE) {
- DPRINTF(("MAXINE turbochannel\n"));
+#ifdef DEBUG
+ printf("MAXINE turbochannel\n");
+#endif
tc_enable_interrupt = xine_enable_intr;
return &xine_tc_desc;
} else if (cpu == DS_PMAX) {
- DPRINTF(("tcattach: PMAX, no turbochannel\n"));
+#ifdef DIAGNOSTIC
+ printf("tcattach: PMAX, no turbochannel\n");
+#endif
return NULL;
} else if (cpu == DS_MIPSFAIR) {
- DPRINTF(("tcattach: Mipsfair (5100), no turbochannel\n"));
+ printf("tcattach: Mipsfair (5100), no turbochannel\n");
+ return NULL;
} else {
panic("tcattach: Unrecognized bus type 0x%x\n", cpu);
}
+}
+
+
+/*
+ * Temporary glue:
+ * present the old-style signatures as used by BUS_INTR_ESTABLISH(),
+ * but using the new NetBSD machine-independent TC infrastructure.
+ */
-#else /* alpha?*/
- return tc_cpu_devs[cputype];
-#endif /* alpha?*/
+void
+confglue_tc_intr_establish(ca, handler, arg)
+ struct confargs *ca;
+ intr_handler_t handler;
+ intr_arg_t arg;
+{
+ struct tc_softc *sc = tccd.cd_devs[0]; /* XXX */
+ /* XXX guess at level */
+ (*sc->sc_desc->tc_intr_establish)
+ ((struct device*)sc, (void*)ca->ca_slotpri, 0, handler, arg);
}
+void
+confglue_tc_intr_disestablish(ca)
+ struct confargs *ca;
+{
+ struct tc_softc *sc = tccd.cd_devs[0]; /* XXX */
+
+ (*sc->sc_desc->tc_intr_disestablish)(
+ (struct device*)sc, (void*)ca->ca_slotpri);
+}
+/*
+ * End of temporary glue.
+ */
+
+
int
tcmatch(parent, cfdata, aux)
struct device *parent;
@@ -239,8 +284,8 @@ tcattach(parent, self, aux)
sc->sc_bus.ab_dv = (struct device *)sc;
sc->sc_bus.ab_type = BUS_TC;
- sc->sc_bus.ab_intr_establish = tc_intr_establish;
- sc->sc_bus.ab_intr_disestablish = tc_intr_disestablish;
+ sc->sc_bus.ab_intr_establish = confglue_tc_intr_establish;
+ sc->sc_bus.ab_intr_disestablish = confglue_tc_intr_disestablish;
sc->sc_bus.ab_cvtaddr = tc_cvtaddr;
sc->sc_bus.ab_matchname = tc_matchname;
@@ -296,28 +341,40 @@ tc_cvtaddr(ca)
{
struct tc_softc *sc = tccd.cd_devs[0];
- return (sc->sc_desc->tcd_slots[ca->ca_slot].tsd_dense + ca->ca_offset);
+ return ((caddr_t)sc->sc_desc->tcd_slots[ca->ca_slot].tcs_addr +
+ ca->ca_offset);
}
void
-tc_intr_establish(ca, handler, val)
- struct confargs *ca;
+tc_intr_establish(dev, cookie, level, handler, arg)
+ /*struct confargs *ca;*/
+ struct device *dev;
+ void *cookie;
+ tc_intrlevel_t level;
intr_handler_t handler;
- intr_arg_t val;
+ intr_arg_t arg;
{
- struct tc_softc *sc = tccd.cd_devs[0];
+ struct tc_softc *sc = (struct tc_softc *)dev;
+
+#ifdef DEBUG
+ printf("tc_intr_establish: %s parent intrcode %d\n",
+ dev->dv_xname, dev->dv_parent->dv_xname, (int) cookie);
+#endif
- (*sc->sc_desc->tc_intr_establish)(ca, handler, val);
+ /* XXX pmax interrupt-enable interface */
+ (*sc->sc_desc->tc_intr_establish)(sc->sc_dv.dv_parent, cookie,
+ level, handler, arg);
}
void
-tc_intr_disestablish(ca)
- struct confargs *ca;
+tc_intr_disestablish(dev, cookie)
+ struct device *dev;
+ void *cookie;
{
- struct tc_softc *sc = tccd.cd_devs[0];
+ struct tc_softc *sc = (struct tc_softc *)dev;
- (*sc->sc_desc->tc_intr_disestablish)(ca);
+ (*sc->sc_intr_disestablish)(sc->sc_dv.dv_parent, cookie);
}
int
@@ -390,8 +447,102 @@ tc_intrnull(val)
panic("uncaught TC intr for slot %ld\n", (long)val);
}
+
-/* hack for kn03 */
+
+/*
+ * Probe the turbochannel for a framebuffer option card, starting
+ * at the preferred slot and then scanning all slots. Configure the first
+ * supported framebuffer device found, if any, as the console, and return
+ * 1 if found.
+ * Called before autoconfiguration, to find a system console.
+ */
+int
+tc_findconsole(preferred_slot)
+ int preferred_slot;
+{
+ int slot;
+
+ struct tc_cpu_desc * sc_desc;
+
+ /* First, try the slot configured as console in NVRAM. */
+ /* if (consprobeslot(preferred_slot)) return (1); */
+
+ /*
+ * Try to configure each turbochannel (or CPU-internal) device.
+ * Knows about gross internals of TurboChannel bus autoconfig
+ * descriptor, which needs to be fixed badly.
+ */
+ if ((sc_desc = cpu_tcdesc(pmax_boardtype)) == NULL)
+ return 0;
+ for (slot = 0; slot < sc_desc->tcd_ndevs; slot++) {
+
+ if (tc_consprobeslot(slot))
+ return (1);
+ }
+ return (0);
+}
+
+/*
+ * Try and configure one slot as framebuffer console.
+ * Accept only the framebuffers for which driver are configured into
+ * the kernel. If a suitable framebuffer is found, attach it and
+ * set up glass-tty emulation.
+ */
+int
+tc_consprobeslot(slot)
+ int slot;
+{
+ void *slotaddr;
+ char name[20];
+ struct tc_cpu_desc * sc_desc;
+
+ if (slot < 0 || ((sc_desc = cpu_tcdesc(pmax_boardtype)) == NULL))
+ return 0;
+ slotaddr = (void *)(sc_desc->tcd_slots[slot].tcs_addr);
+
+ if (tc_checkdevmem(slotaddr) == 0)
+ return (0);
+
+ if (tc_checkslot(slotaddr, name) == 0)
+ return (0);
+
+ /*
+ * We found an device in the given slot. Now see if it's a
+ * framebuffer for which we have a driver.
+ */
+
+ /*printf(", trying to init a \"%s\"", name);*/
+
+#define DRIVER_FOR_SLOT(slotname, drivername) \
+ (strcmp (slotname, drivername) == 0)
+
+#if NMFB > 0
+ if (DRIVER_FOR_SLOT(name, "PMAG-AA ") &&
+ mfbinit(slotaddr, 0, 1)) {
+ return (1);
+ }
+#endif /* NMFB */
+
+#if NSFB > 0
+ if (DRIVER_FOR_SLOT(name, "PMAGB-BA") &&
+ sfbinit(slotaddr, 0, 1)) {
+ return (1);
+ }
+#endif /* NSFB */
+
+#if NCFB > 0
+ /*"cfb"*/
+ if (DRIVER_FOR_SLOT(name, "PMAG-BA ") &&
+ cfbinit(NULL, slotaddr, 0, 1)) {
+ return (1);
+ }
+#endif /* NCFB */
+ return (0);
+}
+
+
+/* hack for kn03 ioasic */
void
tc_ds_ioasic_intr_setup ()
@@ -399,14 +550,19 @@ tc_ds_ioasic_intr_setup ()
printf("not setting up TC intrs\n");
}
+/*
+ * Estabish an interrupt handler, but on what bus -- TC or ioctl asic?
+ */
void
-tc_ds_ioasic_intr_establish(ca, handler, val)
- struct confargs *ca;
+tc_ds_ioasic_intr_establish(dev, cookie, level, handler, val)
+ struct device *dev;
+ void *cookie;
+ int level;
intr_handler_t handler;
void *val;
{
- int unit = (int) val;
+#ifdef notanymore
if (BUS_MATCHNAME(ca, "IOCTL ")) {
printf("(no interrupt for asic");
return;
@@ -417,23 +573,27 @@ tc_ds_ioasic_intr_establish(ca, handler, val)
printf("(no interrupt for proto-asic)\n");
return;
}
+#endif
+
/* Never tested on these processors */
if (cputype == DS_3MIN || cputype == DS_MAXINE)
- printf("tc_enable %s%d slot %d\n",
- ca->ca_name, (int)unit, ca->ca_slotpri);
+ printf("tc_enable %s sc %x slot %d\n",
+ dev->dv_xname, (int)val, cookie);
#ifdef DIAGNOSTIC
if (tc_enable_interrupt == NULL)
panic("tc_intr_establish: tc_enable not set\n");
#endif
- (*tc_enable_interrupt) (ca->ca_slotpri, handler, (void*)unit, 1);
+ /* Enable interrupt number "cookie" on this CPU */
+ (*tc_enable_interrupt) ((int)cookie, handler, val, 1);
}
void
-tc_ds_ioasic_intr_disestablish(args)
- struct confargs *args;
+tc_ds_ioasic_intr_disestablish(dev, arg)
+ struct device *dev;
+ void *arg;
{
/*(*tc_enable_interrupt) (ca->ca_slot, handler, 0);*/
printf("cannot dis-establish TC intrs\n");
@@ -443,8 +603,6 @@ void
tc_ds_ioasic_iointr (framep, vec)
void * framep;
int vec;
-
-
{
- printf("bogus interrupt handler\n");
+ printf("bogus interrupt handler fp %x vec %d\n", framep, vec);
}