diff options
Diffstat (limited to 'sys/arch/pmax/tc/tc.c')
-rw-r--r-- | sys/arch/pmax/tc/tc.c | 300 |
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); } |