From 59b4da2b39e4ca1d8d8d6e61c623844567c54595 Mon Sep 17 00:00:00 2001 From: briggs Date: Sat, 29 Apr 1995 20:23:36 +0000 Subject: [PATCH] Add new nubus handling that's much more robust. Update via, if_ae, and grf accordingly. Revamp grf. --- sys/arch/mac68k/conf/files.mac68k | 7 +- sys/arch/mac68k/dev/grf.c | 341 +++------ sys/arch/mac68k/dev/grf_iv.c | 101 +++ sys/arch/mac68k/dev/grf_mv.c | 213 ++++++ sys/arch/mac68k/dev/grfvar.h | 98 ++- sys/arch/mac68k/dev/if_ae.c | 162 ++--- sys/arch/mac68k/dev/nubus.c | 1026 ++++++++++++---------------- sys/arch/mac68k/dev/nubus.h | 276 ++++++-- sys/arch/mac68k/include/grfioctl.h | 87 ++- sys/arch/mac68k/mac68k/via.c | 14 +- sys/arch/mac68k/nubus/grf_nubus.c | 213 ++++++ sys/arch/mac68k/nubus/nubus.c | 1026 ++++++++++++---------------- sys/arch/mac68k/nubus/nubus.h | 276 ++++++-- sys/arch/mac68k/obio/grf_obio.c | 101 +++ 14 files changed, 2208 insertions(+), 1733 deletions(-) create mode 100644 sys/arch/mac68k/dev/grf_iv.c create mode 100644 sys/arch/mac68k/dev/grf_mv.c create mode 100644 sys/arch/mac68k/nubus/grf_nubus.c create mode 100644 sys/arch/mac68k/obio/grf_obio.c diff --git a/sys/arch/mac68k/conf/files.mac68k b/sys/arch/mac68k/conf/files.mac68k index 57b124bcf459..eea13f57a409 100644 --- a/sys/arch/mac68k/conf/files.mac68k +++ b/sys/arch/mac68k/conf/files.mac68k @@ -1,8 +1,5 @@ -# $NetBSD: files.mac68k,v 1.31 1995/04/27 12:10:51 christos Exp $ +# $NetBSD: files.mac68k,v 1.32 1995/04/29 20:23:36 briggs Exp $ -# @(#)files.sparc 8.1 (Berkeley) 7/19/93 -# -# files.mac68k.newconf # mac68k-specific configuration info # maxpartitions must be first item in files.${ARCH}.newconf @@ -31,6 +28,8 @@ file arch/mac68k/mac68k/fpu.c fpu device grf at nubus file arch/mac68k/dev/grf.c grf needs-count +file arch/mac68k/dev/grf_mv.c grf +file arch/mac68k/dev/grf_iv.c grf device ite at mainbus file arch/mac68k/dev/ite.c ite needs-flag diff --git a/sys/arch/mac68k/dev/grf.c b/sys/arch/mac68k/dev/grf.c index ca1785f2e81a..9475c5d93107 100644 --- a/sys/arch/mac68k/dev/grf.c +++ b/sys/arch/mac68k/dev/grf.c @@ -1,4 +1,4 @@ -/* $NetBSD: grf.c,v 1.20 1995/04/21 03:44:13 briggs Exp $ */ +/* $NetBSD: grf.c,v 1.21 1995/04/29 20:23:39 briggs Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -79,29 +79,34 @@ #define iteoff(u,f) #endif -static int matchvideocard __P((/*struct device *parent, struct device *dev, +static int grf_match __P((/*struct device *parent, struct device *dev, void *aux*/)); static void grf_attach __P((struct device *parent, struct device *dev, void *aux)); static void fake_internal __P((void)); -static int grfprobe __P((struct nubus_hw *nu, int unit)); -static int macvideo_init __P((struct grf_softc *gp, struct nubus_hw *nu)); -static int macvideo_mode __P((struct grf_softc *gp, int cmd, void *arg)); + +extern int grfmv_probe __P((struct grf_softc *gp, nubus_slot *nu)); +extern int grfmv_init __P((struct grf_softc *gp)); +extern int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); + +extern int grfiv_probe __P((struct grf_softc *gp, nubus_slot *ignore)); +extern int grfiv_init __P((struct grf_softc *gp)); +extern int grfiv_mode __P((struct grf_softc *gp, int cmd, void *arg)); struct cfdriver grfcd = { - NULL, "grf", matchvideocard, grf_attach, DV_DULL, + NULL, "grf", grf_match, grf_attach, DV_DULL, sizeof(struct grf_softc) }; struct grfdev grfdev[] = { - GID_MAC, GRFMAC, macvideo_init, macvideo_mode, "MacVideo", +/* DrSW (*gd_probe)() (*gd_init)() (*gd_mode)() gd_desc */ + NUBUS_DRSW_APPLE, grfmv_probe, grfmv_init, grfmv_mode, "QD-compatible", + 0xFF, grfiv_probe, grfiv_init, grfiv_mode, "Internal video", }; static int ngrfdev=(sizeof(grfdev) / sizeof(grfdev[0])); -static int gNumGrfDev=0; - #ifdef DEBUG static int grfdebug = 0xff; #define GDB_DEVNO 0x01 @@ -110,119 +115,49 @@ static int grfdebug = 0xff; #define GDB_LOCK 0x08 #endif -/* - * Normal init routine called by configure() code - */ -grfprobe(nu, unit) - struct nubus_hw *nu; - int unit; -{ - struct grf_softc *gp; - - gp = grfcd.cd_devs[unit]; - - if ((gp->g_flags & GF_ALIVE) == 0 && !grfinit(nu, unit)) { - printf("\n"); - return (0); - } - printf(": %d x %d ", - gp->g_display.gd_dwidth, gp->g_display.gd_dheight); - - if (gp->g_display.gd_colors == 2) - printf("monochrome"); - else - printf("%d color", gp->g_display.gd_colors); - - printf(" %s (%s) display\n", - grfdev[gp->g_type].gd_desc, nu->slot.name); - - gp->g_data = (void *) &nu->slot; - - return (1); -} - static int -matchvideocard(parent, cf, aux) - struct device *parent; - struct device *cf; - void *aux; +grf_match(parent, match, aux) + struct device *parent; + void *match, *aux; { - struct nubus_hw *nu = (struct nubus_hw *) aux; + struct grf_softc *sc = match; + nubus_slot *nu = (nubus_slot *) aux; + int i, r; - return (nu->slot.type == NUBUS_VIDEO); + for (i = 0; i < ngrfdev; i++) { + if ((r = (*grfdev[i].gd_probe)(sc, nu)) > 0) { + sc->g_type = i; + bcopy(aux, &sc->sc_slot, sizeof(nubus_slot)); + return r; + } + } + return 0; } static void -grf_attach(parent, dev, aux) - struct device *parent, *dev; +grf_attach(parent, self, aux) + struct device *parent, *self; void *aux; { - struct nubus_hw *nu = (struct nubus_hw *) aux; + struct grf_softc *sc; - grfprobe(nu, dev->dv_unit); -} + sc = (struct grf_softc *) self; -int -grfinit(nu, unit) - struct nubus_hw *nu; - int unit; -{ - struct grf_softc *gp; - struct grfreg *gr; - register struct grfdev *gd; - - gp = grfcd.cd_devs[unit]; - - for (gd = grfdev; gd < &grfdev[ngrfdev]; gd++) - /* if (gd->gd_hardid == gr->gr_id2) */ - break; - if (gd < &grfdev[ngrfdev] && (*gd->gd_init) (gp, nu)) { - gp->g_display.gd_id = gd->gd_softid; - gp->g_type = gd - grfdev; - gp->g_flags = GF_ALIVE; - return (1); - } - return (0); -} - -static void -fake_internal() -{ - extern unsigned long int_video_start; - struct grf_softc *gp; - struct grfinfo *gi; - struct grfterm *gt; - struct grfmouse *gm; - int i, j; - - if (int_video_start == 0) { + if ((*grfdev[sc->g_type].gd_init)(sc) == 0) { + printf("\n"); return; } - for (i = 0; i < NGRF; i++) { - gp = grfcd.cd_devs[i]; - if ((gp->g_flags & GF_ALIVE) == 0) { - break; - } - } + sc->g_flags = GF_ALIVE; - if (i == NGRF) { - printf("grf: not enough grf's to map internal video.\n"); - return; - } - gp->g_type = 0; - gp->g_flags = GF_ALIVE; + printf(": %d x %d ", sc->curr_mode.width, sc->curr_mode.height); - gi = &(gp->g_display); - gi->gd_id = GRFMAC; - gi->gd_regsize = 0; - gi->gd_colors = 1; - gi->gd_planes = 1; - gi->gd_dwidth = gi->gd_fbwidth = 640; /* XXX */ - gi->gd_dheight = gi->gd_fbheight = 480; /* XXX */ - gi->gd_fbsize = gi->gd_dwidth * gi->gd_dheight; - gi->gd_fbrowbytes = 80; /* XXX Hack */ - gi->gd_fbaddr = (caddr_t) 0; - gp->g_fbkva = gi->gd_fbaddr; + if (sc->curr_mode.psize == 1) + printf("monochrome"); + else + printf("%d color", 1 << sc->curr_mode.psize); + + printf(" %s (%s) display\n", + grfdev[sc->g_type].gd_desc, sc->card_name); } /*ARGSUSED*/ @@ -233,19 +168,14 @@ grfopen(dev, flag, mode, p) int mode; struct proc *p; { - static int faked; /* Whether we've faked internal video yet */ register struct grf_softc *gp; int unit; int error; unit = GRFUNIT(dev); gp = grfcd.cd_devs[unit]; - if (!faked) { - fake_internal(); - faked = 1; - } - if (unit >= NGRF || (gp->g_flags & GF_ALIVE) == 0) + if (unit >= grfcd.cd_ndevs || (gp->g_flags & GF_ALIVE) == 0) return (ENXIO); if ((gp->g_flags & (GF_OPEN | GF_EXCLUDE)) == (GF_OPEN | GF_EXCLUDE)) @@ -275,7 +205,6 @@ grfclose(dev, flag, mode, p) gp = grfcd.cd_devs[GRFUNIT(dev)]; (void) grfoff(dev); - (void) grfunlock(gp); gp->g_flags &= GF_ALIVE; return (0); @@ -291,17 +220,28 @@ grfioctl(dev, cmd, data, flag, p) { register struct grf_softc *gp; int error; + int unit = GRFUNIT(dev); - gp = grfcd.cd_devs[GRFUNIT(dev)]; + gp = grfcd.cd_devs[unit]; error = 0; switch (cmd) { - case OGRFIOCGINFO: - bcopy((caddr_t) & gp->g_display, data, sizeof(struct ogrfinfo)); - break; - case GRFIOCGINFO: - bcopy((caddr_t) & gp->g_display, data, sizeof(struct grfinfo)); + case GRFIOCGINFO: /* XXX - This should go away as soon as X and */ + /* dt are fixed to use GRFIOC*MODE* */ + { struct grfinfo *g; + g = (struct grfinfo *) data; + bzero(data, sizeof(struct grfinfo)); + g->gd_id = gp->curr_mode.mode_id; + g->gd_fbaddr = gp->curr_mode.fbbase; + g->gd_fbsize = gp->curr_mode.fbsize; + g->gd_colors = 1 << (u_int32_t) gp->curr_mode.psize; + g->gd_planes = gp->curr_mode.psize; + g->gd_fbwidth = g->gd_dwidth = gp->curr_mode.width; + g->gd_fbheight = g->gd_dheight = gp->curr_mode.height; + g->gd_fbrowbytes = gp->curr_mode.rowbytes; + } break; + case GRFIOCON: error = grfon(dev); break; @@ -314,6 +254,17 @@ grfioctl(dev, cmd, data, flag, p) case GRFIOCUNMAP: error = grfunmap(dev, *(caddr_t *) data, p); break; + + case GRFIOCGETMODE: + error = (*grfdev[gp->g_type].gd_mode)(gp, GM_CURRMODE, data); + break; + case GRFIOCSETMODE: + error = (*grfdev[gp->g_type].gd_mode)(gp, GM_NEWMODE, data); + break; + case GRFIOCLISTMODES: + error = (*grfdev[gp->g_type].gd_mode)(gp, GM_LISTMODES, data); + break; + default: error = EINVAL; break; @@ -332,59 +283,6 @@ grfselect(dev, rw, p) return (1); } -int -grflock(gp, block) - register struct grf_softc *gp; - int block; -{ - extern char devioc[]; - struct proc *p = curproc; /* XXX */ - int error; - -#ifdef DEBUG - if (grfdebug & GDB_LOCK) - printf("grflock(%d): dev %x flags %x lockpid %x\n", - p->p_pid, gp->sc_dev.dv_unit, gp->g_flags, - gp->g_lockp ? gp->g_lockp->p_pid : -1); -#endif - if (gp->g_lockp) { - if (gp->g_lockp == p) - return (EBUSY); - if (!block) - return (EAGAIN); - do { - gp->g_flags |= GF_WANTED; - if (error = tsleep((caddr_t) & gp->g_flags, - (PZERO + 1) | PCATCH, devioc, 0)) - return (error); - } while (gp->g_lockp); - } - gp->g_lockp = p; - return (0); -} - -int -grfunlock(gp) - register struct grf_softc *gp; -{ -#ifdef DEBUG - if (grfdebug & GDB_LOCK) - printf("grfunlock(%d): dev %x flags %x lockpid %d\n", - curproc->p_pid, gp->sc_dev.dv_unit, gp->g_flags, - gp->g_lockp ? gp->g_lockp->p_pid : -1); -#endif - if (gp->g_lockp != curproc) - return (EBUSY); - - if (gp->g_flags & GF_WANTED) { - wakeup((caddr_t) & gp->g_flags); - gp->g_flags &= ~GF_WANTED; - } - gp->g_lockp = NULL; - - return (0); -} - /*ARGSUSED*/ grfmmap(dev, off, prot) dev_t dev; @@ -402,14 +300,15 @@ grfon(dev) struct grf_softc *gp; gp = grfcd.cd_devs[unit]; + /* * XXX: iteoff call relies on devices being in same order * as ITEs and the fact that iteoff only uses the minor part * of the dev arg. */ iteoff(unit, 3); - return ((*grfdev[gp->g_type].gd_mode) - (gp, (dev & GRFOVDEV) ? GM_GRFOVON : GM_GRFON)); + + return (*grfdev[gp->g_type].gd_mode) (gp, GM_GRFON, NULL); } int @@ -421,11 +320,14 @@ grfoff(dev) int error; gp = grfcd.cd_devs[unit]; + (void) grfunmap(dev, (caddr_t) 0, curproc); - error = (*grfdev[gp->g_type].gd_mode) - (gp, (dev & GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF); + + error = (*grfdev[gp->g_type].gd_mode) (gp, GM_GRFOFF, NULL); + /* XXX: see comment for iteoff above */ iteon(unit, 2); + return (error); } @@ -434,16 +336,10 @@ grfaddr(gp, off) struct grf_softc *gp; register int off; { - register struct grfinfo *gi = &gp->g_display; + register struct grfmode *gm = &gp->curr_mode; - /* control registers */ - if (off >= 0 && off < gi->gd_regsize) - return (((u_int) gi->gd_regaddr + off) >> PGSHIFT); - - /* frame buffer */ - if (off >= gi->gd_regsize && off < gi->gd_regsize + gi->gd_fbsize) { - off -= gi->gd_regsize; - return (((u_int) gi->gd_fbaddr + off) >> PGSHIFT); + if (off < gm->fbsize) { + return (((u_int) gm->fbbase + off) >> PGSHIFT); } /* bogus */ return (-1); @@ -456,17 +352,17 @@ grfmap(dev, addrp, p) struct proc *p; { struct grf_softc *gp; - int len, error; - struct vnode vn; struct specinfo si; - int flags; + struct vnode vn; + int len, error; + int flags; gp = grfcd.cd_devs[GRFUNIT(dev)]; #ifdef DEBUG if (grfdebug & GDB_MMAP) printf("grfmap(%d): addr %x\n", p->p_pid, *addrp); #endif - len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; + len = gp->curr_mode.fbsize; flags = MAP_SHARED; if (*addrp) flags |= MAP_FIXED; @@ -483,7 +379,7 @@ grfmap(dev, addrp, p) 0); /* Offset into page: */ - *addrp += (unsigned long) gp->g_display.gd_fbaddr & 0xfff; + *addrp += (unsigned long) gp->curr_mode.fbbase & 0xfff; return (error); } @@ -499,67 +395,18 @@ grfunmap(dev, addr, p) int rv; gp = grfcd.cd_devs[GRFUNIT(dev)]; + #ifdef DEBUG if (grfdebug & GDB_MMAP) printf("grfunmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); #endif + if (addr == 0) return (EINVAL);/* XXX: how do we deal with this? */ - size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); + + size = round_page(gp->curr_mode.fbsize); + rv = vm_deallocate(&p->p_vmspace->vm_map, (vm_offset_t) addr, size); + return (rv == KERN_SUCCESS ? 0 : EINVAL); } - -static char zero = 0; - -static void -macvideo_intr(unit, slot) - int unit, slot; -{ - struct grf_softc *gp; - - ((char *) (0xf0000000 | ((long) slot << 24)))[0xa0000] = zero; -} - -static int -macvideo_init(gp, nu) - struct grf_softc *gp; - struct nubus_hw *nu; -{ - struct grfinfo *gi; - struct imagedata *image; - struct imagedata imageSpace; - int i = 0; - - /* - * find out which nubus slot this guy is in, then get the video params - */ - image = (struct imagedata *) NUBUS_GetImageData(&(nu->slot), &imageSpace); - - gi = &(gp->g_display); - gi->gd_regsize = 0; - gi->gd_colors = 1; - gi->gd_planes = 1; - gi->gd_dwidth = gi->gd_fbwidth = image->right; - gi->gd_dheight = gi->gd_fbheight = image->bottom; - gi->gd_fbsize = image->rowbytes * image->bottom; - gi->gd_fbrowbytes = image->rowbytes; - gi->gd_fbaddr = (caddr_t) ((u_long) image->offset + (u_long) nu->addr); - gp->g_fbkva = gi->gd_fbaddr; - - add_nubus_intr((unsigned int) nu->addr & 0xFF000000, macvideo_intr, - (gp->sc_dev.dv_unit)); - - gNumGrfDev++; - - return 1; -} - -static int -macvideo_mode(gp, cmd, arg) - struct grf_softc *gp; - int cmd; - void *arg; -{ - return 0; -} diff --git a/sys/arch/mac68k/dev/grf_iv.c b/sys/arch/mac68k/dev/grf_iv.c new file mode 100644 index 000000000000..f6419a620aea --- /dev/null +++ b/sys/arch/mac68k/dev/grf_iv.c @@ -0,0 +1,101 @@ +/* $NetBSD: grf_iv.c,v 1.1 1995/04/29 20:23:41 briggs Exp $ */ + +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Graphics display driver for the Macintosh internal video for machines + * that don't map it into a fake nubus card. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nubus.h" +#include "grfvar.h" + +extern int grfiv_probe __P((struct grf_softc *sc, nubus_slot *ignore)); +extern int grfiv_init __P((struct grf_softc *sc)); +extern int grfiv_mode __P((struct grf_softc *sc, int cmd, void *arg)); + +extern int +grfiv_probe(sc, ignore) + struct grf_softc *sc; + nubus_slot *ignore; +{ + extern unsigned long int_video_start; + + if (int_video_start == 0) { + return 0; + } + return 1; +} + +extern int +grfiv_init(sc) + struct grf_softc *sc; +{ + struct grfmode *gm; + int i, j; + + sc->card_id = 0; + + strcpy(sc->card_name, "Internal video"); + + gm = &(sc->curr_mode); + gm->mode_id = 0; + gm->psize = 1; + gm->ptype = 0; + gm->width = 640; /* XXX */ + gm->height = 480; /* XXX */ + gm->rowbytes = 80; /* XXX Hack */ + gm->hres = 80; /* XXX Hack */ + gm->vres = 80; /* XXX Hack */ + gm->fbsize = gm->width * gm->height; + gm->fbbase = (caddr_t) 0; + + return 1; +} + +extern int +grfiv_mode(sc, cmd, arg) + struct grf_softc *sc; + int cmd; + void *arg; +{ + return 0; +} diff --git a/sys/arch/mac68k/dev/grf_mv.c b/sys/arch/mac68k/dev/grf_mv.c new file mode 100644 index 000000000000..184418783283 --- /dev/null +++ b/sys/arch/mac68k/dev/grf_mv.c @@ -0,0 +1,213 @@ +/* $NetBSD: grf_mv.c,v 1.1 1995/04/29 20:23:42 briggs Exp $ */ + +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Device-specific routines for handling Nubus-based video cards. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nubus.h" +#include "grfvar.h" + +extern int grfmv_probe __P((struct grf_softc *gp, nubus_slot *slot)); +extern int grfmv_init __P((struct grf_softc *gp)); +extern int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); + +static char zero = 0; + +static void +load_image_data(data, image) + caddr_t data; + struct image_data *image; +{ + bcopy(data , &image->size, 4); + bcopy(data + 4, &image->offset, 4); + bcopy(data + 8, &image->rowbytes, 2); + bcopy(data + 10, &image->top, 2); + bcopy(data + 12, &image->left, 2); + bcopy(data + 14, &image->bottom, 2); + bcopy(data + 16, &image->right, 2); + bcopy(data + 18, &image->version, 2); + bcopy(data + 20, &image->packType, 2); + bcopy(data + 22, &image->packSize, 4); + bcopy(data + 26, &image->hRes, 4); + bcopy(data + 30, &image->vRes, 4); + bcopy(data + 34, &image->pixelType, 2); + bcopy(data + 36, &image->pixelSize, 2); + bcopy(data + 38, &image->cmpCount, 2); + bcopy(data + 40, &image->cmpSize, 2); + bcopy(data + 42, &image->planeBytes, 4); +} + +static void +grfmv_intr(sc, slot) + struct grf_softc *sc; + int slot; +{ + struct grf_softc *gp; + + ((char *) (((u_long) (0xf0 | slot)) << 24))[0xa0000] = zero; +} + +extern int +grfmv_probe(sc, slot) + struct grf_softc *sc; + nubus_slot *slot; +{ + nubus_dir dir, *dirp, dir2, *dirp2; + nubus_dirent dirent, *direntp; + nubus_type slottype; + + dirp = &dir; + direntp = &dirent; + nubus_get_main_dir(slot, dirp); + + /* + * Unfortunately, I think we'll have to load this value from + * the macos. The alternative is putting in enough hooks to + * be able to call the card's PrimaryInit routine which could + * call just about any part of the ROM, I think. + */ + if (nubus_find_rsrc(slot, dirp, 128, direntp) <= 0) { + if (nubus_find_rsrc(slot, dirp, 129, direntp) <= 0) { + return 0; + } + } + + dirp2 = (nubus_dir *) &sc->board_dir; + nubus_get_dir_from_rsrc(slot, direntp, dirp2); + + if (nubus_find_rsrc(slot, dirp2, NUBUS_RSRC_TYPE, direntp) <= 0) + /* Type is a required entry... This should never happen. */ + return 0; + + if (nubus_get_ind_data(slot, direntp, + (caddr_t) &slottype, sizeof(nubus_type)) <= 0) + return 0; + + if (slottype.category != NUBUS_CATEGORY_DISPLAY) + return 0; + + if (slottype.type != NUBUS_TYPE_VIDEO) + return 0; + + if (slottype.drsw != NUBUS_DRSW_APPLE) + return 0; + + /* + * If we've gotten this far, then we're dealing with a real-live + * Apple QuickDraw-compatible display card resource. Now, how to + * determine that this is an active resource??? Dunno. But we'll + * proceed like it is. + */ + + sc->card_id = slottype.drhw; +printf("card id = 0x%x.\n", sc->card_id); + + /* Need to load display info (and driver?), etc... */ + + return 1; +} + +extern int +grfmv_init(sc) + struct grf_softc *sc; +{ + struct image_data image_store, image; + nubus_dirent dirent; + nubus_dir mode_dir; + int mode; + u_long base; + + mode = NUBUS_RSRC_FIRSTMODE; + if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) + return 0; + + nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir); + + if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) <= 0) + return 0; + + if (nubus_get_ind_data(&sc->sc_slot, &dirent, (caddr_t) &image_store, + sizeof(struct image_data)) <= 0) + return 0; + + load_image_data((caddr_t) &image_store, &image); + + base = NUBUS_SLOT_TO_BASE(sc->sc_slot.slot); + + sc->curr_mode.mode_id = mode; + sc->curr_mode.fbbase = (caddr_t) (base + image.offset); + sc->curr_mode.rowbytes = image.rowbytes; + sc->curr_mode.width = image.right - image.left; + sc->curr_mode.height = image.bottom - image.top; + sc->curr_mode.fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes; + sc->curr_mode.hres = image.hRes; + sc->curr_mode.vres = image.vRes; + sc->curr_mode.ptype = image.pixelType; + sc->curr_mode.psize = image.pixelSize; + + strncpy(sc->card_name, nubus_get_card_name(&sc->sc_slot), + CARD_NAME_LEN); + + sc->card_name[CARD_NAME_LEN-1] = '\0'; + + add_nubus_intr(sc->sc_slot.slot, grfmv_intr, sc); + + return 1; +} + +extern int +grfmv_mode(gp, cmd, arg) + struct grf_softc *gp; + int cmd; + void *arg; +{ + switch (cmd) { + case GM_CURRMODE: + break; + case GM_NEWMODE: + break; + case GM_LISTMODES: + break; + } + return EINVAL; +} diff --git a/sys/arch/mac68k/dev/grfvar.h b/sys/arch/mac68k/dev/grfvar.h index 1df08474b80d..93bbfcf779a9 100644 --- a/sys/arch/mac68k/dev/grfvar.h +++ b/sys/arch/mac68k/dev/grfvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: grfvar.h,v 1.6 1995/04/21 03:44:19 briggs Exp $ */ +/* $NetBSD: grfvar.h,v 1.7 1995/04/29 20:23:43 briggs Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -42,27 +42,19 @@ * @(#)grfvar.h 7.3 (Berkeley) 5/7/91 */ -/* internal structure of lock page */ -#define GRFMAXLCK 256 -struct grf_lockpage { - u_char gl_locks[GRFMAXLCK]; -}; -#define gl_lockslot gl_locks[0] - +#define CARD_NAME_LEN 64 /* per display info */ struct grf_softc { - struct device sc_dev; + struct device sc_dev; + nubus_slot sc_slot; - int g_flags; /* software flags */ - int g_type; /* type of display */ - caddr_t g_regkva; /* KVA of registers */ - caddr_t g_fbkva; /* KVA of framebuffer */ - struct grfinfo g_display; /* hardware description (for ioctl) */ - struct grf_lockpage *g_lock; /* lock page associated with device */ - struct proc *g_lockp; /* process holding lock */ - short *g_pid; /* array of pids with device open */ - int g_lockpslot; /* g_pid entry of g_lockp */ - caddr_t g_data; /* device dependent data */ + char card_name[CARD_NAME_LEN]; + struct grfmode curr_mode; /* hardware desc(for ioctl) */ + u_int32_t g_flags; /* software flags */ + u_int32_t g_type; /* index into grfdev */ + u_int16_t card_id; /* DrHW value for nubus cards */ + nubus_dir board_dir; /* Nubus dir for curr board */ + caddr_t g_data; /* device dependent data */ }; /* flags */ @@ -74,47 +66,53 @@ struct grf_softc { #define GF_HPUXOPEN 0x20 /* display types - indices into grfdev */ -#define GT_MAC 0 +#define GT_MACVIDEO 0 +#define GT_INTERNALVIDEO 1 struct grfdev { - int gd_hardid; /* secondary id returned by hardware */ - int gd_softid; /* id returned by HP-UX */ + int gd_softid; /* DrSW */ + int (*gd_probe)(); /* probe routine */ int (*gd_init) (); /* boot time initialization */ - int (*gd_mode) (); /* misc functions */ + int (*gd_mode) (); /* mode-change on/off/mode function */ char *gd_desc; /* text description */ }; -/* hardware ids */ -#define GID_MAC 1 - -/* software ids defined in grfioctl.h */ /* requests to mode routine */ #define GM_GRFON 1 #define GM_GRFOFF 2 -#define GM_GRFOVON 3 -#define GM_GRFOVOFF 4 - -struct grfreg { - char gr_pad0; - u_char gr_id; /* +0x01 */ - char gr_pad1[0x13]; - u_char gr_id2; /* +0x15 */ - char gr_pad2[0x47]; - u_char gr_fbomsb; /* +0x5d */ - char gr_pad3; - u_char gr_fbolsb; /* +0x5f */ -}; -/* bitmapped display hardware id */ -#define GRFHWID 0x39 - -/* internal bitmapped display address */ -#define GRFIADDR 0x560000 +#define GM_CURRMODE 3 +#define GM_LISTMODES 4 +#define GM_NEWMODE 5 /* minor device interpretation */ -#define GRFOVDEV 0x10 /* overlay planes */ -#define GRFIMDEV 0x20 /* images planes */ #define GRFUNIT(d) ((d) & 0x7) -#ifdef _KERNEL -extern struct grf_softc grf_softc[]; -#endif /* _KERNEL */ +/* + * Nubus image data structure. This is the equivalent of a PixMap in + * MacOS programming parlance. One of these structures exists for each + * video mode that a quickdraw compatible card can fit in. + */ +struct image_data { + u_int32_t size; + u_int32_t offset; + u_int16_t rowbytes; + u_int16_t top; + u_int16_t left; + u_int16_t bottom; + u_int16_t right; + u_int16_t version; + u_int16_t packType; + u_int32_t packSize; + u_int32_t hRes; + u_int32_t vRes; + u_int16_t pixelType; + u_int16_t pixelSize; + u_int16_t cmpCount; + u_int16_t cmpSize; + u_int32_t planeBytes; +}; + +#define VID_PARAMS 1 +#define VID_TABLE_OFFSET 2 +#define VID_PAGE_CNT 3 +#define VID_DEV_TYPE 4 diff --git a/sys/arch/mac68k/dev/if_ae.c b/sys/arch/mac68k/dev/if_ae.c index 9273385866af..d1429487d362 100644 --- a/sys/arch/mac68k/dev/if_ae.c +++ b/sys/arch/mac68k/dev/if_ae.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ae.c,v 1.27 1995/04/22 12:08:12 briggs Exp $ */ +/* $NetBSD: if_ae.c,v 1.28 1995/04/29 20:23:44 briggs Exp $ */ /* * Device driver for National Semiconductor DS8390/WD83C690 based ethernet @@ -61,20 +61,22 @@ #include #include "if_aereg.h" +#define INTERFACE_NAME_LEN 32 + /* * ae_softc: per line info and status */ struct ae_softc { - struct device sc_dev; -/* struct nubusdev sc_nu; - struct intrhand sc_ih; */ + struct device sc_dev; + nubus_slot sc_slot; +/* struct intrhand sc_ih; */ struct arpcom sc_arpcom;/* ethernet common */ - char *type_str; /* pointer to type string */ - u_char vendor; /* interface vendor */ - u_char type; /* interface type code */ - u_char regs_rev; /* registers are reversed */ + char type_str[INTERFACE_NAME_LEN]; /* type string */ + u_short type; /* interface type code */ + u_char vendor; /* interface vendor */ + u_char regs_rev; /* registers are reversed */ #define REG_MAP(sc, reg) ((sc)->regs_rev ? (0x0f-(reg))<<2 : (reg)<<2) #define NIC_GET(sc, reg) ((sc)->nic_addr[REG_MAP(sc, reg)]) @@ -121,45 +123,19 @@ u_short ae_put __P((struct ae_softc *, struct mbuf *, caddr_t)); void ae_get_packet __P(( /* struct ae_softc *, caddr_t, u_short */ )); static inline void ae_rint __P((struct ae_softc *)); static inline void ae_xmit __P((struct ae_softc *)); -static inline caddr_t ae_ring_copy -__P(( /* struct ae_softc *, caddr_t, caddr_t, - u_short */ )); +static inline caddr_t ae_ring_copy __P(( + /* struct ae_softc *, caddr_t, caddr_t, u_short */ )); + +struct cfdriver aecd = { + NULL, "ae", aeprobe, aeattach, DV_IFNET, sizeof(struct ae_softc) +}; - struct cfdriver aecd = { - NULL, "ae", aeprobe, aeattach, DV_IFNET, sizeof(struct ae_softc) - }; #define ETHER_MIN_LEN 64 #define ETHER_MAX_LEN 1518 #define ETHER_ADDR_LEN 6 - char ae_name[] = "8390 Nubus Ethernet card"; - static char zero = 0; - static u_char ones = 0xff; - - struct vendor_S { - char *manu; - int len; - int vendor; - } vend[] = -{ - { - "Apple", 5, AE_VENDOR_APPLE - }, - { - "3Com", 4, AE_VENDOR_APPLE - }, - { - "Dayna", 5, AE_VENDOR_DAYNA - }, - { - "Inter", 5, AE_VENDOR_INTERLAN - }, - { - "Asant", 5, AE_VENDOR_ASANTE - }, -}; - -static int numvend = sizeof(vend) / sizeof(vend[0]); +static char zero = 0; +static u_char ones = 0xff; /* * XXX These two should be moved to locore, and maybe changed to use shorts @@ -200,25 +176,59 @@ byte_copy(a, b, len) *b++ = *a++; } -void -ae_id_card(nu, sc) - struct nubus_hw *nu; +static int +ae_id_card(slot, sc) + nubus_slot *slot; struct ae_softc *sc; { - int i; + nubus_dir dir; + nubus_dirent dirent; + nubus_type slottype; - /* - * Try to determine what type of card this is... - */ - sc->vendor = AE_VENDOR_UNKNOWN; - for (i = 0; i < numvend; i++) { - if (!strncmp(nu->slot.manufacturer, vend[i].manu, vend[i].len)) { - sc->vendor = vend[i].vendor; - break; - } + nubus_get_main_dir(slot, &dir); + + if (nubus_find_rsrc(slot, &dir, 0x80, &dirent) <= 0) + return 0; + + nubus_get_dir_from_rsrc(slot, &dirent, &dir); + + if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_TYPE, &dirent) <= 0) + return 0; + + if (nubus_get_ind_data(slot, &dirent, + (caddr_t) &slottype, sizeof(nubus_type)) <= 0) + return 0; + + if (slottype.category != NUBUS_CATEGORY_NETWORK) + return 0; + + if (slottype.type != NUBUS_TYPE_ETHERNET) + return 0; + + switch (slottype.type) { + case NUBUS_DRSW_3COM: + case NUBUS_DRSW_APPLE: + sc->vendor = AE_VENDOR_APPLE; + break; + case NUBUS_DRSW_ASANTE: + sc->vendor = AE_VENDOR_ASANTE; + break; + case NUBUS_DRSW_DAYNA: + sc->vendor = AE_VENDOR_DAYNA; + break; + case NUBUS_DRSW_INTERLAN: + sc->vendor = AE_VENDOR_INTERLAN; + break; + default: + sc->vendor = AE_VENDOR_UNKNOWN; + return 0; } - sc->type_str = (char *) (nu->slot.manufacturer); + strncpy(sc->type_str, nubus_get_card_name(slot), INTERFACE_NAME_LEN); + + sc->type_str[INTERFACE_NAME_LEN-1] = '\0'; + + return 1; } int @@ -266,28 +276,29 @@ aeprobe(parent, match, aux) void *match, *aux; { struct ae_softc *sc = match; - register struct nubus_hw *nu = aux; + nubus_slot *nu = (nubus_slot *) aux; + caddr_t addr; int i, memsize; int flags = 0; - if (nu->slot.type != NUBUS_NETWORK) + if (ae_id_card(nu, sc) < 0) return 0; - ae_id_card(nu, sc); - sc->regs_rev = 0; sc->mem_wr_short = 0; + addr = (caddr_t) NUBUS_SLOT_TO_BASE(nu->slot); + switch (sc->vendor) { case AE_VENDOR_INTERLAN: - sc->nic_addr = nu->addr + GC_NIC_OFFSET; - sc->rom_addr = nu->addr + GC_ROM_OFFSET; - sc->mem_start = nu->addr + GC_DATA_OFFSET; + sc->nic_addr = addr + GC_NIC_OFFSET; + sc->rom_addr = addr + GC_ROM_OFFSET; + sc->mem_start = addr + GC_DATA_OFFSET; if ((memsize = ae_size_card_memory(sc)) == 0) return 0; /* reset the NIC chip */ - *((caddr_t) nu->addr + GC_RESET_OFFSET) = (char) zero; + *((caddr_t) addr + GC_RESET_OFFSET) = (char) zero; /* Get station address from on-board ROM */ for (i = 0; i < ETHER_ADDR_LEN; ++i) @@ -301,9 +312,9 @@ aeprobe(parent, match, aux) case AE_VENDOR_APPLE: sc->regs_rev = 1; - sc->nic_addr = nu->addr + AE_NIC_OFFSET; - sc->rom_addr = nu->addr + AE_ROM_OFFSET; - sc->mem_start = nu->addr + AE_DATA_OFFSET; + sc->nic_addr = addr + AE_NIC_OFFSET; + sc->rom_addr = addr + AE_ROM_OFFSET; + sc->mem_start = addr + AE_DATA_OFFSET; if ((memsize = ae_size_card_memory(sc)) == 0) return (0); @@ -314,9 +325,9 @@ aeprobe(parent, match, aux) case AE_VENDOR_DAYNA: printf("We think we are a Dayna card, but "); - sc->nic_addr = nu->addr + DP_NIC_OFFSET; - sc->rom_addr = nu->addr + DP_ROM_OFFSET; - sc->mem_start = nu->addr + DP_DATA_OFFSET; + sc->nic_addr = addr + DP_NIC_OFFSET; + sc->rom_addr = addr + DP_ROM_OFFSET; + sc->mem_start = addr + DP_DATA_OFFSET; memsize = 8192; /* Get station address from on-board ROM */ @@ -356,6 +367,8 @@ aeprobe(parent, match, aux) sc->mem_start + i); return (0); } + + bcopy(nu, &sc->sc_slot, sizeof(nubus_slot)); return (1); } /* @@ -390,19 +403,14 @@ aeattach(parent, self, aux) /* Print additional info when attached. */ printf(": address %s, ", ether_sprintf(sc->sc_arpcom.ac_enaddr)); - if (sc->type_str && (*sc->type_str != 0)) - printf("type %s", sc->type_str); - else - printf("type unknown (0x%x)", sc->type); - - printf(", %dk mem.\n", sc->mem_size / 1024); + printf("type %s, %dk mem.\n", sc->type_str, sc->mem_size / 1024); #if NBPFILTER > 0 bpfattach(&ifp->if_bpf, ifp, DLT_EN10MB, sizeof(struct ether_header)); #endif /* make sure interrupts are vectored to us */ - add_nubus_intr((int) sc->rom_addr & 0xFF000000, aeintr, sc); + add_nubus_intr(sc->sc_slot.slot, aeintr, sc); /* * XXX -- enable nubus interrupts here. Should be done elsewhere, diff --git a/sys/arch/mac68k/dev/nubus.c b/sys/arch/mac68k/dev/nubus.c index 9701bddf1363..afd99b69fe8a 100644 --- a/sys/arch/mac68k/dev/nubus.c +++ b/sys/arch/mac68k/dev/nubus.c @@ -1,10 +1,7 @@ -/* $NetBSD: nubus.c,v 1.10 1995/04/21 02:47:59 briggs Exp $ */ +/* $NetBSD: nubus.c,v 1.11 1995/04/29 20:23:46 briggs Exp $ */ -/*- - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * All rights reserved. +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -16,21 +13,20 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -41,595 +37,469 @@ #include "nubus.h" -static struct dir *getRsrcByNum __P((struct slot *slot, struct dir *p, - int num, struct dir *out, int max)); -static int print_rsrcinfo __P((struct slot *slot, struct dir *p)); -static char *GetStringInfo __P((struct slot *slot, u_char *data1, - char *space, int len)); -static int printTree __P((struct slot *slot, struct dir *root)); -static long GetLongInfo __P((struct slot *slot, u_char *data)); -static int FindMagic __P((u_long *data)); -static int GetHeader __P((struct slot *slot, u_long pos)); -static u_char *IncPtr __P((struct slot *slot, u_char *p, int size)); -static char GetByteInfo __P((struct slot *slot, u_char *data)); -static int GetRsrcs __P((struct slot *slot, u_char *p, - struct dir *dir, int maxdir)); -static u_char *getDataAtRsrc __P((struct slot *slot, struct dir *p, int num)); -static short GetShortInfo __P((struct slot *slot, u_char *data)); - -static int -GetHeader(slot, pos) - struct slot *slot; - u_long pos; -{ - /* the pos passed in is the pos that the magic testvalue was found at */ - u_char *p; - u_char *dirBase; - - switch (slot->size) { - case 1: /* char */ - pos -= 14; - break; - case 2: - pos -= 28; - break; - case 4: - pos -= 56; - break; - } - - p = (u_char *) pos; - - slot->head.offset = (0xff000000 | (u_long) GetLongInfo(slot, p)); - p = IncPtr(slot, p, 4); - - slot->head.length = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.crc = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.romrev = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - slot->head.format = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - slot->head.tst = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.reserved = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - -/* byte lanes should be used instead of size, this hasn't bitten me yet */ - slot->head.bytelane = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - dirBase = (u_char *) (pos + slot->head.offset * slot->size); - GetRsrcs(slot, dirBase, slot->mainDir, 15); - return 0; -} - -static int -printTree(slot, root) - struct slot *slot; - struct dir *root; -{ - struct dir *b; - u_char *c; - struct dir *d; - u_char *e; - struct dir *f; - u_char *g; - struct dir *h; - u_char *i; - u_char *j; - u_char *k; - struct dir bSpace[15]; - struct dir cSpace[15]; - struct dir dSpace[15]; - struct dir fSpace[15]; - struct dir hSpace[15]; - char space[40]; -/* to get a good idea of what is happening here you should get the -"slots" program from apple dts, it is so cool. Its the next -best thing to actual docs, which i didn't have... -*/ - - b = getRsrcByNum(slot, root, 1, bSpace, 15); - c = getDataAtRsrc(slot, b, 2); - d = getRsrcByNum(slot, b, 0x24, dSpace, 15); - - e = getDataAtRsrc(slot, d, 1); - - f = getRsrcByNum(slot, root, 0x80, fSpace, 15); - g = getDataAtRsrc(slot, f, 2); - j = getDataAtRsrc(slot, f, 0x0a); - k = getDataAtRsrc(slot, f, 0x0b); - - h = getRsrcByNum(slot, root, 0xa0, hSpace, 15); - i = getDataAtRsrc(slot, h, 2); - - printf("A\n"); - print_rsrcinfo(slot, root); - - printf("B\n"); - print_rsrcinfo(slot, b); - - printf("C\n"); - printf("%s\n", GetStringInfo(slot, c, space, 40)); - - printf("D\n"); - print_rsrcinfo(slot, d); - - printf("E\n"); - printf("%s\n", GetStringInfo(slot, e, space, 40)); - - printf("F\n"); - print_rsrcinfo(slot, f); - - printf("g\n"); - printf("%s\n", GetStringInfo(slot, g, space, 40)); - printf("Video RAM Base %lx\n", GetLongInfo(slot, j)); - printf("Video RAM Length %lx\n", GetLongInfo(slot, k)); - - printf("H\n"); - print_rsrcinfo(slot, h); - - printf("I\n"); - printf("%s\n", GetStringInfo(slot, i, space, 40)); -} - -static int -print_rsrcinfo(slot, p) - struct slot *slot; - struct dir *p; -{ - int i = 0; - int failsafe = 20; - - if (p == NULL) - return 1; - while (failsafe--) { - printf("RSRC %02x :%06lx\n", p[i].rsrc, p[i].offset); - if (p[i].rsrc == 0xff) - break; - i++; - } - -} - -static struct dir * -getRsrcByNum(slot, p, num, out, max) - struct slot *slot; - struct dir *p; - int num; - struct dir *out; - int max; -{ - int i = 0; - int failsafe = 20; - long nextoffset = 0; - u_char *base; - - if (p == NULL) - return NULL; - - - base = getDataAtRsrc(slot, p, num); - - if (NULL == base) - return NULL; - - GetRsrcs(slot, base, out, max); - - return out; -} - -static char * -GetStringInfo(slot, data, space, len) - struct slot *slot; - u_char *data; - char *space; - int len; -{ - int i; - char *p = space; - - if (NULL == data) - return ""; - - for (i = 0; (i < len) && *data; i++, p++) { - *p = GetByteInfo(slot, data); - data = IncPtr(slot, data, 1); - } - *p = '\0'; - return space; -} - -static long -GetLongInfo(slot, data) - struct slot *slot; - u_char *data; -{ - long ret = 0; - - switch (slot->size) { - case 1: - ret = (u_long) data[0] << 24 | (u_long) data[1] << 16 - | (u_long) data[2] << 8 | data[3]; - break; - case 2: - ret = (u_long) data[0] << 24 | (u_long) data[2] << 16 - | (u_long) data[4] << 8 | data[6]; - break; - case 4: - ret = (u_long) data[0] << 24 | (u_long) data[4] << 16 - | (u_long) data[8] << 8 | data[12]; - break; - } - - return ret; -} - -static short -GetShortInfo(slot, data) - struct slot *slot; - u_char *data; -{ - short ret; - - switch (slot->size) { - case 1: - ret = (u_long) data[0] << 8 | data[1]; - break; - case 2: - ret = (u_long) data[0] << 8 | data[2]; - break; - case 4: - ret = (u_long) data[0] << 8 | data[4]; - break; - } - - return ret; -} - -static char -GetByteInfo(slot, data) - struct slot *slot; - u_char *data; -{ - /* boring .... */ - return data[0]; -} - - -static int -FindMagic(data) - u_long data[]; -{ - u_short *data2; - u_char *data3 = (u_char *) data; - - data2 = (u_short *) data; - data3 = (u_char *) data; - - /* char data */ - if (((data3[0]) == 0x5a) && - ((data3[1]) == 0x93) && - ((data3[2]) == 0x2b) && - ((data3[3]) == 0xc7)) - return 1; - - /* short data */ - if (((data3[0]) == 0x5a) && - ((data3[2]) == 0x93) && - ((data3[4]) == 0x2b) && - ((data3[6]) == 0xc7)) - return 2; - - /* long data */ - if (((data3[0]) == 0x5a) && - ((data3[4]) == 0x93) && - ((data3[8]) == 0x2b) && - ((data3[12]) == 0xc7)) - return 4; - - return 0; -} - -static u_char * -IncPtr(slot, p, size) - struct slot *slot; - u_char *p; - int size; -{ - u_char *tmp; - - tmp = p + size * slot->size; - - return tmp; -} - -static int -GetRsrcs(slot, p, dir, maxdir) - struct slot *slot; - u_char *p; - struct dir *dir; - int maxdir; -{ - int i = 0; - - if (p == NULL) - return 1; - - while (maxdir--) { - long entry; - - entry = GetLongInfo(slot, p); - - dir[i].rsrc = (entry & 0xff000000) >> 24; - dir[i].offset = entry & 0x00ffffff; - dir[i].base = (u_long) p; - p = IncPtr(slot, p, 4); - if (dir[i].rsrc == 0xff) - break; - i++; - } - - return 0; -} - -static u_char * -getDataAtRsrc(slot, p, num) - struct slot *slot; - struct dir *p; - int num; -{ - int i = 0; - int failsafe = num; - long nextoffset = 0; - u_char *base; - - if (p == NULL) - return NULL; - - while (failsafe--) { - if (p[i].rsrc == num) { - base = (u_char *) ((u_long) slot->size * p[i].offset + - (u_long) p[i].base); - return base; - } - if (p[i].rsrc == 0xff) - return NULL; - i++; - } - - return NULL; -} - - -static int -InitNubusSlot(slotaddr, newslot) - u_long slotaddr; - struct slot *newslot; -{ - int i = 0; - struct slot slot; - struct dir *b; - struct dir bSpace[5]; - struct dir *d; - struct dir dSpace[5]; - struct dir *f; - struct dir fSpace[5]; - u_char *c; - u_char *e; - u_char *g; - u_long slotend; - - slotend = slotaddr + NBMEMSIZE - 1; - -/* - * If magic is not on the card, then we will quite likely bus error, - * because we will read a long word when there are only 3 bytes left - * on the card, unless there is a card in the next slot that has - * readable memory starting at 0, so more than likely we crash. Oh well. - * - * The directory and the rest of the card can be in different formats. - * This code won't handle that case. - */ - for (i = 5; i < 100; i++) { - if (slot.size = FindMagic((u_long *) (slotend - i))) { - GetHeader(&slot, slotend - i); - break; - } - } - - if (slot.size) { - b = getRsrcByNum(&slot, slot.mainDir, 1, bSpace, 5); - c = getDataAtRsrc(&slot, b, 2); - d = getRsrcByNum(&slot, b, 0x24, dSpace, 5); - e = getDataAtRsrc(&slot, d, 1); - f = getRsrcByNum(&slot, slot.mainDir, 0x80, fSpace, 5); - g = getDataAtRsrc(&slot, f, 1); - GetStringInfo(&slot, c, slot.name, 40); - - GetStringInfo(&slot, e, slot.manufacturer, 40); - -/* info here is two long words (cat,type,drvrsw,drvrhw) */ - slot.type = (GetLongInfo(&slot, g) & 0xffff0000) >> 16; - - } else - return 1; - - *newslot = slot; - return 0; -} - -struct imagedata * -NUBUS_GetImageData(slot, Rimage) - struct slot *slot; - struct imagedata *Rimage; -{ - struct imagedata image; - struct dir *dir; - struct dir dirSpace[10]; - struct dir dirSpace2[10]; - u_char *rawImage; - - - dir = getRsrcByNum(slot, slot->mainDir, 128, dirSpace, 10); - dir = getRsrcByNum(slot, dir, 128, dirSpace2, 10); - - rawImage = getDataAtRsrc(slot, dir, 1); - - image.whatTheHellIsThis = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.offset = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.rowbytes = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.top = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.left = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.bottom = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.right = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.version = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.packType = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.packSize = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.hRes = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.vRes = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.pixelType = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.pixelSize = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - *Rimage = image; - - return Rimage; -} - -struct nubus_hw nubus_table[NUBUS_MAXSLOTS]; - -extern int -nubus_addr_to_slot(addr) - caddr_t addr; -{ - int nubus_num; - - for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++) - if (nubus_table[nubus_num].addr == addr) - return nubus_num; - return -1; -} +extern int matchbyname(); + +static int nubusprint __P((void *aux, char *name)); +static void nubusattach __P((struct device *parent, struct device *self, + void *aux)); + +static int probe_slot __P((int slot, nubus_slot *fmt)); +static u_long IncPtr __P((nubus_slot *fmt, u_long base, long amt)); +static u_long nubus_calc_CRC __P((nubus_slot *fmt)); +static u_char GetByte __P((nubus_slot *fmt, u_long ptr)); +static u_short GetWord __P((nubus_slot *fmt, u_long ptr)); +static u_long GetLong __P((nubus_slot *fmt, u_long ptr)); + +struct cfdriver nubuscd = { + NULL, "nubus", matchbyname, nubusattach, + DV_DULL, sizeof(struct nubus_softc), 1 +}; static void -find_nubus() +nubusattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - /* - * This function sets up the array "nubus_table" which contains the - * basic information about each card in the Nubus slot. When device - * drivers are initialized later, they can look through this array to - * see if their hardware is present and claim it. - */ + nubus_slot fmtblock; + int i; - extern u_long NuBusBase; - register struct nubus_hw *nu; - int nubus_num; - - for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++) - nubus_table[nubus_num].found = 0; /* Empty */ - - /* - * LAK: For now we can only check 9..F because that's all we map in - * locore.s. Eventually (i.e. near future) we should put THIS - * function in locore.s before enabling the MMU and only map the slots - * that have a card in them. Also, the next loop should go from 1 to - * 0xF inclusive (0 is "reserved") to cover all possible hardware. - * Even if the MacII only has 9..F, it won't hurt us to probe 1..8 - * also. - */ - for (nubus_num = 0; nubus_num < 6; nubus_num++) { - nu = nubus_table + nubus_num + 9; - nu->addr = (caddr_t) (NuBusBase + nubus_num * NBMEMSIZE); - nu->rom = nu->addr + NBROMOFFSET; - - if (!badbaddr(nu->addr + NBMEMSIZE - 1)) { - InitNubusSlot((u_long) nu->addr, &(nu->slot)); - - nu->found = 1; - nu->claimed = 0; /* No driver has claimed this - * slot yet */ + printf("\n"); + for ( i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { + if (probe_slot(i, &fmtblock)) { + config_found(self, &fmtblock, nubusprint); } } } static int -nubus_print(aux, name) - void *aux; - char *name; +nubusprint(aux, name) + void *aux; + char *name; { - struct nubus_hw *nu = (struct nubus_hw *) aux; - int i; + nubus_slot *fmt; + int slot; + char *info; + fmt = (nubus_slot *) aux; if (name) { - i = nu - nubus_table; - printf("%s: s:%d t:%d \"", - name, i, nu->slot.type); - printf("%s, ", nu->slot.name); - printf("%s\"", nu->slot.manufacturer); + printf("%s: Card in slot %d: Name: %s", name, fmt->slot, + nubus_get_card_name(fmt)); + printf("Vendor: %s, \n", + nubus_get_vendor(fmt, NUBUS_RSRC_VEND_ID)); + printf("Part: %s.\n", + nubus_get_vendor(fmt, NUBUS_RSRC_VEND_PART)); } return (UNCONF); } -static void -nubus_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +/* + * Probe a given nubus slot. If a card is there and we can get the + * format block from it's clutching decl. ROMs, fill the format block + * and return non-zero. If we can't find a card there with a valid + * decl. ROM, return 0. + * + * First, we check to see if we can access the memory at the tail + * end of the slot. If so, then we check for a bytelanes byte. We + * could probably just return a failure status if we bus error on + * the first try, but there really is little reason not to go ahead + * and check the other three locations in case there's a wierd card + * out there. + * + * Checking for a card involves locating the "bytelanes" byte which + * tells us how to interpret the declaration ROM's data. The format + * block is at the top of the card's standard memory space and the + * bytelanes byte is at the end of that block. + * + * After some inspection of the bytelanes byte, it appears that it + * takes the form 0xXY where Y is a bitmask of the bytelanes in use + * and X is a bitmask of the lanes to ignore. Hence, (X ^ Y) == 0 + * and (less obviously), Y will have the upper N bits clear if it is + * found N bytes from the last possible location. Both that and + * the exclusive-or check are made. + * + * If a valid + */ +static u_char nbits[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; +static int +probe_slot(slot, fmt) + int slot; + nubus_slot *fmt; { - register struct nubus_hw *nu; - int i; + caddr_t rom_probe; + u_long hdr; + u_char data; + int hdr_size, i; - printf("\n"); + fmt->bytelanes = 0; + fmt->slot = (u_long)slot; - find_nubus(); + rom_probe = (caddr_t) (NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE); - for (i = 0; i < 6; i++) { - nu = nubus_table + i + 9; + for (i = 4; i && (fmt->bytelanes == 0); i--) { - if (!nu->found) + rom_probe--; + + if (badbaddr(rom_probe)) continue; - if (config_found(self, nu, nubus_print)) - nu->claimed = 1; + if ((data = *rom_probe) == 0) + continue; + + if ( ((((data & 0xf0) >> 4) ^ (data & 0x0f)) == 0x0f) + && ((data & 0x0f) < (1 << i)) ) { + fmt->bytelanes = data; + fmt->step = nbits[(data & 0x0f)]; + } } +#ifdef DEBUG + if (fmt->bytelanes == 0) + printf("bytelanes not found for slot 0x%x.\n", slot); +#endif + + if (fmt->bytelanes == 0) + return 0; + +#ifdef DEBUG + printf("bytelanes of 0x%x found for slot 0x%x.\n", + fmt->bytelanes, slot); +#endif + + hdr_size = 20; + + /* + * Go ahead and attempt to load format header. + * First, we need to find the first byte beyond memory that + * would be valid. This is necessary for NUBUS_ROM_offset() + * to work. + */ + hdr = NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE; + i = 0x10 | (fmt->bytelanes & 0x0f); + while ((i & 1) == 0) { + hdr++; + i >>= 1; + } + fmt->top = hdr; + hdr = IncPtr(fmt, hdr, -hdr_size); +#ifdef DEBUG + printf("fmt->top is 0x%x, that minus 0x%x puts us at 0x%x.\n", + fmt->top, hdr_size, hdr); +#if 0 + for (i=1 ; i < 8 ; i++) { + printf("0x%x - 0x%x = 0x%x, + 0x%x = 0x%x.\n", + hdr, i, IncPtr(fmt, hdr, -i), + i, IncPtr(fmt, hdr, i)); + } +#endif +#endif + + fmt->directory_offset = 0xff000000 | GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->length = GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->crc = GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->revision_level = GetByte(fmt, hdr); + hdr = IncPtr(fmt, hdr, 1); + fmt->format = GetByte(fmt, hdr); + hdr = IncPtr(fmt, hdr, 1); + fmt->test_pattern = GetLong(fmt, hdr); + +#if DEBUG +printf("Directory offset 0x%x\t", fmt->directory_offset); +printf("Length 0x%x\t", fmt->length); +printf("CRC 0x%x\n", fmt->crc); +printf("Revision level 0x%x\t", fmt->revision_level); +printf("Format 0x%x\t", fmt->format); +printf("Test Pattern 0x%x\n", fmt->test_pattern); +#endif + + if (fmt->test_pattern != NUBUS_ROM_TEST_PATTERN) { + printf("Nubus--test pattern invalid:\n"); + printf(" slot 0x%x, bytelanes 0x%x?\n", + fmt->slot, fmt->bytelanes); + printf(" read test 0x%x, compare with 0x%x.\n", + fmt->test_pattern, NUBUS_ROM_TEST_PATTERN); + return 0; + } + + /* Perform CRC */ + if (fmt->crc != nubus_calc_CRC(fmt)) { + printf("Nubus--crc check failed, slot 0x%x.\n", + fmt->slot); + return 0; + } + + return 1; } -extern int matchbyname(); +/* + * Compute byte offset on card, taking into account bytelanes. + * Base must be on a valid bytelane for this function to work. + * Return the new address. + * + * XXX -- There has GOT to be a better way to do this. + */ +static u_long +IncPtr(fmt, base, amt) + nubus_slot *fmt; + u_long base; + long amt; +{ + u_char b, t; -struct cfdriver nubuscd = { - NULL, "nubus", matchbyname, nubus_attach, - DV_DULL, sizeof(struct device), 1 -}; + if (!amt) + return base; + + if (amt < 0) { + amt = -amt; + b = fmt->bytelanes; + t = (b << 4); + b <<= (3 - (base & 0x3)); + while (amt) { + b <<= 1; + if (b == t) + b = fmt->bytelanes; + if (b & 0x08) + amt--; + base--; + } + return base; + } + + t = (fmt->bytelanes & 0xf) | 0x10; + b = t >> (base & 0x3); + while (amt) { + b >>= 1; + if (b == 1) + b = t; + if (b & 1) + amt--; + base++; + } + + return base; +} + +static u_long +nubus_calc_CRC(fmt) + nubus_slot *fmt; +{ +#if 0 + u_long base, ptr, crc_loc, sum; + int i; + + base = fmt->top; + crc_loc = NUBUS_ROM_offset(fmt, base, -12); + ptr = NUBUS_ROM_offset(fmt, base, -fmt->length); + + sum = 0; + while (ptr < base) + roll #1, sum + if (ptr == crc_loc) { + roll #3, sum + ptr = IncPtr(fmt, ptr, 3); + } else { + sum += GetByte(fmt, ptr); + } + ptr = IncPtr(fmt, ptr, 1); + } + + return sum; +#endif + return fmt->crc; +} + +static u_char +GetByte(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + return *(caddr_t)ptr; +} + +static u_short +GetWord(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + u_short s; + + s = (GetByte(fmt, ptr) << 8); + ptr = IncPtr(fmt, ptr, 1); + s |= GetByte(fmt, ptr); + return s; +} + +static u_long +GetLong(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + register u_long l; + register int i; + + l = 0; + for ( i = 0; i < 4; i++) { + l = (l << 8) | GetByte(fmt, ptr); + ptr = IncPtr(fmt, ptr, 1); + } + return l; +} + +void +nubus_get_main_dir(slot, dir_return) + nubus_slot *slot; + nubus_dir *dir_return; +{ + u_long off; + + dir_return->dirbase = IncPtr(slot, slot->top, + slot->directory_offset - 20); + dir_return->curr_ent = dir_return->dirbase; +} + +int +nubus_find_rsrc(slot, dir, rsrcid, dirent_return) + nubus_slot *slot; + nubus_dir *dir; + u_int8_t rsrcid; + nubus_dirent *dirent_return; +{ + u_long entry; + u_char byte; + + entry = dir->curr_ent; +#if DEBUG +printf("nubus_find_rsrc (0x%x,0x%x)\n", dir, rsrcid); +#endif + do { + byte = GetByte(slot, entry); +#if DEBUG +printf("\tFound rsrc 0x%x.\n", byte); +#endif + if (byte == rsrcid) { + dirent_return->myloc = entry; + dirent_return->rsrc_id = rsrcid; + entry = GetLong(slot, entry); + dirent_return->offset = (entry & 0x00ffffff); + return 1; + } + if (byte == 0xff) { + entry = dir->dirbase; + } else { + entry = IncPtr(slot, entry, 4); + } + } while (entry != (u_long) dir->curr_ent); + return 0; +} + +void +nubus_get_dir_from_rsrc(slot, dirent, dir_return) + nubus_slot *slot; + nubus_dirent *dirent; + nubus_dir *dir_return; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + dir_return->dirbase = IncPtr(slot, dirent->myloc, loc); + dir_return->curr_ent = dir_return->dirbase; +} + +int +nubus_get_ind_data(slot, dirent, data_return, nbytes) + nubus_slot *slot; + nubus_dirent *dirent; + caddr_t data_return; + int nbytes; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + loc = IncPtr(slot, dirent->myloc, loc); + + while (nbytes--) { + *data_return++ = GetByte(slot, loc); + loc = IncPtr(slot, loc, 1); + } + return 1; +} + +int +nubus_get_c_string(slot, dirent, data_return, max_bytes) + nubus_slot *slot; + nubus_dirent *dirent; + caddr_t data_return; + int max_bytes; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + loc = IncPtr(slot, dirent->myloc, loc); + + *data_return = '\0'; + while (max_bytes--) { + if ((*data_return++ = GetByte(slot, loc)) == 0) + return 1; + loc = IncPtr(slot, loc, 1); + } + return 0; +} + +static char *huh = "???"; + +char * +nubus_get_vendor(slot, rsrc) + nubus_slot *slot; + int rsrc; +{ +static char str_ret[64]; + nubus_dir dir; + nubus_dirent ent; + + nubus_get_main_dir(slot, &dir); + if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + return huh; + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_VENDORINFO, &ent) <= 0) + return huh; + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, rsrc, &ent) <= 0) + return huh; + + nubus_get_c_string(slot, &ent, str_ret, 64); + + return str_ret; +} + +char * +nubus_get_card_name(slot) + nubus_slot *slot; +{ +static char name_ret[64]; + nubus_dir dir; + nubus_dirent ent; + + nubus_get_main_dir(slot, &dir); + + if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + return huh; + + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_NAME, &ent) <= 0) + return huh; + + nubus_get_c_string(slot, &ent, name_ret, 64); + + return name_ret; +} diff --git a/sys/arch/mac68k/dev/nubus.h b/sys/arch/mac68k/dev/nubus.h index 7c62f4e4ee16..5cedaf7225fc 100644 --- a/sys/arch/mac68k/dev/nubus.h +++ b/sys/arch/mac68k/dev/nubus.h @@ -1,10 +1,7 @@ -/* $NetBSD: nubus.h,v 1.4 1995/04/21 02:48:01 briggs Exp $ */ +/* $NetBSD: nubus.h,v 1.5 1995/04/29 20:23:48 briggs Exp $ */ -/*- - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * All rights reserved. +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -16,80 +13,219 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define NUBUS_VIDEO 3 -#define NUBUS_NETWORK 4 -#define NUBUS_MOTHERBOARD 0x0a -#define NUBUS_MAXSLOTS 16 +/* + * Nubus cards in Macintoshes are identified by 4 16-bit numbers: + * Category: What is the main purpose of this card? + * Type: Within this overall category, what kind of card? + * DrSW: What software interface does it use? + * DrHW: What specific hardware is it? + * + * For example, the "Toby Frame Buffer" display card is + * Category 3 (display) + * Type 1 (video) + * DrSW 1 (Apple) + * and DrHW 1 (TFB). + */ -struct imagedata { - long whatTheHellIsThis; - long offset; - short rowbytes; - short top; - short left; - short right; - short bottom; - short version; - short packType; - short packSize; - long hRes; - long vRes; - short pixelType; - short pixelSize; +#define NUBUS_CATEGORY_BOARD 0x0001 + +#define NUBUS_CATEGORY_DISPLAY 0x0003 +#define NUBUS_TYPE_VIDEO 0x0001 +#define NUBUS_TYPE_LCD 0x0002 +#define NUBUS_DRSW_APPLE 0x0001 +#define NUBUS_DRHW_TFB 0x0001 +#define NUBUS_DRHW_M2HRVC 0x0013 +#define NUBUS_DRHW_MICRON 0x0146 + +#define NUBUS_CATEGORY_NETWORK 0x0004 +#define NUBUS_TYPE_ETHERNET 0x0001 +#define NUBUS_DRSW_3COM 0x0000 +#define NUBUS_DRSW_ASANTE 0x0104 +#define NUBUS_DRSW_DAYNA 0x0105 /* XXX */ +#define NUBUS_DRSW_INTERLAN 0x0106 /* XXX */ +#define NUBUS_DRHW_SONIC 0x0110 + +#define NUBUS_CATEGORY_FONT 0x0009 /* KanjiTalk Font Card? */ + +#define NUBUS_CATEGORY_CPU 0x000A +#define NUBUS_TYPE_68000 0x0002 +#define NUBUS_TYPE_68020 0x0003 +#define NUBUS_TYPE_68030 0x0004 +#define NUBUS_TYPE_68040 0x0005 + +/* + * This is the same as Apple's Format Block for a card, with the + * addition of a pointer to the base of the NuBUS slot. + * + * This basically describes a nubus card--this structure is held in the last + * N bytes of each valid card's declaration ROM. + */ +typedef struct _nubus_slot { + u_long top; + u_int8_t slot; + u_int8_t bytelanes; + u_int8_t step; + u_int32_t test_pattern; + u_int8_t format; + u_int8_t revision_level; + u_int32_t crc; + u_int32_t length; + u_int32_t directory_offset; +} nubus_slot; + +/* + * Just a structure to ease comparison of type for drivers, etc. + */ +typedef struct _nubus_type { + u_int16_t category; + u_int16_t type; + u_int16_t drsw; + u_int16_t drhw; +} nubus_type; + +/* + * nubus_dir is a structure that describes a nubus directory. + * The nubus*dir() functions should be used to traverse this. + */ +typedef struct _nubus_dir { + u_int32_t dirbase; + u_int32_t curr_ent; +} nubus_dir; + +/* + * This is the equivalent of an Apple sResource directory entry + * with the addition of a pointer to itself (essentially) for easy + * calculation of jump to indirect data. + */ +typedef struct _nubus_dirent { + u_int32_t myloc; + u_int8_t rsrc_id; + u_int32_t offset; +} nubus_dirent; + +/* + * This is the equivalent of an Apple sResource with the addition of + * a pointer back to the sResource directory from whence we came. + * + * According to the Apple documentation, each sResource is of one of the + * following forms: + * all: bits 31-24 Identification number + * + * offset: bits 23-0 Offset to long data, cString, sBlock, etc. + * word: bits 23-16 0x00 + * bits 15-0 word data + * byte: bits 23-8 0x0000 + * bits 7-0 byte data + * + * The last resource has id = 0xff and data = 0x000000. + */ +typedef struct _nubus_rsrc { + u_int32_t myloc; + u_int8_t id; + u_int32_t data; +} nubus_rsrc; + +/* Resource IDs for NUBUS_CATEGORY_* (All) */ +#define NUBUS_RSRC_TYPE 0x01 /* Type (required) */ +#define NUBUS_RSRC_NAME 0x02 /* Name (required) */ +#define NUBUS_RSRC_ICON 0x03 /* Icon */ +#define NUBUS_RSRC_DRVRDIR 0x04 /* Driver directory */ +#define NUBUS_RSRC_LOADREC 0x05 /* Load record for resource */ +#define NUBUS_RSRC_BOOTREC 0x06 /* Boot record */ +#define NUBUS_RSRC_FLAGS 0x07 /* sResource Flags */ +#define NUBUS_RSRC_HWDEVID 0x08 /* Hardware device ID */ +#define NUBUS_RSRC_MINOR_BASEOS 0x0A /* Offset to hw in std space */ +#define NUBUS_RSRC_MINOR_LENGTH 0x0B /* Length of std space */ +#define NUBUS_RSRC_MAJOR_BASEOS 0x0C /* Offset to hw in super space */ +#define NUBUS_RSRC_MAJOR_LENGTH 0x0D /* Length of super space */ +#define NUBUS_RSRC_CICN 0x0F /* Color icon */ +#define NUBUS_RSRC_ICL8 0x10 /* 8-bit icon data */ +#define NUBUS_RSRC_ICL4 0x11 /* 4-bit icon data */ + +/* Resource IDs for NUBUS_CATEGORY_DISPLAY */ +#define NUBUS_RSRC_GAMMADIR 0x40 /* ID for gamma directory */ +#define NUBUS_RSRC_VIDNAMES 0x41 /* ID for video name directory */ +#define NUBUS_RSRC_FIRSTMODE 0x80 /* ID for first mode (1-bit) */ +#define NUBUS_RSRC_SECONDMODE 0x81 /* ID for 2nd mode (2-bit) */ +#define NUBUS_RSRC_THIRDMODE 0x82 /* ID for 3rd mode (4-bit) */ +#define NUBUS_RSRC_FOURTHMODE 0x83 /* ID for 4th mode (8-bit) */ +#define NUBUS_RSRC_FIFTHMODE 0x84 /* ID for 5th mode (16-bit) */ +#define NUBUS_RSRC_SIXTHMODE 0x85 /* ID for 6th mode (32-bit) */ + +/* Resource IDs for NUBUS_CATEGORY_BOARD */ +#define NUBUS_RSRC_BOARDID 0x20 /* Board ID */ +#define NUBUS_RSRC_PRAMINITDATA 0x21 /* Private board data for PRAM */ +#define NUBUS_RSRC_PRIMARYINIT 0x22 /* Primary init record */ +#define NUBUS_RSRC_TIMEOUTCONST 0x23 /* Timeout constant */ +#define NUBUS_RSRC_VENDORINFO 0x24 /* Vendor info list */ +#define NUBUS_RSRC_BOARDFLAGS 0x25 /* Board flags */ +#define NUBUS_RSRC_SECONDINIT 0x26 /* Secondary init record */ + +#define NUBUS_RSRC_VEND_ID 0x01 /* Card vendor's design ID */ +#define NUBUS_RSRC_VEND_SERIAL 0x02 /* Card's serial number */ +#define NUBUS_RSRC_VEND_REV 0x03 /* Card design's revision level */ +#define NUBUS_RSRC_VEND_PART 0x04 /* Card part number */ +#define NUBUS_RSRC_VEND_DATE 0x05 /* Card revision date */ + +typedef struct _NUBUS_DRIVER { + u_int8_t drvr_id; + u_int32_t offset; +} NUBUS_DRIVER; + +typedef struct _NUBUS_BLOCK { + u_int32_t size; /* Size of block of data */ + caddr_t data; /* Pointer to data */ +} NUBUS_BLOCK; + +typedef struct _NUBUS_EXEC_BLOCK { + u_int32_t size; /* Size of total block - 4 */ + u_int8_t revision; /* Always 0x2 */ + u_int8_t cpu; /* Which processor? */ + u_int32_t code_offset; /* Offset base to start of code */ + caddr_t code; /* pointer to base of code. */ +} NUBUS_EXEC_BLOCK; + +#define NUBUS_EXEC_CPU_68000 1 +#define NUBUS_EXEC_CPU_68020 2 +#define NUBUS_EXEC_CPU_68030 3 +#define NUBUS_EXEC_CPU_68040 4 + +#define NUBUS_MIN_SLOT 0x9 +#define NUBUS_MAX_SLOT 0xE +#define NUBUS_ROM_TEST_PATTERN 0x5A932BC7 + +#define NUBUS_BASE_TO_SLOT(x) (((x) >> 24) & 0x0F) +#define NUBUS_SLOT_TO_BASE(x) (0xF0000000 | (((x) & 0xF) << 24)) + +struct nubus_softc { + struct device sc_dev; }; -/* this is the main data structure that points to good stuff */ -struct header { - long offset; - long length; - long crc; - char romrev; - char format; - long tst; - char reserved; - char bytelane; -}; +void nubus_get_main_dir __P((nubus_slot *slot, nubus_dir *dir_return)); +int nubus_find_rsrc __P((nubus_slot *slot, nubus_dir *dir, u_int8_t rsrcid, + nubus_dirent *dirent_return)); +void nubus_get_dir_from_rsrc __P((nubus_slot *slot, nubus_dirent *dirent, + nubus_dir *dir_return)); +int nubus_get_ind_data __P((nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int nbytes)); +int nubus_get_c_string __P((nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int max_bytes)); +char *nubus_get_vendor __P((nubus_slot *slot, int rsrc)); +char *nubus_get_card_name __P((nubus_slot *slot)); -/* this is what the directory entries contain */ -struct dir { - unsigned char rsrc; - unsigned long offset; - unsigned long base; -}; - -/* describe a single slot */ -struct slot { - int size; - struct header head; - struct dir mainDir[15]; - long type; - char name[40]; - char manufacturer[40]; -}; - -struct nubus_hw { - int found; /* If there is a card there */ - caddr_t addr; /* Phys addr of start of card */ - caddr_t rom; /* Phys addr of start of ROM */ - int claimed; /* TRUE if a driver claims this */ - struct slot slot; /* MF NUBUS STUFF */ - /* any other Nubus stuff we can think of when we get */ - /* the NuBus documentation */ -}; diff --git a/sys/arch/mac68k/include/grfioctl.h b/sys/arch/mac68k/include/grfioctl.h index 613f8dd19d55..d710c8cda519 100644 --- a/sys/arch/mac68k/include/grfioctl.h +++ b/sys/arch/mac68k/include/grfioctl.h @@ -1,4 +1,4 @@ -/* $NetBSD: grfioctl.h,v 1.2 1994/10/26 08:46:32 cgd Exp $ */ +/* $NetBSD: grfioctl.h,v 1.3 1995/04/29 20:23:50 briggs Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -42,6 +42,43 @@ * @(#)grfioctl.h 7.2 (Berkeley) 11/4/90 */ +struct grfmode { + u_int8_t mode_id; /* Identifier for mode. */ + caddr_t fbbase; /* Base of frame buffer */ + u_int32_t fbsize; /* Size of frame buffer */ + u_int16_t rowbytes; /* Screen rowbytes */ + u_int16_t width; /* Screen width */ + u_int16_t height; /* Screen height */ + u_int16_t hres; /* Horizontal resolution (dpi) */ + u_int16_t vres; /* Vertical resolution (dpi) */ + u_int16_t ptype; /* 0 = indexed, 0x10 = direct */ + u_int16_t psize; /* Screen depth */ +}; + +struct grfmodes { + int nmodes; /* Number of modes in modelist */ + struct grfmode *modelist; /* Pointer to space for modes */ +}; + +/* + * BSD ioctls (first few match HP/UX ioctl()s. In case we want + * compatibility later, start our own at 16). + */ +#define GRFIOCGINFO _IOR('G', 0, struct grfinfo) /* get info on device */ +#define GRFIOCON _IO('G', 1) /* turn graphics on */ +#define GRFIOCOFF _IO('G', 2) /* turn graphics off */ +#define GRFIOCMAP _IOWR('G', 5, int) /* map in regs+framebuffer */ +#define GRFIOCUNMAP _IOW('G', 6, int) /* unmap regs+framebuffer */ + +#define GRFIOCLISTMODES _IOWR('G', 16, struct grfmodes) /* Get list of modes */ +#define GRFIOCGETMODE _IOR('G', 17, int) /* Get list of modes */ +#define GRFIOCSETMODE _IOW('G', 18, int) /* Set to mode_id mode */ + +/* + * Obsolete structure. + * Only used to return information to older programs that still + * depend on GRFIOCGINFO. + */ struct grfinfo { int gd_id; /* HPUX identifier */ caddr_t gd_regaddr; /* control registers physaddr */ @@ -50,7 +87,6 @@ struct grfinfo { int gd_fbsize; /* frame buffer size */ short gd_colors; /* number of colors */ short gd_planes; /* number of planes */ -/* new stuff */ int gd_fbwidth; /* frame buffer width */ int gd_fbheight; /* frame buffer height */ int gd_fbrowbytes; /* frame buffer rowbytes */ @@ -59,50 +95,3 @@ struct grfinfo { int gd_pad[6]; /* for future expansion */ }; -/* types */ -#define GRFMAC 8 - -/* - * HPUX ioctls (here for the benefit of the driver) - */ -struct grf_slot { - int slot; - u_char *addr; -}; - -#ifndef _IOH -#define _IOH(x,y) (IOC_IN|((x)<<8)|y) /* IOC_IN is IOC_VOID */ - -#define GCID _IOR('G', 0, int) -#define GCON _IOH('G', 1) -#define GCOFF _IOH('G', 2) -#define GCAON _IOH('G', 3) -#define GCAOFF _IOH('G', 4) -#define GCMAP _IOWR('G', 5, int) -#define GCUNMAP _IOWR('G', 6, int) -#define GCLOCK _IOH('G', 7) -#define GCUNLOCK _IOH('G', 8) -#define GCLOCK_MINIMUM _IOH('G', 9) -#define GCUNLOCK_MINIMUM _IOH('G', 10) -#define GCSTATIC_CMAP _IOH('G', 11) -#define GCVARIABLE_CMAP _IOH('G', 12) -#define GCSLOT _IOWR('G', 13, struct grf_slot) - -/* XXX: for now */ -#define IOMAPID _IOR('M',0,int) /* ??? */ -#define IOMAPMAP _IOWR('M',1,int) -#define IOMAPUNMAP _IOWR('M',2,int) -#endif - -/* - * BSD ioctls - */ -#define GRFIOCGINFO _IOR('G', 0, struct grfinfo) /* get info on device */ -#define GRFIOCON _IO('G', 1) /* turn graphics on */ -#define GRFIOCOFF _IO('G', 2) /* turn graphics off */ -#define GRFIOCMAP _IOWR('G', 5, int) /* map in regs+framebuffer */ -#define GRFIOCUNMAP _IOW('G', 6, int) /* unmap regs+framebuffer */ - -/* compat - for old grfinfo structure */ -struct ogrfinfo { char oinfo[24]; }; -#define OGRFIOCGINFO _IOR('G', 0, struct ogrfinfo) diff --git a/sys/arch/mac68k/mac68k/via.c b/sys/arch/mac68k/mac68k/via.c index 1da4f3a6b781..51cfac5a6901 100644 --- a/sys/arch/mac68k/mac68k/via.c +++ b/sys/arch/mac68k/mac68k/via.c @@ -1,4 +1,4 @@ -/* $NetBSD: via.c,v 1.19 1995/04/21 04:00:55 briggs Exp $ */ +/* $NetBSD: via.c,v 1.20 1995/04/29 20:23:53 briggs Exp $ */ /*- * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, @@ -140,10 +140,6 @@ void VIA_initialize() via2itab[1] = via2_nubus_intr; }else{ /* RBV */ - /* I'm sure that I'll find something to put in here - someday. -- BG */ - /* enable specific interrupts */ - /* via_reg(VIA2, rIER) = RBV_INTS | 0x80; */ real_via2_intr = rbv_intr; via2itab[1] = rbv_nubus_intr; } @@ -244,16 +240,14 @@ long via2_noint(int bitnum) static int nubus_intr_mask = 0; int -add_nubus_intr(addr, func, client_data) -int addr; +add_nubus_intr(slot, func, client_data) +int slot; void (*func)(); void *client_data; { int s = splhigh(); - int slot; - slot = nubus_addr_to_slot(addr); - if (slot < 0) return 0; + if (slot < 9 || slot > 15) return 0; slotitab[slot-9] = func; slotptab[slot-9] = client_data; diff --git a/sys/arch/mac68k/nubus/grf_nubus.c b/sys/arch/mac68k/nubus/grf_nubus.c new file mode 100644 index 000000000000..56b1f92fd2e9 --- /dev/null +++ b/sys/arch/mac68k/nubus/grf_nubus.c @@ -0,0 +1,213 @@ +/* $NetBSD: grf_nubus.c,v 1.1 1995/04/29 20:23:42 briggs Exp $ */ + +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Device-specific routines for handling Nubus-based video cards. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nubus.h" +#include "grfvar.h" + +extern int grfmv_probe __P((struct grf_softc *gp, nubus_slot *slot)); +extern int grfmv_init __P((struct grf_softc *gp)); +extern int grfmv_mode __P((struct grf_softc *gp, int cmd, void *arg)); + +static char zero = 0; + +static void +load_image_data(data, image) + caddr_t data; + struct image_data *image; +{ + bcopy(data , &image->size, 4); + bcopy(data + 4, &image->offset, 4); + bcopy(data + 8, &image->rowbytes, 2); + bcopy(data + 10, &image->top, 2); + bcopy(data + 12, &image->left, 2); + bcopy(data + 14, &image->bottom, 2); + bcopy(data + 16, &image->right, 2); + bcopy(data + 18, &image->version, 2); + bcopy(data + 20, &image->packType, 2); + bcopy(data + 22, &image->packSize, 4); + bcopy(data + 26, &image->hRes, 4); + bcopy(data + 30, &image->vRes, 4); + bcopy(data + 34, &image->pixelType, 2); + bcopy(data + 36, &image->pixelSize, 2); + bcopy(data + 38, &image->cmpCount, 2); + bcopy(data + 40, &image->cmpSize, 2); + bcopy(data + 42, &image->planeBytes, 4); +} + +static void +grfmv_intr(sc, slot) + struct grf_softc *sc; + int slot; +{ + struct grf_softc *gp; + + ((char *) (((u_long) (0xf0 | slot)) << 24))[0xa0000] = zero; +} + +extern int +grfmv_probe(sc, slot) + struct grf_softc *sc; + nubus_slot *slot; +{ + nubus_dir dir, *dirp, dir2, *dirp2; + nubus_dirent dirent, *direntp; + nubus_type slottype; + + dirp = &dir; + direntp = &dirent; + nubus_get_main_dir(slot, dirp); + + /* + * Unfortunately, I think we'll have to load this value from + * the macos. The alternative is putting in enough hooks to + * be able to call the card's PrimaryInit routine which could + * call just about any part of the ROM, I think. + */ + if (nubus_find_rsrc(slot, dirp, 128, direntp) <= 0) { + if (nubus_find_rsrc(slot, dirp, 129, direntp) <= 0) { + return 0; + } + } + + dirp2 = (nubus_dir *) &sc->board_dir; + nubus_get_dir_from_rsrc(slot, direntp, dirp2); + + if (nubus_find_rsrc(slot, dirp2, NUBUS_RSRC_TYPE, direntp) <= 0) + /* Type is a required entry... This should never happen. */ + return 0; + + if (nubus_get_ind_data(slot, direntp, + (caddr_t) &slottype, sizeof(nubus_type)) <= 0) + return 0; + + if (slottype.category != NUBUS_CATEGORY_DISPLAY) + return 0; + + if (slottype.type != NUBUS_TYPE_VIDEO) + return 0; + + if (slottype.drsw != NUBUS_DRSW_APPLE) + return 0; + + /* + * If we've gotten this far, then we're dealing with a real-live + * Apple QuickDraw-compatible display card resource. Now, how to + * determine that this is an active resource??? Dunno. But we'll + * proceed like it is. + */ + + sc->card_id = slottype.drhw; +printf("card id = 0x%x.\n", sc->card_id); + + /* Need to load display info (and driver?), etc... */ + + return 1; +} + +extern int +grfmv_init(sc) + struct grf_softc *sc; +{ + struct image_data image_store, image; + nubus_dirent dirent; + nubus_dir mode_dir; + int mode; + u_long base; + + mode = NUBUS_RSRC_FIRSTMODE; + if (nubus_find_rsrc(&sc->sc_slot, &sc->board_dir, mode, &dirent) <= 0) + return 0; + + nubus_get_dir_from_rsrc(&sc->sc_slot, &dirent, &mode_dir); + + if (nubus_find_rsrc(&sc->sc_slot, &mode_dir, VID_PARAMS, &dirent) <= 0) + return 0; + + if (nubus_get_ind_data(&sc->sc_slot, &dirent, (caddr_t) &image_store, + sizeof(struct image_data)) <= 0) + return 0; + + load_image_data((caddr_t) &image_store, &image); + + base = NUBUS_SLOT_TO_BASE(sc->sc_slot.slot); + + sc->curr_mode.mode_id = mode; + sc->curr_mode.fbbase = (caddr_t) (base + image.offset); + sc->curr_mode.rowbytes = image.rowbytes; + sc->curr_mode.width = image.right - image.left; + sc->curr_mode.height = image.bottom - image.top; + sc->curr_mode.fbsize = sc->curr_mode.height * sc->curr_mode.rowbytes; + sc->curr_mode.hres = image.hRes; + sc->curr_mode.vres = image.vRes; + sc->curr_mode.ptype = image.pixelType; + sc->curr_mode.psize = image.pixelSize; + + strncpy(sc->card_name, nubus_get_card_name(&sc->sc_slot), + CARD_NAME_LEN); + + sc->card_name[CARD_NAME_LEN-1] = '\0'; + + add_nubus_intr(sc->sc_slot.slot, grfmv_intr, sc); + + return 1; +} + +extern int +grfmv_mode(gp, cmd, arg) + struct grf_softc *gp; + int cmd; + void *arg; +{ + switch (cmd) { + case GM_CURRMODE: + break; + case GM_NEWMODE: + break; + case GM_LISTMODES: + break; + } + return EINVAL; +} diff --git a/sys/arch/mac68k/nubus/nubus.c b/sys/arch/mac68k/nubus/nubus.c index 9701bddf1363..afd99b69fe8a 100644 --- a/sys/arch/mac68k/nubus/nubus.c +++ b/sys/arch/mac68k/nubus/nubus.c @@ -1,10 +1,7 @@ -/* $NetBSD: nubus.c,v 1.10 1995/04/21 02:47:59 briggs Exp $ */ +/* $NetBSD: nubus.c,v 1.11 1995/04/29 20:23:46 briggs Exp $ */ -/*- - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * All rights reserved. +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -16,21 +13,20 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -41,595 +37,469 @@ #include "nubus.h" -static struct dir *getRsrcByNum __P((struct slot *slot, struct dir *p, - int num, struct dir *out, int max)); -static int print_rsrcinfo __P((struct slot *slot, struct dir *p)); -static char *GetStringInfo __P((struct slot *slot, u_char *data1, - char *space, int len)); -static int printTree __P((struct slot *slot, struct dir *root)); -static long GetLongInfo __P((struct slot *slot, u_char *data)); -static int FindMagic __P((u_long *data)); -static int GetHeader __P((struct slot *slot, u_long pos)); -static u_char *IncPtr __P((struct slot *slot, u_char *p, int size)); -static char GetByteInfo __P((struct slot *slot, u_char *data)); -static int GetRsrcs __P((struct slot *slot, u_char *p, - struct dir *dir, int maxdir)); -static u_char *getDataAtRsrc __P((struct slot *slot, struct dir *p, int num)); -static short GetShortInfo __P((struct slot *slot, u_char *data)); - -static int -GetHeader(slot, pos) - struct slot *slot; - u_long pos; -{ - /* the pos passed in is the pos that the magic testvalue was found at */ - u_char *p; - u_char *dirBase; - - switch (slot->size) { - case 1: /* char */ - pos -= 14; - break; - case 2: - pos -= 28; - break; - case 4: - pos -= 56; - break; - } - - p = (u_char *) pos; - - slot->head.offset = (0xff000000 | (u_long) GetLongInfo(slot, p)); - p = IncPtr(slot, p, 4); - - slot->head.length = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.crc = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.romrev = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - slot->head.format = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - slot->head.tst = GetLongInfo(slot, p); - p = IncPtr(slot, p, 4); - - slot->head.reserved = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - -/* byte lanes should be used instead of size, this hasn't bitten me yet */ - slot->head.bytelane = GetByteInfo(slot, p); - p = IncPtr(slot, p, 1); - - dirBase = (u_char *) (pos + slot->head.offset * slot->size); - GetRsrcs(slot, dirBase, slot->mainDir, 15); - return 0; -} - -static int -printTree(slot, root) - struct slot *slot; - struct dir *root; -{ - struct dir *b; - u_char *c; - struct dir *d; - u_char *e; - struct dir *f; - u_char *g; - struct dir *h; - u_char *i; - u_char *j; - u_char *k; - struct dir bSpace[15]; - struct dir cSpace[15]; - struct dir dSpace[15]; - struct dir fSpace[15]; - struct dir hSpace[15]; - char space[40]; -/* to get a good idea of what is happening here you should get the -"slots" program from apple dts, it is so cool. Its the next -best thing to actual docs, which i didn't have... -*/ - - b = getRsrcByNum(slot, root, 1, bSpace, 15); - c = getDataAtRsrc(slot, b, 2); - d = getRsrcByNum(slot, b, 0x24, dSpace, 15); - - e = getDataAtRsrc(slot, d, 1); - - f = getRsrcByNum(slot, root, 0x80, fSpace, 15); - g = getDataAtRsrc(slot, f, 2); - j = getDataAtRsrc(slot, f, 0x0a); - k = getDataAtRsrc(slot, f, 0x0b); - - h = getRsrcByNum(slot, root, 0xa0, hSpace, 15); - i = getDataAtRsrc(slot, h, 2); - - printf("A\n"); - print_rsrcinfo(slot, root); - - printf("B\n"); - print_rsrcinfo(slot, b); - - printf("C\n"); - printf("%s\n", GetStringInfo(slot, c, space, 40)); - - printf("D\n"); - print_rsrcinfo(slot, d); - - printf("E\n"); - printf("%s\n", GetStringInfo(slot, e, space, 40)); - - printf("F\n"); - print_rsrcinfo(slot, f); - - printf("g\n"); - printf("%s\n", GetStringInfo(slot, g, space, 40)); - printf("Video RAM Base %lx\n", GetLongInfo(slot, j)); - printf("Video RAM Length %lx\n", GetLongInfo(slot, k)); - - printf("H\n"); - print_rsrcinfo(slot, h); - - printf("I\n"); - printf("%s\n", GetStringInfo(slot, i, space, 40)); -} - -static int -print_rsrcinfo(slot, p) - struct slot *slot; - struct dir *p; -{ - int i = 0; - int failsafe = 20; - - if (p == NULL) - return 1; - while (failsafe--) { - printf("RSRC %02x :%06lx\n", p[i].rsrc, p[i].offset); - if (p[i].rsrc == 0xff) - break; - i++; - } - -} - -static struct dir * -getRsrcByNum(slot, p, num, out, max) - struct slot *slot; - struct dir *p; - int num; - struct dir *out; - int max; -{ - int i = 0; - int failsafe = 20; - long nextoffset = 0; - u_char *base; - - if (p == NULL) - return NULL; - - - base = getDataAtRsrc(slot, p, num); - - if (NULL == base) - return NULL; - - GetRsrcs(slot, base, out, max); - - return out; -} - -static char * -GetStringInfo(slot, data, space, len) - struct slot *slot; - u_char *data; - char *space; - int len; -{ - int i; - char *p = space; - - if (NULL == data) - return ""; - - for (i = 0; (i < len) && *data; i++, p++) { - *p = GetByteInfo(slot, data); - data = IncPtr(slot, data, 1); - } - *p = '\0'; - return space; -} - -static long -GetLongInfo(slot, data) - struct slot *slot; - u_char *data; -{ - long ret = 0; - - switch (slot->size) { - case 1: - ret = (u_long) data[0] << 24 | (u_long) data[1] << 16 - | (u_long) data[2] << 8 | data[3]; - break; - case 2: - ret = (u_long) data[0] << 24 | (u_long) data[2] << 16 - | (u_long) data[4] << 8 | data[6]; - break; - case 4: - ret = (u_long) data[0] << 24 | (u_long) data[4] << 16 - | (u_long) data[8] << 8 | data[12]; - break; - } - - return ret; -} - -static short -GetShortInfo(slot, data) - struct slot *slot; - u_char *data; -{ - short ret; - - switch (slot->size) { - case 1: - ret = (u_long) data[0] << 8 | data[1]; - break; - case 2: - ret = (u_long) data[0] << 8 | data[2]; - break; - case 4: - ret = (u_long) data[0] << 8 | data[4]; - break; - } - - return ret; -} - -static char -GetByteInfo(slot, data) - struct slot *slot; - u_char *data; -{ - /* boring .... */ - return data[0]; -} - - -static int -FindMagic(data) - u_long data[]; -{ - u_short *data2; - u_char *data3 = (u_char *) data; - - data2 = (u_short *) data; - data3 = (u_char *) data; - - /* char data */ - if (((data3[0]) == 0x5a) && - ((data3[1]) == 0x93) && - ((data3[2]) == 0x2b) && - ((data3[3]) == 0xc7)) - return 1; - - /* short data */ - if (((data3[0]) == 0x5a) && - ((data3[2]) == 0x93) && - ((data3[4]) == 0x2b) && - ((data3[6]) == 0xc7)) - return 2; - - /* long data */ - if (((data3[0]) == 0x5a) && - ((data3[4]) == 0x93) && - ((data3[8]) == 0x2b) && - ((data3[12]) == 0xc7)) - return 4; - - return 0; -} - -static u_char * -IncPtr(slot, p, size) - struct slot *slot; - u_char *p; - int size; -{ - u_char *tmp; - - tmp = p + size * slot->size; - - return tmp; -} - -static int -GetRsrcs(slot, p, dir, maxdir) - struct slot *slot; - u_char *p; - struct dir *dir; - int maxdir; -{ - int i = 0; - - if (p == NULL) - return 1; - - while (maxdir--) { - long entry; - - entry = GetLongInfo(slot, p); - - dir[i].rsrc = (entry & 0xff000000) >> 24; - dir[i].offset = entry & 0x00ffffff; - dir[i].base = (u_long) p; - p = IncPtr(slot, p, 4); - if (dir[i].rsrc == 0xff) - break; - i++; - } - - return 0; -} - -static u_char * -getDataAtRsrc(slot, p, num) - struct slot *slot; - struct dir *p; - int num; -{ - int i = 0; - int failsafe = num; - long nextoffset = 0; - u_char *base; - - if (p == NULL) - return NULL; - - while (failsafe--) { - if (p[i].rsrc == num) { - base = (u_char *) ((u_long) slot->size * p[i].offset + - (u_long) p[i].base); - return base; - } - if (p[i].rsrc == 0xff) - return NULL; - i++; - } - - return NULL; -} - - -static int -InitNubusSlot(slotaddr, newslot) - u_long slotaddr; - struct slot *newslot; -{ - int i = 0; - struct slot slot; - struct dir *b; - struct dir bSpace[5]; - struct dir *d; - struct dir dSpace[5]; - struct dir *f; - struct dir fSpace[5]; - u_char *c; - u_char *e; - u_char *g; - u_long slotend; - - slotend = slotaddr + NBMEMSIZE - 1; - -/* - * If magic is not on the card, then we will quite likely bus error, - * because we will read a long word when there are only 3 bytes left - * on the card, unless there is a card in the next slot that has - * readable memory starting at 0, so more than likely we crash. Oh well. - * - * The directory and the rest of the card can be in different formats. - * This code won't handle that case. - */ - for (i = 5; i < 100; i++) { - if (slot.size = FindMagic((u_long *) (slotend - i))) { - GetHeader(&slot, slotend - i); - break; - } - } - - if (slot.size) { - b = getRsrcByNum(&slot, slot.mainDir, 1, bSpace, 5); - c = getDataAtRsrc(&slot, b, 2); - d = getRsrcByNum(&slot, b, 0x24, dSpace, 5); - e = getDataAtRsrc(&slot, d, 1); - f = getRsrcByNum(&slot, slot.mainDir, 0x80, fSpace, 5); - g = getDataAtRsrc(&slot, f, 1); - GetStringInfo(&slot, c, slot.name, 40); - - GetStringInfo(&slot, e, slot.manufacturer, 40); - -/* info here is two long words (cat,type,drvrsw,drvrhw) */ - slot.type = (GetLongInfo(&slot, g) & 0xffff0000) >> 16; - - } else - return 1; - - *newslot = slot; - return 0; -} - -struct imagedata * -NUBUS_GetImageData(slot, Rimage) - struct slot *slot; - struct imagedata *Rimage; -{ - struct imagedata image; - struct dir *dir; - struct dir dirSpace[10]; - struct dir dirSpace2[10]; - u_char *rawImage; - - - dir = getRsrcByNum(slot, slot->mainDir, 128, dirSpace, 10); - dir = getRsrcByNum(slot, dir, 128, dirSpace2, 10); - - rawImage = getDataAtRsrc(slot, dir, 1); - - image.whatTheHellIsThis = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.offset = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.rowbytes = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.top = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.left = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.bottom = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.right = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.version = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.packType = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.packSize = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.hRes = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.vRes = GetLongInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 4); - - image.pixelType = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - image.pixelSize = GetShortInfo(slot, rawImage); - rawImage = IncPtr(slot, rawImage, 2); - - *Rimage = image; - - return Rimage; -} - -struct nubus_hw nubus_table[NUBUS_MAXSLOTS]; - -extern int -nubus_addr_to_slot(addr) - caddr_t addr; -{ - int nubus_num; - - for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++) - if (nubus_table[nubus_num].addr == addr) - return nubus_num; - return -1; -} +extern int matchbyname(); + +static int nubusprint __P((void *aux, char *name)); +static void nubusattach __P((struct device *parent, struct device *self, + void *aux)); + +static int probe_slot __P((int slot, nubus_slot *fmt)); +static u_long IncPtr __P((nubus_slot *fmt, u_long base, long amt)); +static u_long nubus_calc_CRC __P((nubus_slot *fmt)); +static u_char GetByte __P((nubus_slot *fmt, u_long ptr)); +static u_short GetWord __P((nubus_slot *fmt, u_long ptr)); +static u_long GetLong __P((nubus_slot *fmt, u_long ptr)); + +struct cfdriver nubuscd = { + NULL, "nubus", matchbyname, nubusattach, + DV_DULL, sizeof(struct nubus_softc), 1 +}; static void -find_nubus() +nubusattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - /* - * This function sets up the array "nubus_table" which contains the - * basic information about each card in the Nubus slot. When device - * drivers are initialized later, they can look through this array to - * see if their hardware is present and claim it. - */ + nubus_slot fmtblock; + int i; - extern u_long NuBusBase; - register struct nubus_hw *nu; - int nubus_num; - - for (nubus_num = 0; nubus_num < NUBUS_MAXSLOTS; nubus_num++) - nubus_table[nubus_num].found = 0; /* Empty */ - - /* - * LAK: For now we can only check 9..F because that's all we map in - * locore.s. Eventually (i.e. near future) we should put THIS - * function in locore.s before enabling the MMU and only map the slots - * that have a card in them. Also, the next loop should go from 1 to - * 0xF inclusive (0 is "reserved") to cover all possible hardware. - * Even if the MacII only has 9..F, it won't hurt us to probe 1..8 - * also. - */ - for (nubus_num = 0; nubus_num < 6; nubus_num++) { - nu = nubus_table + nubus_num + 9; - nu->addr = (caddr_t) (NuBusBase + nubus_num * NBMEMSIZE); - nu->rom = nu->addr + NBROMOFFSET; - - if (!badbaddr(nu->addr + NBMEMSIZE - 1)) { - InitNubusSlot((u_long) nu->addr, &(nu->slot)); - - nu->found = 1; - nu->claimed = 0; /* No driver has claimed this - * slot yet */ + printf("\n"); + for ( i = NUBUS_MIN_SLOT; i <= NUBUS_MAX_SLOT; i++) { + if (probe_slot(i, &fmtblock)) { + config_found(self, &fmtblock, nubusprint); } } } static int -nubus_print(aux, name) - void *aux; - char *name; +nubusprint(aux, name) + void *aux; + char *name; { - struct nubus_hw *nu = (struct nubus_hw *) aux; - int i; + nubus_slot *fmt; + int slot; + char *info; + fmt = (nubus_slot *) aux; if (name) { - i = nu - nubus_table; - printf("%s: s:%d t:%d \"", - name, i, nu->slot.type); - printf("%s, ", nu->slot.name); - printf("%s\"", nu->slot.manufacturer); + printf("%s: Card in slot %d: Name: %s", name, fmt->slot, + nubus_get_card_name(fmt)); + printf("Vendor: %s, \n", + nubus_get_vendor(fmt, NUBUS_RSRC_VEND_ID)); + printf("Part: %s.\n", + nubus_get_vendor(fmt, NUBUS_RSRC_VEND_PART)); } return (UNCONF); } -static void -nubus_attach(parent, self, aux) - struct device *parent, *self; - void *aux; +/* + * Probe a given nubus slot. If a card is there and we can get the + * format block from it's clutching decl. ROMs, fill the format block + * and return non-zero. If we can't find a card there with a valid + * decl. ROM, return 0. + * + * First, we check to see if we can access the memory at the tail + * end of the slot. If so, then we check for a bytelanes byte. We + * could probably just return a failure status if we bus error on + * the first try, but there really is little reason not to go ahead + * and check the other three locations in case there's a wierd card + * out there. + * + * Checking for a card involves locating the "bytelanes" byte which + * tells us how to interpret the declaration ROM's data. The format + * block is at the top of the card's standard memory space and the + * bytelanes byte is at the end of that block. + * + * After some inspection of the bytelanes byte, it appears that it + * takes the form 0xXY where Y is a bitmask of the bytelanes in use + * and X is a bitmask of the lanes to ignore. Hence, (X ^ Y) == 0 + * and (less obviously), Y will have the upper N bits clear if it is + * found N bytes from the last possible location. Both that and + * the exclusive-or check are made. + * + * If a valid + */ +static u_char nbits[]={0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4}; +static int +probe_slot(slot, fmt) + int slot; + nubus_slot *fmt; { - register struct nubus_hw *nu; - int i; + caddr_t rom_probe; + u_long hdr; + u_char data; + int hdr_size, i; - printf("\n"); + fmt->bytelanes = 0; + fmt->slot = (u_long)slot; - find_nubus(); + rom_probe = (caddr_t) (NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE); - for (i = 0; i < 6; i++) { - nu = nubus_table + i + 9; + for (i = 4; i && (fmt->bytelanes == 0); i--) { - if (!nu->found) + rom_probe--; + + if (badbaddr(rom_probe)) continue; - if (config_found(self, nu, nubus_print)) - nu->claimed = 1; + if ((data = *rom_probe) == 0) + continue; + + if ( ((((data & 0xf0) >> 4) ^ (data & 0x0f)) == 0x0f) + && ((data & 0x0f) < (1 << i)) ) { + fmt->bytelanes = data; + fmt->step = nbits[(data & 0x0f)]; + } } +#ifdef DEBUG + if (fmt->bytelanes == 0) + printf("bytelanes not found for slot 0x%x.\n", slot); +#endif + + if (fmt->bytelanes == 0) + return 0; + +#ifdef DEBUG + printf("bytelanes of 0x%x found for slot 0x%x.\n", + fmt->bytelanes, slot); +#endif + + hdr_size = 20; + + /* + * Go ahead and attempt to load format header. + * First, we need to find the first byte beyond memory that + * would be valid. This is necessary for NUBUS_ROM_offset() + * to work. + */ + hdr = NUBUS_SLOT_TO_BASE(fmt->slot) + NBMEMSIZE; + i = 0x10 | (fmt->bytelanes & 0x0f); + while ((i & 1) == 0) { + hdr++; + i >>= 1; + } + fmt->top = hdr; + hdr = IncPtr(fmt, hdr, -hdr_size); +#ifdef DEBUG + printf("fmt->top is 0x%x, that minus 0x%x puts us at 0x%x.\n", + fmt->top, hdr_size, hdr); +#if 0 + for (i=1 ; i < 8 ; i++) { + printf("0x%x - 0x%x = 0x%x, + 0x%x = 0x%x.\n", + hdr, i, IncPtr(fmt, hdr, -i), + i, IncPtr(fmt, hdr, i)); + } +#endif +#endif + + fmt->directory_offset = 0xff000000 | GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->length = GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->crc = GetLong(fmt, hdr); + hdr = IncPtr(fmt, hdr, 4); + fmt->revision_level = GetByte(fmt, hdr); + hdr = IncPtr(fmt, hdr, 1); + fmt->format = GetByte(fmt, hdr); + hdr = IncPtr(fmt, hdr, 1); + fmt->test_pattern = GetLong(fmt, hdr); + +#if DEBUG +printf("Directory offset 0x%x\t", fmt->directory_offset); +printf("Length 0x%x\t", fmt->length); +printf("CRC 0x%x\n", fmt->crc); +printf("Revision level 0x%x\t", fmt->revision_level); +printf("Format 0x%x\t", fmt->format); +printf("Test Pattern 0x%x\n", fmt->test_pattern); +#endif + + if (fmt->test_pattern != NUBUS_ROM_TEST_PATTERN) { + printf("Nubus--test pattern invalid:\n"); + printf(" slot 0x%x, bytelanes 0x%x?\n", + fmt->slot, fmt->bytelanes); + printf(" read test 0x%x, compare with 0x%x.\n", + fmt->test_pattern, NUBUS_ROM_TEST_PATTERN); + return 0; + } + + /* Perform CRC */ + if (fmt->crc != nubus_calc_CRC(fmt)) { + printf("Nubus--crc check failed, slot 0x%x.\n", + fmt->slot); + return 0; + } + + return 1; } -extern int matchbyname(); +/* + * Compute byte offset on card, taking into account bytelanes. + * Base must be on a valid bytelane for this function to work. + * Return the new address. + * + * XXX -- There has GOT to be a better way to do this. + */ +static u_long +IncPtr(fmt, base, amt) + nubus_slot *fmt; + u_long base; + long amt; +{ + u_char b, t; -struct cfdriver nubuscd = { - NULL, "nubus", matchbyname, nubus_attach, - DV_DULL, sizeof(struct device), 1 -}; + if (!amt) + return base; + + if (amt < 0) { + amt = -amt; + b = fmt->bytelanes; + t = (b << 4); + b <<= (3 - (base & 0x3)); + while (amt) { + b <<= 1; + if (b == t) + b = fmt->bytelanes; + if (b & 0x08) + amt--; + base--; + } + return base; + } + + t = (fmt->bytelanes & 0xf) | 0x10; + b = t >> (base & 0x3); + while (amt) { + b >>= 1; + if (b == 1) + b = t; + if (b & 1) + amt--; + base++; + } + + return base; +} + +static u_long +nubus_calc_CRC(fmt) + nubus_slot *fmt; +{ +#if 0 + u_long base, ptr, crc_loc, sum; + int i; + + base = fmt->top; + crc_loc = NUBUS_ROM_offset(fmt, base, -12); + ptr = NUBUS_ROM_offset(fmt, base, -fmt->length); + + sum = 0; + while (ptr < base) + roll #1, sum + if (ptr == crc_loc) { + roll #3, sum + ptr = IncPtr(fmt, ptr, 3); + } else { + sum += GetByte(fmt, ptr); + } + ptr = IncPtr(fmt, ptr, 1); + } + + return sum; +#endif + return fmt->crc; +} + +static u_char +GetByte(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + return *(caddr_t)ptr; +} + +static u_short +GetWord(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + u_short s; + + s = (GetByte(fmt, ptr) << 8); + ptr = IncPtr(fmt, ptr, 1); + s |= GetByte(fmt, ptr); + return s; +} + +static u_long +GetLong(fmt, ptr) + nubus_slot *fmt; + u_long ptr; +{ + register u_long l; + register int i; + + l = 0; + for ( i = 0; i < 4; i++) { + l = (l << 8) | GetByte(fmt, ptr); + ptr = IncPtr(fmt, ptr, 1); + } + return l; +} + +void +nubus_get_main_dir(slot, dir_return) + nubus_slot *slot; + nubus_dir *dir_return; +{ + u_long off; + + dir_return->dirbase = IncPtr(slot, slot->top, + slot->directory_offset - 20); + dir_return->curr_ent = dir_return->dirbase; +} + +int +nubus_find_rsrc(slot, dir, rsrcid, dirent_return) + nubus_slot *slot; + nubus_dir *dir; + u_int8_t rsrcid; + nubus_dirent *dirent_return; +{ + u_long entry; + u_char byte; + + entry = dir->curr_ent; +#if DEBUG +printf("nubus_find_rsrc (0x%x,0x%x)\n", dir, rsrcid); +#endif + do { + byte = GetByte(slot, entry); +#if DEBUG +printf("\tFound rsrc 0x%x.\n", byte); +#endif + if (byte == rsrcid) { + dirent_return->myloc = entry; + dirent_return->rsrc_id = rsrcid; + entry = GetLong(slot, entry); + dirent_return->offset = (entry & 0x00ffffff); + return 1; + } + if (byte == 0xff) { + entry = dir->dirbase; + } else { + entry = IncPtr(slot, entry, 4); + } + } while (entry != (u_long) dir->curr_ent); + return 0; +} + +void +nubus_get_dir_from_rsrc(slot, dirent, dir_return) + nubus_slot *slot; + nubus_dirent *dirent; + nubus_dir *dir_return; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + dir_return->dirbase = IncPtr(slot, dirent->myloc, loc); + dir_return->curr_ent = dir_return->dirbase; +} + +int +nubus_get_ind_data(slot, dirent, data_return, nbytes) + nubus_slot *slot; + nubus_dirent *dirent; + caddr_t data_return; + int nbytes; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + loc = IncPtr(slot, dirent->myloc, loc); + + while (nbytes--) { + *data_return++ = GetByte(slot, loc); + loc = IncPtr(slot, loc, 1); + } + return 1; +} + +int +nubus_get_c_string(slot, dirent, data_return, max_bytes) + nubus_slot *slot; + nubus_dirent *dirent; + caddr_t data_return; + int max_bytes; +{ + u_long loc; + + if ((loc = dirent->offset) & 0x800000) { + loc |= 0xff000000; + } + loc = IncPtr(slot, dirent->myloc, loc); + + *data_return = '\0'; + while (max_bytes--) { + if ((*data_return++ = GetByte(slot, loc)) == 0) + return 1; + loc = IncPtr(slot, loc, 1); + } + return 0; +} + +static char *huh = "???"; + +char * +nubus_get_vendor(slot, rsrc) + nubus_slot *slot; + int rsrc; +{ +static char str_ret[64]; + nubus_dir dir; + nubus_dirent ent; + + nubus_get_main_dir(slot, &dir); + if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + return huh; + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_VENDORINFO, &ent) <= 0) + return huh; + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, rsrc, &ent) <= 0) + return huh; + + nubus_get_c_string(slot, &ent, str_ret, 64); + + return str_ret; +} + +char * +nubus_get_card_name(slot) + nubus_slot *slot; +{ +static char name_ret[64]; + nubus_dir dir; + nubus_dirent ent; + + nubus_get_main_dir(slot, &dir); + + if (nubus_find_rsrc(slot, &dir, 1, &ent) <= 0) + return huh; + + nubus_get_dir_from_rsrc(slot, &ent, &dir); + + if (nubus_find_rsrc(slot, &dir, NUBUS_RSRC_NAME, &ent) <= 0) + return huh; + + nubus_get_c_string(slot, &ent, name_ret, 64); + + return name_ret; +} diff --git a/sys/arch/mac68k/nubus/nubus.h b/sys/arch/mac68k/nubus/nubus.h index 7c62f4e4ee16..5cedaf7225fc 100644 --- a/sys/arch/mac68k/nubus/nubus.h +++ b/sys/arch/mac68k/nubus/nubus.h @@ -1,10 +1,7 @@ -/* $NetBSD: nubus.h,v 1.4 1995/04/21 02:48:01 briggs Exp $ */ +/* $NetBSD: nubus.h,v 1.5 1995/04/29 20:23:48 briggs Exp $ */ -/*- - * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * All rights reserved. +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -16,80 +13,219 @@ * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: - * This product includes software developed by the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define NUBUS_VIDEO 3 -#define NUBUS_NETWORK 4 -#define NUBUS_MOTHERBOARD 0x0a -#define NUBUS_MAXSLOTS 16 +/* + * Nubus cards in Macintoshes are identified by 4 16-bit numbers: + * Category: What is the main purpose of this card? + * Type: Within this overall category, what kind of card? + * DrSW: What software interface does it use? + * DrHW: What specific hardware is it? + * + * For example, the "Toby Frame Buffer" display card is + * Category 3 (display) + * Type 1 (video) + * DrSW 1 (Apple) + * and DrHW 1 (TFB). + */ -struct imagedata { - long whatTheHellIsThis; - long offset; - short rowbytes; - short top; - short left; - short right; - short bottom; - short version; - short packType; - short packSize; - long hRes; - long vRes; - short pixelType; - short pixelSize; +#define NUBUS_CATEGORY_BOARD 0x0001 + +#define NUBUS_CATEGORY_DISPLAY 0x0003 +#define NUBUS_TYPE_VIDEO 0x0001 +#define NUBUS_TYPE_LCD 0x0002 +#define NUBUS_DRSW_APPLE 0x0001 +#define NUBUS_DRHW_TFB 0x0001 +#define NUBUS_DRHW_M2HRVC 0x0013 +#define NUBUS_DRHW_MICRON 0x0146 + +#define NUBUS_CATEGORY_NETWORK 0x0004 +#define NUBUS_TYPE_ETHERNET 0x0001 +#define NUBUS_DRSW_3COM 0x0000 +#define NUBUS_DRSW_ASANTE 0x0104 +#define NUBUS_DRSW_DAYNA 0x0105 /* XXX */ +#define NUBUS_DRSW_INTERLAN 0x0106 /* XXX */ +#define NUBUS_DRHW_SONIC 0x0110 + +#define NUBUS_CATEGORY_FONT 0x0009 /* KanjiTalk Font Card? */ + +#define NUBUS_CATEGORY_CPU 0x000A +#define NUBUS_TYPE_68000 0x0002 +#define NUBUS_TYPE_68020 0x0003 +#define NUBUS_TYPE_68030 0x0004 +#define NUBUS_TYPE_68040 0x0005 + +/* + * This is the same as Apple's Format Block for a card, with the + * addition of a pointer to the base of the NuBUS slot. + * + * This basically describes a nubus card--this structure is held in the last + * N bytes of each valid card's declaration ROM. + */ +typedef struct _nubus_slot { + u_long top; + u_int8_t slot; + u_int8_t bytelanes; + u_int8_t step; + u_int32_t test_pattern; + u_int8_t format; + u_int8_t revision_level; + u_int32_t crc; + u_int32_t length; + u_int32_t directory_offset; +} nubus_slot; + +/* + * Just a structure to ease comparison of type for drivers, etc. + */ +typedef struct _nubus_type { + u_int16_t category; + u_int16_t type; + u_int16_t drsw; + u_int16_t drhw; +} nubus_type; + +/* + * nubus_dir is a structure that describes a nubus directory. + * The nubus*dir() functions should be used to traverse this. + */ +typedef struct _nubus_dir { + u_int32_t dirbase; + u_int32_t curr_ent; +} nubus_dir; + +/* + * This is the equivalent of an Apple sResource directory entry + * with the addition of a pointer to itself (essentially) for easy + * calculation of jump to indirect data. + */ +typedef struct _nubus_dirent { + u_int32_t myloc; + u_int8_t rsrc_id; + u_int32_t offset; +} nubus_dirent; + +/* + * This is the equivalent of an Apple sResource with the addition of + * a pointer back to the sResource directory from whence we came. + * + * According to the Apple documentation, each sResource is of one of the + * following forms: + * all: bits 31-24 Identification number + * + * offset: bits 23-0 Offset to long data, cString, sBlock, etc. + * word: bits 23-16 0x00 + * bits 15-0 word data + * byte: bits 23-8 0x0000 + * bits 7-0 byte data + * + * The last resource has id = 0xff and data = 0x000000. + */ +typedef struct _nubus_rsrc { + u_int32_t myloc; + u_int8_t id; + u_int32_t data; +} nubus_rsrc; + +/* Resource IDs for NUBUS_CATEGORY_* (All) */ +#define NUBUS_RSRC_TYPE 0x01 /* Type (required) */ +#define NUBUS_RSRC_NAME 0x02 /* Name (required) */ +#define NUBUS_RSRC_ICON 0x03 /* Icon */ +#define NUBUS_RSRC_DRVRDIR 0x04 /* Driver directory */ +#define NUBUS_RSRC_LOADREC 0x05 /* Load record for resource */ +#define NUBUS_RSRC_BOOTREC 0x06 /* Boot record */ +#define NUBUS_RSRC_FLAGS 0x07 /* sResource Flags */ +#define NUBUS_RSRC_HWDEVID 0x08 /* Hardware device ID */ +#define NUBUS_RSRC_MINOR_BASEOS 0x0A /* Offset to hw in std space */ +#define NUBUS_RSRC_MINOR_LENGTH 0x0B /* Length of std space */ +#define NUBUS_RSRC_MAJOR_BASEOS 0x0C /* Offset to hw in super space */ +#define NUBUS_RSRC_MAJOR_LENGTH 0x0D /* Length of super space */ +#define NUBUS_RSRC_CICN 0x0F /* Color icon */ +#define NUBUS_RSRC_ICL8 0x10 /* 8-bit icon data */ +#define NUBUS_RSRC_ICL4 0x11 /* 4-bit icon data */ + +/* Resource IDs for NUBUS_CATEGORY_DISPLAY */ +#define NUBUS_RSRC_GAMMADIR 0x40 /* ID for gamma directory */ +#define NUBUS_RSRC_VIDNAMES 0x41 /* ID for video name directory */ +#define NUBUS_RSRC_FIRSTMODE 0x80 /* ID for first mode (1-bit) */ +#define NUBUS_RSRC_SECONDMODE 0x81 /* ID for 2nd mode (2-bit) */ +#define NUBUS_RSRC_THIRDMODE 0x82 /* ID for 3rd mode (4-bit) */ +#define NUBUS_RSRC_FOURTHMODE 0x83 /* ID for 4th mode (8-bit) */ +#define NUBUS_RSRC_FIFTHMODE 0x84 /* ID for 5th mode (16-bit) */ +#define NUBUS_RSRC_SIXTHMODE 0x85 /* ID for 6th mode (32-bit) */ + +/* Resource IDs for NUBUS_CATEGORY_BOARD */ +#define NUBUS_RSRC_BOARDID 0x20 /* Board ID */ +#define NUBUS_RSRC_PRAMINITDATA 0x21 /* Private board data for PRAM */ +#define NUBUS_RSRC_PRIMARYINIT 0x22 /* Primary init record */ +#define NUBUS_RSRC_TIMEOUTCONST 0x23 /* Timeout constant */ +#define NUBUS_RSRC_VENDORINFO 0x24 /* Vendor info list */ +#define NUBUS_RSRC_BOARDFLAGS 0x25 /* Board flags */ +#define NUBUS_RSRC_SECONDINIT 0x26 /* Secondary init record */ + +#define NUBUS_RSRC_VEND_ID 0x01 /* Card vendor's design ID */ +#define NUBUS_RSRC_VEND_SERIAL 0x02 /* Card's serial number */ +#define NUBUS_RSRC_VEND_REV 0x03 /* Card design's revision level */ +#define NUBUS_RSRC_VEND_PART 0x04 /* Card part number */ +#define NUBUS_RSRC_VEND_DATE 0x05 /* Card revision date */ + +typedef struct _NUBUS_DRIVER { + u_int8_t drvr_id; + u_int32_t offset; +} NUBUS_DRIVER; + +typedef struct _NUBUS_BLOCK { + u_int32_t size; /* Size of block of data */ + caddr_t data; /* Pointer to data */ +} NUBUS_BLOCK; + +typedef struct _NUBUS_EXEC_BLOCK { + u_int32_t size; /* Size of total block - 4 */ + u_int8_t revision; /* Always 0x2 */ + u_int8_t cpu; /* Which processor? */ + u_int32_t code_offset; /* Offset base to start of code */ + caddr_t code; /* pointer to base of code. */ +} NUBUS_EXEC_BLOCK; + +#define NUBUS_EXEC_CPU_68000 1 +#define NUBUS_EXEC_CPU_68020 2 +#define NUBUS_EXEC_CPU_68030 3 +#define NUBUS_EXEC_CPU_68040 4 + +#define NUBUS_MIN_SLOT 0x9 +#define NUBUS_MAX_SLOT 0xE +#define NUBUS_ROM_TEST_PATTERN 0x5A932BC7 + +#define NUBUS_BASE_TO_SLOT(x) (((x) >> 24) & 0x0F) +#define NUBUS_SLOT_TO_BASE(x) (0xF0000000 | (((x) & 0xF) << 24)) + +struct nubus_softc { + struct device sc_dev; }; -/* this is the main data structure that points to good stuff */ -struct header { - long offset; - long length; - long crc; - char romrev; - char format; - long tst; - char reserved; - char bytelane; -}; +void nubus_get_main_dir __P((nubus_slot *slot, nubus_dir *dir_return)); +int nubus_find_rsrc __P((nubus_slot *slot, nubus_dir *dir, u_int8_t rsrcid, + nubus_dirent *dirent_return)); +void nubus_get_dir_from_rsrc __P((nubus_slot *slot, nubus_dirent *dirent, + nubus_dir *dir_return)); +int nubus_get_ind_data __P((nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int nbytes)); +int nubus_get_c_string __P((nubus_slot *slot, nubus_dirent *dirent, + caddr_t data_return, int max_bytes)); +char *nubus_get_vendor __P((nubus_slot *slot, int rsrc)); +char *nubus_get_card_name __P((nubus_slot *slot)); -/* this is what the directory entries contain */ -struct dir { - unsigned char rsrc; - unsigned long offset; - unsigned long base; -}; - -/* describe a single slot */ -struct slot { - int size; - struct header head; - struct dir mainDir[15]; - long type; - char name[40]; - char manufacturer[40]; -}; - -struct nubus_hw { - int found; /* If there is a card there */ - caddr_t addr; /* Phys addr of start of card */ - caddr_t rom; /* Phys addr of start of ROM */ - int claimed; /* TRUE if a driver claims this */ - struct slot slot; /* MF NUBUS STUFF */ - /* any other Nubus stuff we can think of when we get */ - /* the NuBus documentation */ -}; diff --git a/sys/arch/mac68k/obio/grf_obio.c b/sys/arch/mac68k/obio/grf_obio.c new file mode 100644 index 000000000000..5b77d0ef58ea --- /dev/null +++ b/sys/arch/mac68k/obio/grf_obio.c @@ -0,0 +1,101 @@ +/* $NetBSD: grf_obio.c,v 1.1 1995/04/29 20:23:41 briggs Exp $ */ + +/* + * Copyright (c) 1995 Allen Briggs. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Allen Briggs. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/* + * Graphics display driver for the Macintosh internal video for machines + * that don't map it into a fake nubus card. + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "nubus.h" +#include "grfvar.h" + +extern int grfiv_probe __P((struct grf_softc *sc, nubus_slot *ignore)); +extern int grfiv_init __P((struct grf_softc *sc)); +extern int grfiv_mode __P((struct grf_softc *sc, int cmd, void *arg)); + +extern int +grfiv_probe(sc, ignore) + struct grf_softc *sc; + nubus_slot *ignore; +{ + extern unsigned long int_video_start; + + if (int_video_start == 0) { + return 0; + } + return 1; +} + +extern int +grfiv_init(sc) + struct grf_softc *sc; +{ + struct grfmode *gm; + int i, j; + + sc->card_id = 0; + + strcpy(sc->card_name, "Internal video"); + + gm = &(sc->curr_mode); + gm->mode_id = 0; + gm->psize = 1; + gm->ptype = 0; + gm->width = 640; /* XXX */ + gm->height = 480; /* XXX */ + gm->rowbytes = 80; /* XXX Hack */ + gm->hres = 80; /* XXX Hack */ + gm->vres = 80; /* XXX Hack */ + gm->fbsize = gm->width * gm->height; + gm->fbbase = (caddr_t) 0; + + return 1; +} + +extern int +grfiv_mode(sc, cmd, arg) + struct grf_softc *sc; + int cmd; + void *arg; +{ + return 0; +}