|
|
1.1 ! root 1: static int blocked; ! 2: static int sg_hal; ! 3: ! 4: /* ! 5: * qq - sample device driver using absolute memory addressing ! 6: * ! 7: * All this device does is read/write video ram. ! 8: * It assumes that there is a monochrome adapter in use, so that video ! 9: * ram starts at segment B000; if color, this should be changed to B800. ! 10: * ! 11: * This driver does not do anything useful; it is intended to serve as ! 12: * an example. ! 13: */ ! 14: #include <sys/coherent.h> ! 15: #include <sys/stat.h> ! 16: #include <sys/uproc.h> ! 17: #include <sys/proc.h> ! 18: #include <sys/con.h> ! 19: #include <sys/errno.h> ! 20: #include <sys/sched.h> ! 21: #include <sys/seg.h> ! 22: #include <sys/types.h> ! 23: #include <sys/mmu.h> ! 24: ! 25: /* ! 26: * Definitions. ! 27: * ! 28: */ ! 29: #define MONOVIDEO 0xB000 /* monochrome text RAM segment */ ! 30: #define VIDLENGTH (2048*2) /* screen locations (2 bytes each) */ ! 31: ! 32: #define QQ_MAJOR 7 /* device major number */ ! 33: ! 34: /* ! 35: * Export Functions. ! 36: */ ! 37: int qqload(); ! 38: int qqopen(); ! 39: int qqclose(); ! 40: int qqread(); ! 41: int qqwrite(); ! 42: int qqunload(); ! 43: int qqioctl(); ! 44: int qqtime(); ! 45: ! 46: /* ! 47: * Import Functions ! 48: */ ! 49: int nulldev(); ! 50: int nonedev(); ! 51: ! 52: /* ! 53: * Configuration table. ! 54: */ ! 55: CON qqcon ={ ! 56: DFCHR, /* Flags */ ! 57: QQ_MAJOR, /* Major index */ ! 58: qqopen, /* Open */ ! 59: qqclose, /* Close */ ! 60: nulldev, /* Block */ ! 61: qqread, /* Read */ ! 62: qqwrite, /* Write */ ! 63: qqioctl, /* Ioctl */ ! 64: nulldev, /* Powerfail */ ! 65: qqtime, /* Timeout */ ! 66: qqload, /* Load */ ! 67: qqunload, /* Unload */ ! 68: nulldev /* Poll */ ! 69: }; ! 70: ! 71: /* ! 72: * Local variables. ! 73: */ ! 74: #ifdef _I386 ! 75: static paddr_t screen_fp; /* virtual address of screen base */ ! 76: #else ! 77: static faddr_t screen_fp; /* (far *) to access screen */ ! 78: static paddr_t screen_base; /* physical address of screen base */ ! 79: #endif ! 80: int qqopct; ! 81: ! 82: /* ! 83: * Load Routine. ! 84: */ ! 85: qqload() ! 86: { ! 87: /* ! 88: * Allocate a selector to map onto the video RAM. ptov() will ! 89: * return the first available selector of the 8,192 possible. ! 90: * This is time consuming, so we only want to do this as part ! 91: * of our initialization code and not on every access. ! 92: * ! 93: * Since we are operating in 286 protected mode (ugh), the ! 94: * second argument to ptov() must not exceed 0x10000L. ! 95: */ ! 96: #ifdef _I386 ! 97: screen_fp = map_pv(MONOVIDEO<<4, VIDLENGTH); ! 98: printf("qqload: screen_fp = %x = map_pv(%x, %x)\n", ! 99: screen_fp, MONOVIDEO<<4, VIDLENGTH); ! 100: #else ! 101: screen_base = (paddr_t)((long)(unsigned)MONOVIDEO << 4); ! 102: screen_fp = ptov(screen_base, (fsize_t)VIDLENGTH); ! 103: #endif ! 104: } ! 105: ! 106: qqunload() ! 107: { ! 108: /* ! 109: * We have to free up the selector now that we're done using it. ! 110: */ ! 111: #ifdef _I386 ! 112: unmap_pv(screen_fp); ! 113: #else ! 114: vrelse(screen_fp); ! 115: #endif ! 116: } ! 117: ! 118: /* ! 119: * Open Routine. ! 120: */ ! 121: qqopen( dev, mode ) ! 122: dev_t dev; ! 123: { ! 124: qqopct++; ! 125: printf("qqopen %d\n", qqopct); ! 126: } ! 127: ! 128: /* ! 129: * Close Routine. ! 130: */ ! 131: qqclose( dev ) ! 132: dev_t dev; ! 133: { ! 134: qqopct--; ! 135: printf("qqclose %d\n", qqopct); ! 136: } ! 137: ! 138: /* ! 139: * Read Routine. ! 140: */ ! 141: qqread( dev, iop ) ! 142: dev_t dev; ! 143: register IO * iop; ! 144: { ! 145: static int offset; ! 146: int c; ! 147: /* ! 148: * Read a character code from video RAM ! 149: * Start reading RAM just after where previous read ended ! 150: * ! 151: * Note that "offset" is the value of the displacement into ! 152: * the screen RAM. Any expression which results in a value ! 153: * which is less than VIDLENGTH is OK here. ! 154: */ ! 155: while(iop->io_ioc) { ! 156: c = ((char *)screen_fp)[offset]; ! 157: if(ioputc(c, iop) == -1) ! 158: break; ! 159: offset += 2; ! 160: offset %= VIDLENGTH; ! 161: } ! 162: } ! 163: ! 164: /* ! 165: * Write Routine. ! 166: */ ! 167: static char flab [] = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z "; ! 168: ! 169: qqwrite( dev, iop ) ! 170: dev_t dev; ! 171: register IO * iop; ! 172: { ! 173: int offset = 0; ! 174: int c; ! 175: ! 176: struct foob { long la, lb; } f; ! 177: ! 178: while (iop->io_ioc >= sizeof(f)) { ! 179: ioread(iop, &f, sizeof(f)); ! 180: #if MEMCPY ! 181: /* memcpy from struct f to virtual address */ ! 182: memcpy(screen_fp + offset, &f, sizeof(f)); ! 183: #else ! 184: /* struct assignment to virtual address (implicit memcpy) */ ! 185: * (struct foob *)(screen_fp + offset) = f; ! 186: #endif ! 187: offset += 2 * sizeof(f); /* skip attribute byte */ ! 188: } ! 189: ! 190: /* single character writes to virtual address */ ! 191: while ((c = iogetc(iop)) >= 0 && offset < VIDLENGTH) { ! 192: *(char *)(screen_fp + offset) = c; ! 193: *(char *)(screen_fp + offset + 1) ^= 0xff; ! 194: offset += 2; /* skip attribute byte */ ! 195: } ! 196: ! 197: ! 198: /* no virtual address used - xpcopy to physical destination */ ! 199: xpcopy(flab, (MONOVIDEO<<4)+320, 52, SEG_386_KD); ! 200: } ! 201: ! 202: int qqct; ! 203: ! 204: int ! 205: qqioctl(dev, com, vec) ! 206: dev_t dev; ! 207: int com; ! 208: struct sgttyb *vec; ! 209: { ! 210: if (com == 333) { ! 211: ukcopy(vec, screen_fp, 20); ! 212: sg_hal = vtosg(vec, 20); ! 213: drvl[QQ_MAJOR].d_time = 30; ! 214: blocked = 1; ! 215: qqct = 0; ! 216: } ! 217: while (blocked) { ! 218: #ifdef _I386 ! 219: if (x_sleep (& blocked, pritty, slpriSigCatch, ! 220: "qqioctl") == PROCESS_SIGNALLED) { ! 221: #else ! 222: v_sleep(&blocked, CVTTOUT, IVTTOUT, SVTTOUT, "qqioctl"); ! 223: if (nondsig ()) { /* signal? */ ! 224: #endif ! 225: u.u_error = EINTR; ! 226: break; ! 227: } ! 228: } ! 229: } ! 230: ! 231: int ! 232: qqtime() ! 233: { ! 234: int j; ! 235: char buffer[20 + 1]; ! 236: ! 237: buffer[20] = '\0'; ! 238: ! 239: j = --drvl[QQ_MAJOR].d_time; ! 240: ! 241: if ((j % 2) == 0) { ! 242: if (sg_hal) { ! 243: qqct += 20; ! 244: printf("qqtime: j=%d pxcopy(sg_hal=%x, dest=%x, len=%x, space=%x ", ! 245: j, sg_hal, screen_fp + qqct, 20, SEG_386_KD|SEG_VIRT); ! 246: pxcopy(sg_hal, buffer, 20, ! 247: SEG_386_KD|SEG_VIRT); ! 248: printf("buffer=%s\n", buffer); ! 249: pxcopy(sg_hal, screen_fp + qqct, 20, ! 250: SEG_386_KD|SEG_VIRT); ! 251: } else ! 252: putchar('?'); ! 253: } ! 254: ! 255: if (j == 0) { ! 256: printf("wakeup\n"); ! 257: blocked = 0; ! 258: wakeup(&blocked); ! 259: } ! 260: } ! 261: ! 262: int ! 263: vtosg(virt, size) ! 264: int virt; ! 265: int size; ! 266: { ! 267: register SR *srp; ! 268: register SEG *sp; ! 269: register caddr_t base; ! 270: int ret = 0; ! 271: ! 272: for (srp=u.u_segl; srp<&u.u_segl[NUSEG]; srp++) { ! 273: if ((sp=srp->sr_segp) == NULL) ! 274: continue; ! 275: #if 0 ! 276: /* ! 277: * Doing this check means string constants in text ! 278: * are inaccessible to system global memory. ! 279: */ ! 280: if ((srp->sr_flag&SRFDATA) == 0) ! 281: continue; ! 282: #endif ! 283: /* ! 284: * The following calculation is because the system represents ! 285: * the 'base' of a stack as its upper limit (because it is the ! 286: * upper limit that is fixed). ! 287: */ ! 288: base = srp->sr_base; ! 289: if (srp==&u.u_segl[SISTACK]) ! 290: base -= srp->sr_size; ! 291: ! 292: if (virt < base) ! 293: continue; ! 294: if (virt + size > base + sp->s_size) ! 295: continue; ! 296: ret = MAPIO(sp->s_vmem, virt - base); ! 297: } ! 298: return ret; ! 299: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.