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