|
|
1.1 root 1: /* $Header: /src386/STREAMS/coh.386/RCS/null.c,v 2.3 93/08/09 13:35:51 bin Exp Locker: bin $ */
2: /* (lgl-
3: * The information contained herein is a trade secret of Mark Williams
4: * Company, and is confidential information. It is provided under a
5: * license agreement, and may be copied or disclosed only under the
6: * terms of that agreement. Any reproduction or disclosure of this
7: * material without the express written authorization of Mark Williams
8: * Company or persuant to the license agreement is unlawful.
9: *
10: * COHERENT Version 2.3.37
11: * Copyright (c) 1982, 1983, 1984.
12: * An unpublished work by Mark Williams Company, Chicago.
13: * All rights reserved.
14: -lgl) */
15: /*
16: * Null and memory driver.
17: * Minor device 0 is /dev/null
18: * Minor device 1 is /dev/mem, physical memory
19: * Minor device 2 is /dev/kmem, kernel data
20: * Minor device 3 is /dev/cmos
21: * Minor device 4 is /dev/boot_gift
22: * Minor device 5 is /dev/clock
23: * Minor device 6 is /dev/ps
24: * Minor device 7 is /dev/kmemhi, virtual memory 0x8000_0000-0xFFFF_FFFF
25: * Minor device 11 is /dev/idle
26: *
27: * $Log: null.c,v $
28: * Revision 2.3 93/08/09 13:35:51 bin
29: * Kernel 82 changes
30: *
31: * Revision 2.2 93/07/26 14:28:57 nigel
32: * Nigel's R80
33: *
34: * Revision 1.7 93/04/14 10:06:37 root
35: * r75
36: *
37: * Revision 1.10 93/03/02 08:16:25 bin
38: * kernel 73 update
39: *
40: * Revision 1.6 92/11/09 17:10:54 root
41: * Just before adding vio segs.
42: *
43: * Revision 1.2 92/01/06 11:59:49 hal
44: * Compile with cc.mwc.
45: *
46: * Revision 1.1 88/03/24 16:14:04 src
47: * Initial revision
48: *
49: */
50:
51: /*
52: * The symbol "DANGEROUS" should be undefined for a production system.
53: */
54: #ifdef TRACER
55: #define NULL_IOCTL /* Allow ioctl()s for /dev/kmem. */
56: #define DANGEROUS /* Allow dangerous ioctl()s for /dev/null. */
57: #endif
58: #define IDLE_DEV
59:
60: #include <kernel/typed.h>
61:
62: #include <sys/coherent.h>
63: #include <sys/con.h>
64: #include <sys/errno.h>
65: #include <sys/stat.h>
66: #include <sys/inode.h>
67: #include <sys/seg.h>
68: #include <sys/coh_ps.h>
69: #include <sys/file.h>
70: #if defined NULL_IOCTL || defined IDLE_DEV
71: #include <sys/null.h>
72: #endif /* NULL_IOCTL || IDLE_DEV */
73:
74:
75: #if TRACER
76: #include <sys/buf.h>
77: #endif
78:
79: /* These are minor numbers. */
80: #define DEV_NULL 0 /* /dev/null */
81: #define DEV_MEM 1 /* /dev/mem */
82: #define DEV_KMEM 2 /* /dev/kmem */
83: #define DEV_CMOS 3 /* /dev/cmos */
84: #define DEV_BOOTGIFT 4 /* /dev/bootgift */
85: #define DEV_CLOCK 5 /* /dev/clock */
86: #define DEV_PS 6 /* /dev/ps */
87: #define DEV_KMEMHI 7 /* /dev/kmemhi */
88: #define DEV_IDLE 11 /* /dev/idle */
89:
90: #define KMEMHI_BASE 0x80000000
91: #define PXCOPY_LIM 4096
92:
93: /*
94: * CMOS devices are limited by an 8 bit address.
95: */
96: #define MAX_CMOS 255
97: #define CMOS_LEN 256
98:
99: /*
100: * The first 14 bytes of the CMOS are the clock.
101: */
102: #define MAX_CLOCK 13
103: #define CLOCK_LEN 14
104:
105: /*
106: * These are definitions for mucking with the CMOS clock.
107: */
108: #define SRA 10 /* Status Register A */
109: #define SRB 11 /* Status Register B */
110: #define SRC 12 /* Status Register C */
111: #define SRD 13 /* Status Register D */
112:
113: #define UIP 0x80 /* Update In Progress bit of SRA. */
114: #define NO_UPD 0x80 /* No Update bit of SRB. */
115:
116: /*
117: * Functions for configuration.
118: */
119: void nlopen();
120: void nlclose();
121: void nlread();
122: void nlwrite();
123: int nlioctl();
124: int nulldev();
125: int nonedev();
126:
127: /*
128: * Configuration table.
129: */
130: CON nlcon ={
131: DFCHR, /* Flags */
132: 0, /* Major index */
133: nlopen, /* Open */
134: nlclose, /* Close */
135: nulldev, /* Block */
136: nlread, /* Read */
137: nlwrite, /* Write */
138: #if defined NULL_IOCTL || defined IDLE_DEV
139: nlioctl, /* Ioctl */
140: #else /* NULL_IOCTL || IDLE_DEV */
141: nonedev, /* Ioctl */
142: #endif /* NULL_IOCTL || IDLE_DEV */
143: nulldev, /* Powerfail */
144: nulldev, /* Timeout */
145: nulldev, /* Load */
146: nulldev /* Unload */
147: };
148:
149: int lock_clock();
150: void unlock_clock();
151:
152: /*
153: * Null/memory open routine.
154: */
155: void
156: nlopen(dev, mode)
157: dev_t dev;
158: int mode;
159: {
160: switch (minor(dev)) {
161: #ifdef IDLE_DEV
162: case DEV_IDLE:
163: #endif
164: case DEV_PS:
165: /* /dev/ps is read only */
166: if (IPR != (IPR & mode))
167: SET_U_ERROR( EACCES, "/dev/ps is read only" );
168: break;
169: default:
170: /*
171: * For minor devices on NULL there is
172: * usually no action for open().
173: */
174: break;
175: }
176: return;
177: } /* nlopen() */
178:
179: /*
180: * Null/memory close routine.
181: */
182: void
183: nlclose(dev, mode)
184: dev_t dev;
185: int mode;
186: {
187: /*
188: * For minor devices on NULL there is
189: * Usually no action for close().
190: */
191: return;
192: } /* nlclose() */
193:
194: /*
195: * Null/memory read routine.
196: */
197: void
198: nlread(dev, iop)
199: dev_t dev;
200: register IO *iop;
201: {
202: register unsigned bytesRead;
203: register PROC *pp1; /* */
204: char psBuf[ARGSZ]; /* buffer for command line
205: * arguments for ps. */
206: stMonitor psData; /* All process data for */
207: UPROC *uprc; /* pointer to u area */
208: int ndpUseg; /* System global address
209: * of U segment */
210: unsigned int seek;
211: unsigned char read_cmos();
212: extern typed_space boot_gift;
213:
214: switch (minor (dev)) {
215: case DEV_NULL:
216: /*
217: * Read nothing.
218: * Do NOT update iop->io_ioc.
219: * This way, caller knows 0 bytes were read.
220: */
221: break;
222:
223: case DEV_MEM: {
224: int src = iop->io_seek;
225: int dest = iop->io.pbase;
226:
227: while (iop->io_ioc) {
228: int numBytes = PXCOPY_LIM;
229: if (numBytes > iop->io_ioc)
230: numBytes = iop->io_ioc;
231:
232: bytesRead = pxcopy (src, dest, numBytes,
233: SEG_386_UD | R_USR);
234: src += bytesRead;
235: dest += bytesRead;
236: iop->io_ioc -= bytesRead;
237: if (u.u_error == EFAULT) {
238: u.u_error = 0;
239: break;
240: }
241: }
242: break;
243: }
244:
245: case DEV_KMEM:
246: iowrite (iop, iop->io_seek, iop->io_ioc);
247: if (u.u_error == EFAULT)
248: u.u_error = 0;
249: break;
250:
251: case DEV_CLOCK:
252: /*
253: * Don't go past the end of the CLOCK.
254: */
255: if (iop->io_seek >= CLOCK_LEN)
256: break;
257:
258: /*
259: * Lock the clock before any reading.
260: */
261:
262: if (lock_clock () == 0) {
263: SET_U_ERROR (EIO, "RT clock will not settle.");
264: break;
265: }
266:
267: /*
268: * Read the requested data out of the CMOS.
269: */
270: for (seek = iop->io_seek; seek < CLOCK_LEN; seek++) {
271: if(ioputc(read_cmos(seek), iop) == -1)
272: break;
273: }
274:
275: /*
276: * Now that we are done reading the CMOS, let
277: * the clock loose.
278: */
279: unlock_clock();
280: break;
281:
282: case DEV_CMOS:
283: /*
284: * Don't go past the end of the CMOS.
285: */
286: if (iop->io_seek >= CMOS_LEN)
287: break;
288:
289: /*
290: * Read the requested data out of the CMOS.
291: */
292: for (seek = iop->io_seek; seek < CMOS_LEN; seek++) {
293: if(ioputc(read_cmos(seek), iop) == -1)
294: break;
295: }
296: break;
297:
298: case DEV_BOOTGIFT:
299: /*
300: * Reads all from the data structure boot_gift.
301: */
302: if (iop->io_seek < BG_LEN) {
303: bytesRead = iop->io_ioc;
304:
305: /*
306: * Copy no more than to the end of boot_gift.
307: */
308: if (iop->io_seek + bytesRead > BG_LEN)
309: bytesRead = BG_LEN - iop->io_seek;
310:
311: iowrite (iop, (char *) (& boot_gift) + iop->io_seek,
312: bytesRead);
313: }
314: break;
315:
316: case DEV_PS:
317: /* Lock the process table. It allows to have an atomic ps. */
318: lock (pnxgate);
319: /* Main driver loop. Go through all processes. Fill struct PS
320: * and send put to user buffer.
321: */
322: for (pp1 = & procq; (pp1 = pp1->p_nforw) != & procq; ) {
323: register int i; /* loop index */
324: register unsigned uLen, /* Process size */
325: uLenR; /* Real process size */
326: register SEG *sp; /* u area segment */
327: int work; /* virtual click number */
328:
329: /* Check if driver can send next proc data */
330: if (iop->io_ioc < sizeof (stMonitor))
331: break;
332:
333: /* Calculate the size of process. */
334: uLen = uLenR = 0;
335: for (i = 0 ; i < NUSEG ; i++) {
336: if ((sp = pp1->p_segp [i]) == NULL)
337: continue;
338: uLenR += sp->s_size;
339: if (i == SIUSERP || i == SIAUXIL)
340: continue;
341: uLen += sp->s_size;
342:
343: }
344:
345: /* Find u area for process pp1 */
346: sp = pp1->p_segp [SIUSERP];
347: ndpUseg = MAPIO (sp->s_vmem, U_OFFSET);
348: work = workAlloc ();
349: ptable1_v [work] =
350: sysmem.u.pbase [btocrd (ndpUseg)] | SEG_RW;
351: uprc = (UPROC *) (ctob (work) + U_OFFSET);
352: memcpy (psData.u_comm, uprc->u_comm, ARGSZ);
353: memcpy (psData.u_sleep, uprc->u_sleep, U_SLEEP_LEN);
354: workFree (work);
355:
356: #ifdef TRACER
357: if (strncmp (psData.u_sleep, "lock",
358: U_SLEEP_LEN) == 0) {
359: GATE * g = pp1->p_event;
360: printf ("[%d] locked at %x lock %s (%d) = %x\n",
361: pp1->p_pid, g, g->_name, g->_count,
362: g->_lock [0]);
363: }
364: if (strncmp (psData.u_sleep, "bpwait",
365: U_SLEEP_LEN) == 0) {
366: BUF * bp = pp1->p_event;
367: printf ("[%d] blocked on %x flags = %x\n",
368: pp1->p_pid, bp, bp->b_flag);
369: }
370: #endif
371:
372: /* fill up stMonitor */
373: psData.p_pid = pp1->p_pid;
374: psData.p_ppid = pp1->p_ppid;
375: psData.p_uid = pp1->p_uid;
376: psData.p_ruid = pp1->p_ruid;
377: psData.p_rgid = pp1->p_rgid;
378: psData.p_state = pp1->p_state;
379: psData.p_flags = pp1->p_flags;
380: psData.rrun = (char *) pp1 != pp1->p_event;
381: psData.p_event = pp1->p_event;
382: psData.p_ttdev = pp1->p_ttdev;
383: psData.p_nice = pp1->p_nice;
384: psData.size = (short) (uLen >> 10);
385: psData.rsize = (short) (uLenR >> 10);
386: psData.p_schedPri = pp1->p_schedPri;
387: psData.p_utime = pp1->p_utime;
388: psData.p_stime = pp1->p_stime;
389:
390: memcpy (psData.pr_argv, psBuf, ARGSZ);
391:
392: /* send data to user */
393: iowrite (iop, (char *) & psData, sizeof (stMonitor));
394: }
395: unlock (pnxgate);
396: break;
397:
398: case DEV_KMEMHI:
399: iowrite (iop, iop->io_seek - KMEMHI_BASE, iop->io_ioc);
400: if (u.u_error == EFAULT)
401: u.u_error = 0;
402: break;
403:
404: default:
405: SET_U_ERROR (ENXIO, "nlread(): illegal minor device for null");
406: }
407: return;
408: }
409:
410: /*
411: * Null/memory write routine.
412: */
413: void
414: nlwrite(dev, iop)
415: dev_t dev;
416: register IO *iop;
417: {
418: register unsigned bytesWrit;
419: unsigned write_cmos();
420: unsigned seek;
421: int ch;
422:
423: switch (minor (dev)) {
424: case DEV_NULL:
425: /*
426: * Tell caller all bytes were written.
427: */
428: iop->io_ioc = 0;
429: break;
430:
431: case DEV_MEM:
432: while (iop->io_ioc) {
433: int src = iop->io.pbase;
434: int dest = iop->io_seek;
435: int numBytes = PXCOPY_LIM;
436: if (numBytes > iop->io_ioc)
437: numBytes = iop->io_ioc;
438:
439: bytesWrit = xpcopy (src, dest, numBytes,
440: SEG_386_UD | R_USR);
441: src += bytesWrit;
442: dest += bytesWrit;
443: iop->io_ioc -= bytesWrit;
444: if (u.u_error == EFAULT) {
445: u.u_error = 0;
446: break;
447: }
448: }
449: break;
450:
451: case DEV_KMEM:
452: ioread (iop, iop->io_seek, iop->io_ioc);
453: break;
454:
455: case DEV_CLOCK:
456: /*
457: * Don't go past the end of the CLOCK.
458: */
459: if (iop->io_seek >= CLOCK_LEN)
460: break;
461:
462: /*
463: * Lock the clock before any writing.
464: */
465: if (lock_clock () == 0) {
466: SET_U_ERROR (EIO, "RT clock will not settle.");
467: break;
468: }
469:
470: /*
471: * Write the requested data into the CMOS.
472: */
473:
474: for (seek = iop->io_seek ; seek < CLOCK_LEN ; seek ++) {
475: if ((ch = iogetc (iop)) == -1)
476: break;
477: write_cmos (seek, ch);
478: }
479:
480: /*
481: * Now that we are done writing the CMOS, let
482: * the clock loose.
483: */
484: unlock_clock ();
485: break;
486:
487: case DEV_CMOS:
488: /*
489: * Don't go past the end of the CMOS.
490: */
491: if (iop->io_seek >= CMOS_LEN)
492: break;
493:
494: /*
495: * Write the requested data into the CMOS.
496: */
497: for (seek = iop->io_seek ; seek < CMOS_LEN ; seek ++) {
498: if ((ch = iogetc (iop)) == -1)
499: break;
500: write_cmos (seek, ch);
501: }
502: break;
503:
504: case DEV_BOOTGIFT:
505: /*
506: * /dev/bootgift is not writable.
507: */
508: break;
509:
510: case DEV_PS:
511: /*
512: * We should not be able to open /dev/ps to write.
513: * Just paranoya.
514: */
515: break;
516:
517: case DEV_KMEMHI:
518: ioread (iop, iop->io_seek - KMEMHI_BASE, iop->io_ioc);
519: break;
520:
521: default:
522: SET_U_ERROR (ENXIO,
523: "nlwrite(): illegal minor device for null");
524: }
525: return;
526: }
527:
528: #if defined NULL_IOCTL || defined IDLE_DEV /* Includes all of nlioctl(). */
529:
530: /*
531: * Do an ioctl call for /dev/null.
532: */
533: int
534: nlioctl(dev, cmd, vec)
535: dev_t dev;
536: int cmd;
537: char * vec;
538: {
539: /* Only /dev/kmem and /dev/idle have an ioctl. */
540: switch (minor (dev)) {
541: #ifdef NULL_IOCTL
542: case DEV_KMEM:
543: switch (cmd) {
544: #ifdef DANGEROUS
545: case NLCALL: /* Call a function. */
546: return docall (vec);
547: #endif /* DANGEROUS */
548: default:
549: SET_U_ERROR (EINVAL,
550: "nioctl(): illegal command for kmem");
551: return -1;
552: }
553: #endif /* NULL_IOCTL */
554: #ifdef IDLE_DEV
555: case DEV_IDLE:
556: if (cmd != NLIDLE) {
557: SET_U_ERROR (EINVAL,
558: "nioctl(): illegal command for idle");
559: return -1;
560: } else {
561: register PROC *pp;
562: register int *mem = vec;
563:
564:
565: pp = & procq; /* point to process queue */
566:
567: if (pp->p_pid != 0) {
568: while ((pp = pp->p_nforw) != &procq)
569: if (pp->p_pid == 0) /* idle process ? */
570: break;
571: }
572:
573: /*
574: * At this point, pp->p_utime and pp->p_stime contain
575: * the idle time of the system process
576: */
577:
578: if (pp->p_pid != 0)
579: putuwd (mem ++, 0);
580: else
581: putuwd (mem ++, pp->p_utime + pp->p_stime);
582: putuwd (mem, lbolt);
583: return 1;
584: }
585:
586: #endif /* IDLE_DEV */
587: default:
588: SET_U_ERROR(EINVAL, "illegal minor device for null ioctl");
589: return -1;
590: } /* switch on minor device */
591:
592: } /* nlioctl() */
593:
594: #endif /* NULL_IOCTL || IDLE_DEV */
595:
596: #ifdef DANGEROUS /* Includes all of docall(). */
597: /*
598: * MASSIVE SECURITY HOLE! This should NOT be included in a distribution
599: * system. Among other problems, it becomes possible to do "setuid(0)".
600: *
601: * Call a function with arguments.
602: *
603: * Takes an array of unsigned ints. The first element is the length of
604: * the whole array, the second element is a pointer to the function to
605: * call, all other elements are arguments. At most 5 arguments may be
606: * passed.
607: *
608: * Returns the return value of the called fuction in uvec[0].
609: */
610: int
611: docall(uvec)
612: unsigned uvec[];
613: {
614: int (* func)();
615: unsigned kvec[7];
616: int retval;
617:
618: printf("NLCALL security hole.\n");
619:
620: /* Fetch the first element of vec. */
621: ukcopy (uvec, kvec, sizeof (unsigned));
622:
623: if (kvec [0] < 2 || kvec[0] > 7) {
624: /* Invalid number of elements in uvec. */
625: SET_U_ERROR (EINVAL, "Invalid number of elements in uvec");
626: return -1;
627: }
628:
629: /* Fetch the whole vector. */
630: ukcopy (uvec, kvec, kvec [0] * sizeof (unsigned));
631:
632: /* Extract the function. */
633: func = (int (*)()) kvec [1];
634:
635: /* Call the function with all arguments. */
636: retval = (* func) (kvec [2], kvec [3], kvec [4], kvec [5], kvec [6]);
637:
638: kucopy (& retval, uvec, sizeof (unsigned));
639: } /* docall() */
640:
641: #endif /* DANGEROUS */
642:
643: /*
644: * int lock_clock() -- Stop the update cycle on the CMOS RT clock and
645: * wait for it to settle. Returns 0 if the clock would not settle
646: * in time.
647: */
648: int
649: lock_clock()
650: {
651: register int i;
652:
653: /*
654: * Wait for the clock to settle. If it does not settle in
655: * a reasonable amount of time, give up.
656: */
657:
658: i = 65536; /* Loop for a longish time. */
659: while (-- i > 0) {
660: if (0 == (UIP & read_cmos (SRA))) {
661: break; /* Break if there is no update in progress. */
662: }
663: }
664:
665: if (0 == i) {
666: /* The clock would not settle. */
667: return 0;
668: }
669:
670: /*
671: * There is a tiny race here--an interrupt could conceivably
672: * come here, thus allowing enough delay for another update to
673: * begin. But if we take interrupts that take a full second
674: * to process, other things are going to break horribly.
675: */
676:
677: /*
678: * Lock out updates.
679: * We set the No Updates bit in Clock Status Register B.
680: */
681: write_cmos (SRB, read_cmos (SRB) | NO_UPD);
682: return 1;
683: } /* lock_clock() */
684:
685: /*
686: * void unlock_clock() -- Restart the update cycle on the CMOS RT clock.
687: */
688: void
689: unlock_clock()
690: {
691: /*
692: * We clear the No Updates bit in Clock Status Register B.
693: */
694: write_cmos (SRB, read_cmos(SRB) & ~ NO_UPD);
695: } /* unlock_clock() */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.