|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.