Annotation of researchv9/sys/sundev/bwtwo.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static  char sccsid[] = "@(#)bwtwo.c 1.1 86/02/03 Copyr 1985 Sun Micro";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 1986 by Sun Microsystems, Inc.
        !             7:  */
        !             8: 
        !             9: /*
        !            10:  * Sun Two Black & White Board(s) Driver
        !            11:  */
        !            12: 
        !            13: #include "bwtwo.h"
        !            14: 
        !            15: #include "../h/param.h"
        !            16: #include "../h/systm.h"
        !            17: #include "../h/dir.h"
        !            18: #include "../h/user.h"
        !            19: #include "../h/proc.h"
        !            20: #include "../h/buf.h"
        !            21: #include "../h/conf.h"
        !            22: #include "../h/file.h"
        !            23: #include "../h/map.h"
        !            24: #include "../h/vmmac.h"
        !            25: 
        !            26: #include "../sun/fbio.h"
        !            27: 
        !            28: #include "../machine/pte.h"
        !            29: #include "../machine/mmu.h"
        !            30: #include "../machine/cpu.h"
        !            31: 
        !            32: #include "../sundev/mbvar.h"
        !            33: #include "../sundev/bw2reg.h"
        !            34: 
        !            35: #ifdef sun3
        !            36: #include "../sun3/eeprom.h"
        !            37: #endif sun3
        !            38: 
        !            39: extern char    CADDR1[];
        !            40: 
        !            41: int    copyenpfnum;    /* pfnum before shadow memory mapped in */
        !            42: caddr_t        copyenvirt = 0; /* virtual address mapped to shadow memory */
        !            43: 
        !            44: struct bw2_softc {
        !            45:        caddr_t image;
        !            46: } bw2_softc[NBWTWO];
        !            47: 
        !            48: #define        BW2SIZEX        1152
        !            49: #define        BW2SIZEY        900
        !            50: #define        BW2SQUARESIZEX  1024
        !            51: #define        BW2SQUARESIZEY  1024
        !            52: 
        !            53: /*
        !            54:  * Driver information for auto-configuration stuff.
        !            55:  */
        !            56: int    bwtwoprobe(), bwtwoattach(), bwtwointr();
        !            57: struct mb_device *bwtwoinfo[NBWTWO];
        !            58: struct mb_driver bwtwodriver = {
        !            59:        bwtwoprobe, 0, bwtwoattach, 0, 0, bwtwointr,
        !            60:        sizeof (struct bw2dev) + CLBYTES /* XXX */, "bwtwo", bwtwoinfo, 0, 0, 0,
        !            61: };
        !            62: 
        !            63: /*
        !            64:  * Only allow opens for writing or reading and writing
        !            65:  * because reading is nonsensical.
        !            66:  */
        !            67: bwtwoopen(dev, flag)
        !            68:        dev_t dev;
        !            69: {
        !            70: 
        !            71:        fbopen(dev, flag, NBWTWO, bwtwoinfo);
        !            72: }
        !            73: 
        !            74: bwtwoclose(dev, flag)
        !            75:        dev_t dev;
        !            76: {
        !            77: }
        !            78: 
        !            79: /*ARGSUSED*/
        !            80: bwtwommap(dev, off, prot)
        !            81:        dev_t dev;
        !            82:        off_t off;
        !            83:        int prot;
        !            84: {
        !            85:        register caddr_t hold;
        !            86:        register int unit = minor(dev);
        !            87:        int page;
        !            88: 
        !            89:        hold = bwtwoinfo[unit]->md_addr;
        !            90:        bwtwoinfo[unit]->md_addr = bw2_softc[unit].image;
        !            91:        page = fbmmap(dev, off, prot, NBWTWO, bwtwoinfo, BW2_FBSIZE);
        !            92:        bwtwoinfo[unit]->md_addr = hold;
        !            93:        return (page);
        !            94: }
        !            95: 
        !            96: /*
        !            97:  * Determine if a bwtwo exists at the given address.
        !            98:  */
        !            99: /*ARGSUSED*/
        !           100: bwtwoprobe(reg, unit)
        !           101:        caddr_t reg;
        !           102:        int     unit;
        !           103: {
        !           104: #ifdef sun3
        !           105:        /* 
        !           106:         * For the sun3 we have to rely on the machine type since the bits 
        !           107:         * in the enable register may not be reliable.
        !           108:         */
        !           109:        int result;
        !           110: 
        !           111:        /*
        !           112:         * XXX - kludge used to get around current mem_rop bug.
        !           113:         * We need to have the page before the frame buffer to not have
        !           114:         * have any "holes" in them as the mem_rop code will sometimes
        !           115:         * access this page.  We kludge here to avoid this problem by
        !           116:         * increasing the size of area to be mapped by adding CLBYTES
        !           117:         * to the device size mapped by the autoconfig code.  Here
        !           118:         * we remap all but the first page so that the first page map
        !           119:         * entry is duplicated and then we bump the virtual address
        !           120:         * up by CLBYTES in bwtwoattach().
        !           121:         */
        !           122:        mapin(&Sysmap[btoc(reg + CLBYTES - KERNELBASE)],
        !           123:            (u_int)btoc(reg + CLBYTES),
        !           124:            ((*(u_int *)&Sysmap[btoc(reg - KERNELBASE)]) & PG_PFNUM),
        !           125:            btoc(BW2_FBSIZE), PG_V | PG_KW);
        !           126: 
        !           127:        switch (cpu) {
        !           128:        case CPU_SUN3_160:
        !           129:                result = BW2_FBSIZE;
        !           130:                break;
        !           131:        case CPU_SUN3_50:
        !           132:                result = BW2_FBSIZE;
        !           133:                break;
        !           134:        case CPU_SUN3_260:
        !           135:                result = 0;
        !           136:                break;
        !           137:        default:
        !           138:                result = 0;
        !           139:                break;
        !           140:        }
        !           141:        return (result);
        !           142: #endif sun3
        !           143: #ifdef sun2
        !           144:        struct  bw2dev *bw2dev = (struct bw2dev *)(reg + CLBYTES); /* XXX */
        !           145:        register struct bw2cr *alias1;
        !           146:        register struct bw2cr *alias2;
        !           147:        short   w1;
        !           148:        register short  w2, wrestore;
        !           149:        int     result = 0;
        !           150: 
        !           151:        /*
        !           152:         * XXX - kludge used to get around current mem_rop bug.
        !           153:         * We need to have the page before the frame buffer to not have
        !           154:         * have any "holes" in them as the mem_rop code will sometimes
        !           155:         * access this page.  We kludge here to avoid this problem by
        !           156:         * increasing the size of area to be mapped by adding CLBYTES
        !           157:         * to the device size mapped by the autoconfig code.  Here
        !           158:         * we remap all but the first page so that the first page map
        !           159:         * entry is duplicated and then we bump the virtual address
        !           160:         * up by CLBYTES above for bw2dev and in bwtwoattach().
        !           161:         */
        !           162:        mapin(&Sysmap[btoc(reg + CLBYTES - KERNELBASE)],
        !           163:            (u_int)btoc(reg + CLBYTES),
        !           164:            ((*(u_int *)&Sysmap[btoc(reg - KERNELBASE)]) & PG_PFNUM),
        !           165:            btoc(BW2_FBSIZE), PG_V | PG_KW);
        !           166: 
        !           167:        bw2crmapin(bw2dev);
        !           168:        alias1 = &bw2dev->bw2cr;
        !           169:        alias2 = alias1 + 1;
        !           170: 
        !           171:        /*
        !           172:         * Two adjacent shorts should be the same because
        !           173:         * the control register is replicated every 2 bytes
        !           174:         * throughout the control page.
        !           175:         */
        !           176:        if ((w1 = peek((short *)alias1)) == -1)
        !           177:                return (0);
        !           178:        wrestore = w1;
        !           179:        ((struct bw2cr *)&w1)->vc_copybase = 0xAA & BW2_COPYBASEMASK;
        !           180:        if (poke((short *)alias1, w1))
        !           181:                return (0);
        !           182:        if ((w2 = peek((short *)alias2)) == -1)
        !           183:                goto restore;
        !           184:        if (w1 != w2)
        !           185:                goto restore;
        !           186:        ((struct bw2cr *)&w1)->vc_copybase = ~0xAA & BW2_COPYBASEMASK;
        !           187:        if (poke((short *)alias1, w1))
        !           188:                goto restore;
        !           189:        if ((w2 = peek((short *)alias2)) == -1)
        !           190:                goto restore;
        !           191:        if (w1 != w2)
        !           192:                goto restore;
        !           193:        result = BW2_FBSIZE;
        !           194: restore:
        !           195:        if (poke((short *)alias1, wrestore))
        !           196:                panic("bwtwoprobe");
        !           197:        return (result);
        !           198: #endif sun2
        !           199: }
        !           200: 
        !           201: /*
        !           202:  * Set up the softc structure
        !           203:  */
        !           204: bwtwoattach(md)
        !           205: register struct mb_device *md;
        !           206: {
        !           207: #ifdef sun2
        !           208:        register struct bw2dev *bw2dev;
        !           209: #endif
        !           210:        int     pfnum;
        !           211:        caddr_t fbvirtaddr;
        !           212:        caddr_t v;
        !           213:        int     i;
        !           214: 
        !           215:        /*
        !           216:         * XXX - Last part of mem_rop bug kludge, increase the virtual
        !           217:         * address set up by autoconfig by CLBYTES as we have remapped
        !           218:         * the first page to be a duplicate in bwtwoprobe().
        !           219:         */
        !           220:        md->md_addr += CLBYTES;
        !           221: 
        !           222:        pfnum = getkpgmap(md->md_addr) & PG_PFNUM;
        !           223: #ifdef sun3
        !           224:        /*
        !           225:         * If we are on a SUN3_50 (Model 25), then we must
        !           226:         * reserve the on board memory for the frame buffer.
        !           227:         */
        !           228:        if (cpu == CPU_SUN3_50) {
        !           229:                if (fbobmemavail == 0)
        !           230:                        panic("No video memory");
        !           231:                else
        !           232:                        fbobmemavail = 0;
        !           233:        }
        !           234: #endif sun3
        !           235: 
        !           236:        /*
        !           237:         * Have we passed this way before? 
        !           238:         */
        !           239:        if (fbobmemavail == 0) {
        !           240:                if (copyenvirt == 0) {
        !           241:                        copyenvirt = (caddr_t)(*romp->v_fbaddr);
        !           242:                        if (pfnum == copyenpfnum)
        !           243:                                bw2_softc[md->md_unit].image = copyenvirt;
        !           244:                        else
        !           245:                                bw2_softc[md->md_unit].image = md->md_addr;
        !           246:                }
        !           247:                return;
        !           248:        }
        !           249: 
        !           250:        /* 
        !           251:         * We know that the copy memory can be used.  Use the
        !           252:         * shadow memory if the config flags say to use it.
        !           253:         */
        !           254:        if ((md->md_flags & BW2_USECOPYMEM) == 0) {
        !           255:                /* don't bother using reserved shadow memory */
        !           256:                copyenvirt  = md->md_addr;
        !           257:                bw2_softc[md->md_unit].image = md->md_addr;
        !           258:                return;
        !           259:        }
        !           260: 
        !           261:        /*
        !           262:         * Mark the onboard frame buffer memory as not available
        !           263:         * anymore as we are going to use it for copy memory.
        !           264:         */
        !           265:        fbobmemavail = 0;
        !           266: 
        !           267:        if (*romp->v_outsink != OUTSCREEN || *romp->v_fbtype != FBTYPE_SUN2BW)
        !           268:                fbvirtaddr = (caddr_t)md->md_addr;
        !           269:        else {
        !           270:                rmfree(kernelmap, (long)btoc(BW2_FBSIZE), 
        !           271:                          btokmx((struct pte *)(md->md_addr)));
        !           272:                mapout(&Usrptmap[btokmx((struct pte *)(md->md_addr))], 
        !           273:                          btoc(BW2_FBSIZE));
        !           274:                fbvirtaddr = (caddr_t)(*romp->v_fbaddr);
        !           275:        } 
        !           276:        copyenvirt = fbvirtaddr;
        !           277:        copyenpfnum = getkpgmap(fbvirtaddr) & PG_PFNUM;
        !           278: 
        !           279:        /*
        !           280:         * Copy the current frame buffer memory
        !           281:         * to the copy memory as we map it in.
        !           282:         */
        !           283:        for (v = (caddr_t)fbvirtaddr, i = btop(OBFBADDR);
        !           284:            i < btop(OBFBADDR + BW2_FBSIZE); v += NBPG, i++) {
        !           285:                mapin(CMAP1, btop(CADDR1),
        !           286:                    (u_int)(i | PGT_OBMEM), 1, PG_V | PG_KW);
        !           287:                bcopy(v, CADDR1, NBPG);
        !           288:                setpgmap(v, (long)(PG_V|PG_KW|PGT_OBMEM|i));
        !           289:        }
        !           290: 
        !           291: #ifdef sun2
        !           292:        bw2dev = (struct bw2dev *)md->md_addr;
        !           293:        i = (OBFBADDR>>BW2_COPYSHIFT) | BW2_COPYENABLEMASK;
        !           294:        (void) bwtwosetcr(&bw2dev->bw2cr, i, 1);
        !           295: #endif sun2
        !           296: #ifdef sun3
        !           297:        setcopyenable();
        !           298: #endif
        !           299:        if (pfnum == copyenpfnum)
        !           300:                bw2_softc[md->md_unit].image = copyenvirt;
        !           301:        else
        !           302:                bw2_softc[md->md_unit].image = md->md_addr;
        !           303: }
        !           304: 
        !           305: /*ARGSUSED*/
        !           306: bwtwoioctl(dev, cmd, data, flag)
        !           307:        dev_t dev;
        !           308:        caddr_t data;
        !           309: {
        !           310:        register int unit = minor(dev);
        !           311: 
        !           312:        switch (cmd) {
        !           313: 
        !           314:        case FBIOGTYPE: {
        !           315:                register struct fbtype *fb = (struct fbtype *)data;
        !           316: #ifdef sun2
        !           317:                register struct bw2dev *bw2dev =
        !           318:                    (struct bw2dev *)bwtwoinfo[unit]->md_addr;
        !           319: #endif
        !           320:                fb->fb_type = FBTYPE_SUN2BW;
        !           321:                fb->fb_depth = 1;
        !           322:                fb->fb_cmsize = 2;
        !           323:                fb->fb_size = BW2_FBSIZE;
        !           324: #ifdef sun3
        !           325:                /*
        !           326:                 * Look at the eeprom for screen configuration,
        !           327:                 * if unknown default to standard sizes.
        !           328:                 */
        !           329:                switch (EEPROM->ee_diag.eed_scrsize) {
        !           330:                case EED_SCR_1024X1024:
        !           331:                        fb->fb_height = BW2SQUARESIZEY;
        !           332:                        fb->fb_width = BW2SQUARESIZEX;
        !           333:                        break;
        !           334: 
        !           335:                case EED_SCR_1152X900:
        !           336:                default:
        !           337:                        fb->fb_height = BW2SIZEY;
        !           338:                        fb->fb_width = BW2SIZEX;
        !           339:                        break;
        !           340:                }
        !           341: #endif sun3
        !           342: #ifdef sun2
        !           343:                /*
        !           344:                 * Check for "square screen" jumper
        !           345:                 */
        !           346:                if (cpu != CPU_SUN2_120 && bwtwoinfo[unit]->md_unit == 0 &&
        !           347:                    bw2dev->bw2cr.vc_1024_jumper) {
        !           348:                        fb->fb_height = BW2SQUARESIZEY;
        !           349:                        fb->fb_width = BW2SQUARESIZEX;
        !           350:                } else {
        !           351:                        fb->fb_height = BW2SIZEY;
        !           352:                        fb->fb_width = BW2SIZEX;
        !           353:                }
        !           354: #endif sun2
        !           355:                break;
        !           356:                }
        !           357: 
        !           358:        default:
        !           359:                u.u_error = ENOTTY;
        !           360:        }
        !           361: }
        !           362: 
        !           363: bwtwointr()
        !           364: {
        !           365:        int bwtwointclear();
        !           366: 
        !           367:        return (fbintr(NBWTWO, bwtwoinfo, bwtwointclear));
        !           368: }
        !           369: 
        !           370: /*
        !           371:  * Turn off interrupts on bwtwo board.
        !           372:  */
        !           373: #ifdef sun3
        !           374: /*ARGSUSED*/
        !           375: bwtwointclear(bw2dev)
        !           376:        struct  bw2dev *bw2dev;
        !           377: {
        !           378: 
        !           379:        (void) setintrenable(0);
        !           380:        return (0);
        !           381: }
        !           382: #endif sun3
        !           383: 
        !           384: #ifdef sun2
        !           385: bwtwointclear(bw2dev)
        !           386:        struct  bw2dev *bw2dev;
        !           387: {
        !           388:        int     int_active;
        !           389: 
        !           390:        int_active = bw2dev->bw2cr.vc_int;
        !           391:        (void) setintrenable(&bw2dev->bw2cr);
        !           392:        return (int_active);
        !           393: }
        !           394: 
        !           395: setvideoenable(bw2cr)
        !           396:        struct bw2cr *bw2cr;
        !           397: {
        !           398: 
        !           399:        bwtwosetcr(bw2cr, BW2_VIDEOENABLEMASK, 1);
        !           400: }
        !           401: 
        !           402: setintrenable(bw2cr)
        !           403:        struct bw2cr *bw2cr;
        !           404: {
        !           405: 
        !           406:        bwtwosetcr(bw2cr, BW2_INTENABLEMASK, 0);
        !           407: }
        !           408: 
        !           409: /*
        !           410:  * Special access approach to video ctrl register needed because byte writes,
        !           411:  * generated when do bit writes, replicates itself on the subsequent byte as
        !           412:  * well (this is a hardware bug).  Thus, we need to access the register as a
        !           413:  * word.  Also these routines assume that only one bit changes at a time.
        !           414:  */
        !           415: bwtwosetcr(bw2cr, mask, value)
        !           416:        struct  bw2cr *bw2cr;
        !           417:        short   mask;
        !           418:        int     value;
        !           419: {
        !           420:        register short  w;
        !           421: 
        !           422:        /*
        !           423:         * Read word from video control register.
        !           424:         */
        !           425:        w = *((short *)bw2cr);
        !           426:        /*
        !           427:         * Modify bit as requested.
        !           428:         */
        !           429:        if (value)
        !           430:                w |= mask;
        !           431:        else
        !           432:                w &= ~mask;
        !           433:        /*
        !           434:         * Write word back to video control register.
        !           435:         */
        !           436:        *((short *)bw2cr) = w;
        !           437:        return;
        !           438: }
        !           439: #endif sun2
        !           440: 
        !           441: #ifndef sun3
        !           442: /*
        !           443:  * Given the video base virtual address,
        !           444:  * map in the control register address.
        !           445:  * This lets us handle minor implementation differences.
        !           446:  */
        !           447: bw2crmapin(bw2dev)
        !           448:        struct bw2dev *bw2dev;
        !           449: {
        !           450:        struct bw2cr *bw2cr = &bw2dev->bw2cr;
        !           451:        int pte = getkpgmap((caddr_t)bw2dev);
        !           452:        int page, delta;
        !           453: 
        !           454:        page = pte & PGT_MASK;
        !           455: 
        !           456:        if (page == PGT_OBMEM)
        !           457:                delta = (int)BW2MB_CR - (int)BW2MB_FB;
        !           458:        else if (page == PGT_OBIO)
        !           459:                delta = (int)BW2VME_CR - (int)BW2VME_FB;
        !           460:        else
        !           461:                panic("bwtwocraddr");
        !           462: 
        !           463:        mapin(&Sysmap[btoc((u_int)bw2cr - KERNELBASE)], btoc(bw2cr),
        !           464:            pte + btoc(delta), 1, PG_V | (pte & PG_PROT));
        !           465: }
        !           466: #endif !sun3

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.