|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 University of Utah. ! 3: * Copyright (c) 1990 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Systems Programming Group of the University of Utah Computer ! 8: * Science Department. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by the University of ! 21: * California, Berkeley and its contributors. ! 22: * 4. Neither the name of the University nor the names of its contributors ! 23: * may be used to endorse or promote products derived from this software ! 24: * without specific prior written permission. ! 25: * ! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 36: * SUCH DAMAGE. ! 37: * ! 38: * from: Utah $Hdr: grf.c 1.31 91/01/21$ ! 39: * ! 40: * @(#)grf.c 7.8 (Berkeley) 5/7/91 ! 41: */ ! 42: ! 43: /* ! 44: * Graphics display driver for the AMIGA ! 45: * This is the hardware-independent portion of the driver. ! 46: * Hardware access is through the grfdev routines below. ! 47: */ ! 48: ! 49: #include "grf.h" ! 50: #if NGRF > 0 ! 51: ! 52: #include "param.h" ! 53: #include "proc.h" ! 54: #include "ioctl.h" ! 55: #include "file.h" ! 56: #include "malloc.h" ! 57: ! 58: #include "device.h" ! 59: #include "grfioctl.h" ! 60: #include "grfvar.h" ! 61: ! 62: #include "machine/cpu.h" ! 63: ! 64: #include "vm/vm.h" ! 65: #include "vm/vm_kern.h" ! 66: #include "vm/vm_page.h" ! 67: #include "vm/vm_pager.h" ! 68: ! 69: #include "specdev.h" ! 70: #include "vnode.h" ! 71: #include "mman.h" ! 72: ! 73: #include "ite.h" ! 74: #if NITE == 0 ! 75: #define iteon(u,f) ! 76: #define iteoff(u,f) ! 77: #endif ! 78: ! 79: int grfprobe(); ! 80: int cc_init(), cc_mode(); ! 81: int tg_init(), tg_mode(); ! 82: ! 83: struct grfdev grfdev[] = { ! 84: MANUF_BUILTIN, PROD_BUILTIN_DISPLAY, ! 85: cc_init, cc_mode, "custom chips", ! 86: MANUF_UNILOWELL, PROD_UNILOWELL_A2410, ! 87: tg_init, tg_mode, "A2410 TIGA board", ! 88: }; ! 89: int ngrfdev = sizeof(grfdev) / sizeof(grfdev[0]); ! 90: ! 91: struct driver grfdriver = { grfprobe, "grf" }; ! 92: struct grf_softc grf_softc[NGRF]; ! 93: ! 94: #ifdef DEBUG ! 95: int grfdebug = 0; ! 96: #define GDB_DEVNO 0x01 ! 97: #define GDB_MMAP 0x02 ! 98: #define GDB_IOMAP 0x04 ! 99: #define GDB_LOCK 0x08 ! 100: #endif ! 101: ! 102: /* ! 103: * XXX: called from ite console init routine. ! 104: * Does just what configure will do later but without printing anything. ! 105: */ ! 106: grfconfig() ! 107: { ! 108: register caddr_t addr; ! 109: register struct amiga_hw *hw; ! 110: register struct amiga_device *ad, *nad; ! 111: ! 112: for (hw = sc_table; hw->hw_type; hw++) { ! 113: if (!HW_ISDEV(hw, D_BITMAP)) ! 114: continue; ! 115: /* ! 116: * Found one, now match up with a logical unit number ! 117: */ ! 118: nad = NULL; ! 119: addr = hw->hw_kva; ! 120: for (ad = amiga_dinit; ad->amiga_driver; ad++) { ! 121: if (ad->amiga_driver != &grfdriver || ad->amiga_alive) ! 122: continue; ! 123: /* ! 124: * Wildcarded. If first, remember as possible match. ! 125: */ ! 126: if (ad->amiga_addr == NULL) { ! 127: if (nad == NULL) ! 128: nad = ad; ! 129: continue; ! 130: } ! 131: /* ! 132: * Not wildcarded. ! 133: * If exact match done searching, else keep looking. ! 134: */ ! 135: if (((hw->hw_manufacturer << 16) | hw->hw_product) ! 136: == ad->amiga_addr) { ! 137: nad = ad; ! 138: break; ! 139: } ! 140: } ! 141: /* ! 142: * Found a match, initialize ! 143: */ ! 144: if (nad && grfinit (nad)) ! 145: nad->amiga_addr = addr; ! 146: } ! 147: } ! 148: ! 149: /* ! 150: * Normal init routine called by configure() code ! 151: */ ! 152: grfprobe(ad) ! 153: struct amiga_device *ad; ! 154: { ! 155: struct grf_softc *gp = &grf_softc[ad->amiga_unit]; ! 156: ! 157: if ((gp->g_flags & GF_ALIVE) == 0 && ! 158: !grfinit (ad)) ! 159: return(0); ! 160: printf("grf%d: %d x %d ", ad->amiga_unit, ! 161: gp->g_display.gd_dwidth, gp->g_display.gd_dheight); ! 162: if (gp->g_display.gd_colors == 2) ! 163: printf("monochrome"); ! 164: else ! 165: printf("%d color", gp->g_display.gd_colors); ! 166: printf(" %s display\n", grfdev[gp->g_type].gd_desc); ! 167: return(1); ! 168: } ! 169: ! 170: grfinit(ad) ! 171: struct amiga_device *ad; ! 172: { ! 173: struct grf_softc *gp = &grf_softc[ad->amiga_unit]; ! 174: register struct grfdev *gd; ! 175: ! 176: for (gd = grfdev; gd < &grfdev[ngrfdev]; gd++) ! 177: if (((gd->gd_manuf << 16) | gd->gd_prod) == ad->amiga_addr) ! 178: break; ! 179: ! 180: if (gd < &grfdev[ngrfdev] && (*gd->gd_init)(gp, ad)) { ! 181: gp->g_type = gd - grfdev; ! 182: gp->g_flags = GF_ALIVE; ! 183: return(1); ! 184: } ! 185: return(0); ! 186: } ! 187: ! 188: /*ARGSUSED*/ ! 189: grfopen(dev, flags) ! 190: dev_t dev; ! 191: { ! 192: int unit = GRFUNIT(dev); ! 193: register struct grf_softc *gp = &grf_softc[unit]; ! 194: int error = 0; ! 195: ! 196: if (unit >= NGRF || (gp->g_flags & GF_ALIVE) == 0) ! 197: return(ENXIO); ! 198: if ((gp->g_flags & (GF_OPEN|GF_EXCLUDE)) == (GF_OPEN|GF_EXCLUDE)) ! 199: return(EBUSY); ! 200: /* ! 201: * First open. ! 202: * XXX: always put in graphics mode. ! 203: */ ! 204: error = 0; ! 205: if ((gp->g_flags & GF_OPEN) == 0) { ! 206: gp->g_flags |= GF_OPEN; ! 207: error = grfon(dev); ! 208: } ! 209: return(error); ! 210: } ! 211: ! 212: /*ARGSUSED*/ ! 213: grfclose(dev, flags) ! 214: dev_t dev; ! 215: { ! 216: register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 217: ! 218: (void) grfoff(dev); ! 219: (void) grfunlock(gp); ! 220: gp->g_flags &= GF_ALIVE; ! 221: return(0); ! 222: } ! 223: ! 224: /*ARGSUSED*/ ! 225: grfioctl(dev, cmd, data, flag, p) ! 226: dev_t dev; ! 227: caddr_t data; ! 228: struct proc *p; ! 229: { ! 230: register struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 231: int error; ! 232: ! 233: error = 0; ! 234: switch (cmd) { ! 235: ! 236: case GRFIOCGINFO: ! 237: bcopy((caddr_t)&gp->g_display, data, sizeof(struct grfinfo)); ! 238: break; ! 239: ! 240: case GRFIOCON: ! 241: error = grfon(dev); ! 242: break; ! 243: ! 244: case GRFIOCOFF: ! 245: error = grfoff(dev); ! 246: break; ! 247: ! 248: case GRFIOCMAP: ! 249: error = grfmmap(dev, (caddr_t *)data, p); ! 250: break; ! 251: ! 252: case GRFIOCUNMAP: ! 253: error = grfunmmap(dev, *(caddr_t *)data, p); ! 254: break; ! 255: ! 256: case GRFIOCSINFO: ! 257: error = grfsinfo (dev, (struct grfdyninfo *) data); ! 258: break; ! 259: ! 260: default: ! 261: error = EINVAL; ! 262: break; ! 263: ! 264: } ! 265: return(error); ! 266: } ! 267: ! 268: /*ARGSUSED*/ ! 269: grfselect(dev, rw) ! 270: dev_t dev; ! 271: { ! 272: if (rw == FREAD) ! 273: return(0); ! 274: return(1); ! 275: } ! 276: ! 277: grflock(gp, block) ! 278: register struct grf_softc *gp; ! 279: int block; ! 280: { ! 281: struct proc *p = curproc; /* XXX */ ! 282: int error; ! 283: extern char devioc[]; ! 284: ! 285: #ifdef DEBUG ! 286: if (grfdebug & GDB_LOCK) ! 287: printf("grflock(%d): dev %x flags %x lockpid %x\n", ! 288: p->p_pid, gp-grf_softc, gp->g_flags, ! 289: gp->g_lockp ? gp->g_lockp->p_pid : -1); ! 290: #endif ! 291: if (gp->g_lockp) { ! 292: if (gp->g_lockp == p) ! 293: return(EBUSY); ! 294: if (!block) ! 295: return(EAGAIN); ! 296: do { ! 297: gp->g_flags |= GF_WANTED; ! 298: if (error = tsleep((caddr_t)&gp->g_flags, ! 299: (PZERO+1) | PCATCH, devioc, 0)) ! 300: return (error); ! 301: } while (gp->g_lockp); ! 302: } ! 303: gp->g_lockp = p; ! 304: return(0); ! 305: } ! 306: ! 307: grfunlock(gp) ! 308: register struct grf_softc *gp; ! 309: { ! 310: #ifdef DEBUG ! 311: if (grfdebug & GDB_LOCK) ! 312: printf("grfunlock(%d): dev %x flags %x lockpid %d\n", ! 313: curproc->p_pid, gp-grf_softc, gp->g_flags, ! 314: gp->g_lockp ? gp->g_lockp->p_pid : -1); ! 315: #endif ! 316: if (gp->g_lockp != curproc) ! 317: return(EBUSY); ! 318: if (gp->g_flags & GF_WANTED) { ! 319: wakeup((caddr_t)&gp->g_flags); ! 320: gp->g_flags &= ~GF_WANTED; ! 321: } ! 322: gp->g_lockp = NULL; ! 323: return(0); ! 324: } ! 325: ! 326: /*ARGSUSED*/ ! 327: grfmap(dev, off, prot) ! 328: dev_t dev; ! 329: { ! 330: return(grfaddr(&grf_softc[GRFUNIT(dev)], off)); ! 331: } ! 332: ! 333: ! 334: grfon(dev) ! 335: dev_t dev; ! 336: { ! 337: int unit = GRFUNIT(dev); ! 338: struct grf_softc *gp = &grf_softc[unit]; ! 339: ! 340: /* ! 341: * XXX: iteoff call relies on devices being in same order ! 342: * as ITEs and the fact that iteoff only uses the minor part ! 343: * of the dev arg. ! 344: */ ! 345: iteoff(unit, 3); ! 346: return((*grfdev[gp->g_type].gd_mode) ! 347: (gp, (dev&GRFOVDEV) ? GM_GRFOVON : GM_GRFON)); ! 348: } ! 349: ! 350: grfoff(dev) ! 351: dev_t dev; ! 352: { ! 353: int unit = GRFUNIT(dev); ! 354: struct grf_softc *gp = &grf_softc[unit]; ! 355: int error; ! 356: ! 357: (void) grfunmmap(dev, (caddr_t)0, curproc); ! 358: error = (*grfdev[gp->g_type].gd_mode) ! 359: (gp, (dev&GRFOVDEV) ? GM_GRFOVOFF : GM_GRFOFF); ! 360: /* XXX: see comment for iteoff above */ ! 361: iteon(unit, 2); ! 362: return(error); ! 363: } ! 364: ! 365: grfsinfo(dev, dyninfo) ! 366: dev_t dev; ! 367: struct grfdyninfo *dyninfo; ! 368: { ! 369: int unit = GRFUNIT(dev); ! 370: struct grf_softc *gp = &grf_softc[unit]; ! 371: int error; ! 372: ! 373: error = grfdev[gp->g_type].gd_mode (gp, GM_GRFCONFIG, dyninfo); ! 374: /* XXX: see comment for iteoff above */ ! 375: itereinit (unit); ! 376: return(error); ! 377: } ! 378: ! 379: grfaddr(gp, off) ! 380: struct grf_softc *gp; ! 381: register int off; ! 382: { ! 383: register struct grfinfo *gi = &gp->g_display; ! 384: ! 385: #if 0 ! 386: /* control registers */ ! 387: if (off >= 0 && off < gi->gd_regsize) ! 388: return(((u_int)gi->gd_regaddr + off) >> PGSHIFT); ! 389: ! 390: /* frame buffer */ ! 391: if (off >= gi->gd_regsize && off < gi->gd_regsize+gi->gd_fbsize) { ! 392: off -= gi->gd_regsize; ! 393: return(((u_int)gi->gd_fbaddr + off) >> PGSHIFT); ! 394: } ! 395: #endif ! 396: /* bogus */ ! 397: return(-1); ! 398: } ! 399: ! 400: grfmmap(dev, addrp, p) ! 401: dev_t dev; ! 402: caddr_t *addrp; ! 403: struct proc *p; ! 404: { ! 405: struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 406: int len, error; ! 407: struct vnode vn; ! 408: struct specinfo si; ! 409: int flags; ! 410: ! 411: #ifdef DEBUG ! 412: if (grfdebug & GDB_MMAP) ! 413: printf("grfmmap(%d): addr %x\n", p->p_pid, *addrp); ! 414: #endif ! 415: len = gp->g_display.gd_regsize + gp->g_display.gd_fbsize; ! 416: flags = MAP_FILE|MAP_SHARED; ! 417: if (*addrp) ! 418: flags |= MAP_FIXED; ! 419: else ! 420: *addrp = (caddr_t)0x1000000; /* XXX */ ! 421: vn.v_type = VCHR; /* XXX */ ! 422: vn.v_specinfo = &si; /* XXX */ ! 423: vn.v_rdev = dev; /* XXX */ ! 424: error = vm_mmap(&p->p_vmspace->vm_map, (vm_offset_t *)addrp, ! 425: (vm_size_t)len, VM_PROT_ALL, flags, (caddr_t)&vn, 0); ! 426: return(error); ! 427: } ! 428: ! 429: grfunmmap(dev, addr, p) ! 430: dev_t dev; ! 431: caddr_t addr; ! 432: struct proc *p; ! 433: { ! 434: struct grf_softc *gp = &grf_softc[GRFUNIT(dev)]; ! 435: vm_size_t size; ! 436: int rv; ! 437: ! 438: #ifdef DEBUG ! 439: if (grfdebug & GDB_MMAP) ! 440: printf("grfunmmap(%d): dev %x addr %x\n", p->p_pid, dev, addr); ! 441: #endif ! 442: if (addr == 0) ! 443: return(EINVAL); /* XXX: how do we deal with this? */ ! 444: size = round_page(gp->g_display.gd_regsize + gp->g_display.gd_fbsize); ! 445: rv = vm_deallocate(p->p_vmspace->vm_map, (vm_offset_t)addr, size); ! 446: return(rv == KERN_SUCCESS ? 0 : EINVAL); ! 447: } ! 448: ! 449: ! 450: #endif /* NGRF > 0 */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.