|
|
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 <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: x_sleep(&blocked, pritty, slpriSigCatch, "qqioctl"); ! 220: #else ! 221: v_sleep(&blocked, CVTTOUT, IVTTOUT, SVTTOUT, "qqioctl"); ! 222: #endif ! 223: if (SELF->p_ssig && nondsig()) { /* signal? */ ! 224: u.u_error = EINTR; ! 225: break; ! 226: } ! 227: } ! 228: } ! 229: ! 230: int ! 231: qqtime() ! 232: { ! 233: int j; ! 234: char buffer[20 + 1]; ! 235: ! 236: buffer[20] = '\0'; ! 237: ! 238: j = --drvl[QQ_MAJOR].d_time; ! 239: ! 240: if ((j % 2) == 0) { ! 241: if (sg_hal) { ! 242: qqct += 20; ! 243: printf("qqtime: j=%d pxcopy(sg_hal=%x, dest=%x, len=%x, space=%x ", ! 244: j, sg_hal, screen_fp + qqct, 20, SEG_386_KD|SEG_VIRT); ! 245: pxcopy(sg_hal, buffer, 20, ! 246: SEG_386_KD|SEG_VIRT); ! 247: printf("buffer=%s\n", buffer); ! 248: pxcopy(sg_hal, screen_fp + qqct, 20, ! 249: SEG_386_KD|SEG_VIRT); ! 250: } else ! 251: putchar('?'); ! 252: } ! 253: ! 254: if (j == 0) { ! 255: printf("wakeup\n"); ! 256: blocked = 0; ! 257: wakeup(&blocked); ! 258: } ! 259: } ! 260: ! 261: int ! 262: vtosg(virt, size) ! 263: int virt; ! 264: int size; ! 265: { ! 266: register SR *srp; ! 267: register SEG *sp; ! 268: register caddr_t base; ! 269: int ret = 0; ! 270: ! 271: for (srp=u.u_segl; srp<&u.u_segl[NUSEG]; srp++) { ! 272: if ((sp=srp->sr_segp) == NULL) ! 273: continue; ! 274: #if 0 ! 275: /* ! 276: * Doing this check means string constants in text ! 277: * are inaccessible to system global memory. ! 278: */ ! 279: if ((srp->sr_flag&SRFDATA) == 0) ! 280: continue; ! 281: #endif ! 282: /* ! 283: * The following calculation is because the system represents ! 284: * the 'base' of a stack as its upper limit (because it is the ! 285: * upper limit that is fixed). ! 286: */ ! 287: base = srp->sr_base; ! 288: if (srp==&u.u_segl[SISTACK]) ! 289: base -= srp->sr_size; ! 290: ! 291: if (virt < base) ! 292: continue; ! 293: if (virt + size > base + sp->s_size) ! 294: continue; ! 295: ret = MAPIO(sp->s_vmem, virt - base); ! 296: } ! 297: return ret; ! 298: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.