|
|
1.1 root 1: typedef struct Alarms Alarms;
2: typedef struct Block Block;
3: typedef struct Blist Blist;
4: typedef struct Chan Chan;
5: typedef struct Dev Dev;
6: typedef struct Dirtab Dirtab;
7: typedef struct Egrp Egrp;
8: typedef struct Evalue Evalue;
9: typedef struct Etherpkt Etherpkt;
10: typedef struct Fgrp Fgrp;
11: typedef struct Image Image;
12: typedef struct IOQ IOQ;
13: typedef struct KIOQ KIOQ;
14: typedef struct List List;
15: typedef struct Mount Mount;
16: typedef struct Mnt Mnt;
17: typedef struct Mhead Mhead;
18: typedef struct Netinf Netinf;
19: typedef struct Netprot Netprot;
20: typedef struct Network Network;
21: typedef struct Note Note;
22: typedef struct Page Page;
23: typedef struct Palloc Palloc;
24: typedef struct Parallax Parallax;
25: typedef struct Pgrps Pgrps;
26: typedef struct Pgrp Pgrp;
27: typedef struct Physseg Physseg;
28: typedef struct Proc Proc;
29: typedef struct Pte Pte;
30: typedef struct Qinfo Qinfo;
31: typedef struct QLock QLock;
32: typedef struct Queue Queue;
33: typedef struct Ref Ref;
34: typedef struct Rendez Rendez;
35: typedef struct RWlock RWlock;
36: typedef struct Sargs Sargs;
37: typedef struct Session Session;
38: typedef struct Scsi Scsi;
39: typedef struct Scsibuf Scsibuf;
40: typedef struct Scsidata Scsidata;
41: typedef struct Segment Segment;
42: typedef struct Stream Stream;
43: typedef struct Talarm Talarm;
44: typedef struct Waitq Waitq;
45: typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
46: typedef void Streamput(Queue*, Block*);
47: typedef void Streamopen(Queue*, Stream*);
48: typedef void Streamclose(Queue*);
49: typedef void Streamreset(void);
50:
51: #include <auth.h>
52: #include <fcall.h>
53:
54: struct Ref
55: {
56: Lock;
57: long ref;
58: };
59:
60: struct Rendez
61: {
62: Lock;
63: Proc *p;
64: };
65:
66: struct QLock
67: {
68: Lock use; /* to access Qlock structure */
69: Proc *head; /* next process waiting for object */
70: Proc *tail; /* last process waiting for object */
71: int locked; /* flag */
72: };
73:
74: struct RWlock
75: {
76: Lock; /* Lock modify lock */
77: QLock x; /* Mutual exclusion lock */
78: QLock k; /* Lock for waiting writers held for readers */
79: int readers; /* Count of readers in lock */
80: };
81:
82: struct Talarm
83: {
84: Lock;
85: Proc *list;
86: };
87:
88: struct Alarms
89: {
90: QLock;
91: Proc *head;
92: };
93:
94: #define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */
95: struct Sargs
96: {
97: ulong args[MAXSYSARG];
98: };
99:
100: /* Block.flags */
101: #define S_DELIM 0x80
102: #define S_CLASS 0x07
103:
104: /* Block.type */
105: #define M_DATA 0
106: #define M_CTL 1
107: #define M_HANGUP 2
108:
109: struct Block
110: {
111: Block *next;
112: Block *list; /* chain of block lists */
113: uchar *rptr; /* first unconsumed byte */
114: uchar *wptr; /* first empty byte */
115: uchar *lim; /* 1 past the end of the buffer */
116: uchar *base; /* start of the buffer */
117: uchar flags;
118: uchar type;
119: ulong pc; /* pc of caller */
120: };
121:
122: struct Blist
123: {
124: Lock;
125: Block *first; /* first data block */
126: Block *last; /* last data block */
127: long len; /* length of list in bytes */
128: int nb; /* number of blocks in list */
129: };
130:
131: /*
132: * Access types in namec
133: */
134: enum
135: {
136: Aaccess, /* as in access, stat */
137: Atodir, /* as in chdir */
138: Aopen, /* for i/o */
139: Amount, /* to be mounted upon */
140: Acreate, /* file is to be created */
141: };
142:
143: /*
144: * Chan.flags
145: */
146: #define COPEN 1 /* for i/o */
147: #define CMSG 2 /* is the message channel for a mount */
148: #define CCREATE 4 /* permits creation if c->mnt */
149: #define CCEXEC 8 /* close on exec */
150: #define CFREE 16 /* not in use */
151: #define CRCLOSE 32 /* remove on close */
152:
153: struct Chan
154: {
155: Ref;
156: union{
157: Chan *next; /* allocation */
158: ulong offset; /* in file */
159: };
160: ushort type;
161: ulong dev;
162: ushort mode; /* read/write */
163: ushort flag;
164: Qid qid;
165: Mount *mnt; /* mount point that derived Chan */
166: ulong mountid;
167: int fid; /* for devmnt */
168: Stream *stream; /* for stream channels */
169: union {
170: void *aux;
171: Qid pgrpid; /* for #p/notepg */
172: Mnt *mntptr; /* for devmnt */
173: };
174: Chan *mchan; /* channel to mounted server */
175: Qid mqid; /* qid of root of mount point */
176: Session *session;
177: };
178:
179: struct Dev
180: {
181: void (*reset)(void);
182: void (*init)(void);
183: Chan* (*attach)(char*);
184: Chan* (*clone)(Chan*, Chan*);
185: int (*walk)(Chan*, char*);
186: void (*stat)(Chan*, char*);
187: Chan* (*open)(Chan*, int);
188: void (*create)(Chan*, char*, int, ulong);
189: void (*close)(Chan*);
190: long (*read)(Chan*, void*, long, ulong);
191: long (*write)(Chan*, void*, long, ulong);
192: void (*remove)(Chan*);
193: void (*wstat)(Chan*, char*);
194: };
195:
196: struct Dirtab
197: {
198: char name[NAMELEN];
199: Qid qid;
200: long length;
201: long perm;
202: };
203:
204: /*
205: * Ethernet packet buffers.
206: */
207: struct Etherpkt
208: {
209: uchar d[6];
210: uchar s[6];
211: uchar type[2];
212: uchar data[1500];
213: uchar crc[4];
214: };
215:
216: enum
217: {
218: ETHERMINTU = 64, /* minimum transmit size */
219: ETHERMAXTU = 1514, /* maximum transmit size */
220: ETHERHDRSIZE = 14, /* size of an ethernet header */
221: };
222:
223: /* SCSI devices. */
224: enum
225: {
226: ScsiTestunit = 0x00,
227: ScsiExtsens = 0x03,
228: ScsiInquiry = 0x12,
229: ScsiModesense = 0x1a,
230: ScsiStartunit = 0x1B,
231: ScsiStopunit = 0x1B,
232: ScsiGetcap = 0x25,
233: ScsiRead = 0x08,
234: ScsiWrite = 0x0a,
235: ScsiExtread = 0x28,
236: ScsiExtwrite = 0x2a,
237:
238: /* data direction */
239: ScsiIn = 1,
240: ScsiOut = 0,
241: };
242:
243: struct Scsibuf
244: {
245: void* virt;
246: void* phys;
247: Scsibuf* next;
248: };
249:
250: struct Scsidata
251: {
252: uchar* base;
253: uchar* lim;
254: uchar* ptr;
255: };
256:
257: struct Scsi
258: {
259: QLock;
260: int bus;
261: ulong pid;
262: ushort target;
263: ushort lun;
264: ushort rflag;
265: ushort status;
266: Scsidata cmd;
267: Scsidata data;
268: Scsibuf* b;
269: uchar* save;
270: uchar cmdblk[16];
271: };
272:
273: /* character based IO (mouse, keyboard, console screen) */
274: #define NQ 4096
275: struct IOQ
276: {
277: Lock;
278: uchar buf[NQ];
279: uchar *in;
280: uchar *out;
281: int state;
282: Rendez r;
283: union{
284: void (*puts)(IOQ*, void*, int); /* output */
285: int (*putc)(IOQ*, int); /* input */
286: };
287: union{
288: int (*gets)(IOQ*, void*, int); /* input */
289: int (*getc)(IOQ*); /* output */
290: };
291: void *ptr;
292: };
293:
294: struct KIOQ
295: {
296: QLock;
297: IOQ;
298: int repeat;
299: int c;
300: int count;
301: };
302:
303: struct Mount
304: {
305: ulong mountid;
306: Mount *next;
307: Mhead *head;
308: Chan *to; /* channel replacing underlying channel */
309: };
310:
311: struct Mhead
312: {
313: Chan *from; /* channel mounted upon */
314: Mount *mount; /* what's mounted upon it */
315: Mhead *hash; /* Hash chain */
316: };
317:
318: enum
319: {
320: NUser, /* note provided externally */
321: NExit, /* deliver note quietly */
322: NDebug, /* print debug message */
323: };
324:
325: struct Note
326: {
327: char msg[ERRLEN];
328: int flag; /* whether system posted it */
329: };
330:
331: enum
332: {
333: PG_NOFLUSH = 0, /* Fields for cache control of pages */
334: PG_TXTFLUSH = 1,
335: PG_DATFLUSH = 2,
336: PG_MOD = 0x01, /* Simulated modified and referenced bits */
337: PG_REF = 0x02,
338: };
339:
340: struct Page
341: {
342: Lock;
343: ulong pa; /* Physical address in memory */
344: ulong va; /* Virtual address for user */
345: ulong daddr; /* Disc address on swap */
346: ushort ref; /* Reference count */
347: char modref; /* Simulated modify/reference bits */
348: char cachectl[MAXMACH]; /* Cache flushing control for putmmu */
349: Image *image; /* Associated text or swap image */
350: Page *next; /* Lru free list */
351: Page *prev;
352: Page *hash; /* Image hash chains */
353: };
354:
355: struct Swapalloc
356: {
357: Lock; /* Free map lock */
358: int free; /* Number of currently free swap pages */
359: uchar *swmap; /* Base of swap map in memory */
360: uchar *alloc; /* Round robin allocator */
361: uchar *last; /* Speed swap allocation */
362: uchar *top; /* Top of swap map */
363: Rendez r; /* Pager kproc idle sleep */
364: ulong highwater; /* Threshold beyond which we must page */
365: ulong headroom; /* Space pager keeps free under highwater */
366: }swapalloc;
367:
368: struct Image
369: {
370: Ref;
371: Chan *c; /* Channel associated with running image */
372: Qid qid; /* Qid for page cache coherence checks */
373: Qid mqid;
374: Chan *mchan;
375: ushort type; /* Device type of owning channel */
376: Segment *s; /* TEXT segment for image if running */
377: Image *hash; /* Qid hash chains */
378: Image *next; /* Free list */
379: };
380:
381: struct Pte
382: {
383: Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */
384: Page **first; /* First used entry */
385: Page **last; /* Last used entry */
386: Pte *next; /* Free list */
387: };
388:
389: /* Segment types */
390: enum
391: {
392: SG_TYPE = 07, /* Mask type of segment */
393: SG_TEXT = 00,
394: SG_DATA = 01,
395: SG_BSS = 02,
396: SG_STACK = 03,
397: SG_SHARED = 04,
398: SG_PHYSICAL = 05,
399: SG_SHDATA = 06,
400:
401: SG_RONLY = 040, /* Segment is read only */
402: SG_CEXEC = 0100, /* Detach at exec */
403: };
404:
405: #define PG_ONSWAP 1
406: #define onswap(s) (((ulong)s)&PG_ONSWAP)
407: #define pagedout(s) (((ulong)s)==0 || onswap(s))
408: #define swapaddr(s) (((ulong)s)&~PG_ONSWAP)
409:
410: #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM)
411:
412: struct Physseg
413: {
414: ulong attr; /* Segment attributes */
415: char *name; /* Attach name */
416: ulong pa; /* Physical address */
417: ulong size; /* Maximum segment size in pages */
418: Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */
419: void (*pgfree)(Page*);
420: };
421:
422: struct Segment
423: {
424: Ref;
425: QLock lk;
426: ushort steal; /* Page stealer lock */
427: Segment *next; /* free list pointers */
428: ushort type; /* segment type */
429: ulong base; /* virtual base */
430: ulong top; /* virtual top */
431: ulong size; /* size in pages */
432: ulong fstart; /* start address in file for demand load */
433: ulong flen; /* length of segment in file */
434: int flushme; /* maintain consistent icache for this segment */
435: Image *image; /* text in file attached to this segment */
436: Physseg *pseg;
437: Pte *map[SEGMAPSIZE]; /* segment pte map */
438: };
439:
440: enum
441: {
442: RENDHASH = 32, /* Hash to lookup rendezvous tags */
443: MNTHASH = 32, /* Hash to walk mount table */
444: NFD = 100, /* Number of per process file descriptors */
445: PGHLOG = 9,
446: PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */
447: };
448: #define REND(p,s) ((p)->rendhash[(s)%RENDHASH])
449: #define MOUNTH(p,s) ((p)->mnthash[(s)->qid.path%MNTHASH])
450:
451: struct Pgrp
452: {
453: Ref; /* also used as a lock when mounting */
454: Pgrp *next; /* free list */
455: ulong pgrpid;
456: QLock debug; /* single access via devproc.c */
457: RWlock ns; /* Namespace many read/one write lock */
458: Mhead *mnthash[MNTHASH];
459: Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */
460: };
461:
462: struct Egrp
463: {
464: Ref;
465: QLock;
466: Evalue *entries;
467: ulong path;
468: };
469:
470: struct Evalue
471: {
472: char *name;
473: char *value;
474: int len;
475: ulong path;
476: Evalue *link;
477: };
478:
479: struct Fgrp
480: {
481: Ref;
482: Chan *fd[NFD];
483: int maxfd; /* highest fd in use */
484: };
485:
486: struct Palloc
487: {
488: Lock;
489: ulong p0, p1; /* base of pages in bank 0/1 */
490: ulong np0, np1; /* number of pages in bank 0/1 */
491: Page *head; /* most recently used */
492: Page *tail; /* least recently used */
493: ulong freecount; /* how many pages on free list now */
494: ulong user; /* how many user pages */
495: Page *hash[PGHSIZE];
496: Lock hashlock;
497: Rendez r; /* Sleep for free mem */
498: QLock pwait; /* Queue of procs waiting for memory */
499: int wanted; /* Do the wakeup at free */
500: ulong cmembase; /* Key memory protected from read by devproc */
501: ulong cmemtop;
502: };
503:
504: struct Waitq
505: {
506: Waitmsg w;
507: Waitq *next;
508: };
509:
510: enum
511: {
512: RFNAMEG = (1<<0),
513: RFENVG = (1<<1),
514: RFFDG = (1<<2),
515: RFNOTEG = (1<<3),
516: RFPROC = (1<<4),
517: RFMEM = (1<<5),
518: RFNOWAIT = (1<<6),
519: RFCNAMEG = (1<<10),
520: RFCENVG = (1<<11),
521: RFCFDG = (1<<12)
522: };
523:
524: /*
525: * process memory segments - NSEG always last !
526: */
527: enum
528: {
529: SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, NSEG
530: };
531:
532: enum
533: {
534: Dead = 0, /* Process states */
535: Moribund,
536: Ready,
537: Scheding,
538: Running,
539: Queueing,
540: Wakeme,
541: Broken,
542: Stopped,
543: Rendezvous,
544:
545: Proc_stopme = 1, /* devproc requests */
546: Proc_exitme,
547: Proc_traceme,
548:
549: TUser = 0, /* Proc.time */
550: TSys,
551: TReal,
552: TCUser,
553: TCSys,
554: TCReal,
555:
556: Nrq = 20, /* number of scheduler priority levels */
557: PriNormal = 10, /* base priority for normal processes */
558: PriKproc = 13, /* base priority for kernel processes */
559: PriRoot = 13, /* base priority for root processes */
560: };
561:
562: struct Proc
563: {
564: Label sched;
565: Mach *mach; /* machine running this proc */
566: char text[NAMELEN];
567: char user[NAMELEN];
568: Proc *rnext; /* next process in run queue */
569: Proc *qnext; /* next process on queue for a QLock */
570: QLock *qlock; /* address of qlock being queued for DEBUG */
571: ulong qlockpc; /* pc of last call to qlock */
572: int state;
573: char *psstate; /* What /proc/#/status reports */
574: Page *upage; /* page from palloc */
575: Segment *seg[NSEG];
576: ulong pid;
577: ulong noteid; /* Equivalent of note group */
578:
579: Lock exl; /* Lock count and waitq */
580: Waitq *waitq; /* Exited processes wait children */
581: int nchild; /* Number of living children */
582: int nwait; /* Number of uncollected wait records */
583: QLock qwaitr;
584: Rendez waitr; /* Place to hang out in wait */
585: Proc *parent;
586:
587: Pgrp *pgrp; /* Process group for notes and namespace */
588: Egrp *egrp; /* Environment group */
589: Fgrp *fgrp; /* File descriptor group */
590:
591: ulong parentpid;
592: ulong time[6]; /* User, Sys, Real; child U, S, R */
593: short insyscall;
594: int fpstate;
595:
596: QLock debug; /* to access debugging elements of User */
597: Proc *pdbg; /* the debugging process */
598: ulong procmode; /* proc device file mode */
599: int hang; /* hang at next exec for debug */
600: int procctl; /* Control for /proc debugging */
601: ulong pc; /* DEBUG only */
602:
603: Rendez *r; /* rendezvous point slept on */
604: Rendez sleep; /* place for syssleep/debug */
605: int notepending; /* note issued but not acted on */
606: int kp; /* true if a kernel process */
607: Proc *palarm; /* Next alarm time */
608: ulong alarm; /* Time of call */
609: int hasspin; /* I hold a spin lock */
610: int newtlb; /* Pager has touched my tables so I must flush */
611:
612: ulong rendtag; /* Tag for rendezvous */
613: ulong rendval; /* Value for rendezvous */
614: Proc *rendhash; /* Hash list for tag values */
615:
616: ulong twhen;
617: Rendez *trend;
618: Proc *tlink;
619: int (*tfn)(void*);
620:
621: Mach *mp; /* machine this process last ran on */
622: ulong priority; /* priority level */
623: ulong basepri; /* base priority level */
624: ulong rt; /* # ticks used since last blocked */
625: ulong art; /* avg # ticks used since last blocked */
626: ulong movetime; /* last time process switched processors */
627: ulong readytime; /* time process went ready */
628:
629: /*
630: * machine specific MMU
631: */
632: PMMU;
633: };
634:
635: /*
636: * operations available to a queue
637: */
638: struct Qinfo
639: {
640: Streamput *iput; /* input routine */
641: Streamput *oput; /* output routine */
642: Streamopen *open;
643: Streamclose *close;
644: char *name;
645: Streamreset *reset; /* initialization */
646: char nodelim; /* True if stream does not preserve delimiters */
647: Qinfo *next;
648: };
649:
650: /* Queue.flag */
651: enum
652: {
653: QHUNGUP = 0x1, /* stream has been hung up */
654: QINUSE = 0x2, /* allocation check */
655: QHIWAT = 0x4, /* queue has gone past the high water mark */
656: QDEBUG = 0x8,
657: };
658:
659: struct Queue
660: {
661: Blist;
662: int flag;
663: Qinfo *info; /* line discipline definition */
664: Queue *other; /* opposite direction, same line discipline */
665: Queue *next; /* next queue in the stream */
666: void (*put)(Queue*, Block*);
667: QLock rlock; /* mutex for processes sleeping at r */
668: Rendez r; /* standard place to wait for flow control */
669: Rendez *rp; /* where flow control wakeups go to */
670: void *ptr; /* private info for the queue */
671: };
672:
673: struct Stream
674: {
675: QLock; /* structure lock */
676: Stream *next;
677: short inuse; /* number of processes in stream */
678: short opens; /* number of processes with stream open */
679: ushort hread; /* number of reads after hangup */
680: ushort type; /* correlation with Chan */
681: ushort dev; /* ... */
682: ulong id; /* ... */
683: QLock rdlock; /* read lock */
684: Queue *procq; /* write queue at process end */
685: Queue *devq; /* read queue at device end */
686: Block *err; /* error message from down stream */
687: int flushmsg; /* flush up till the next delimiter */
688: };
689:
690: /*
691: * useful stream macros
692: */
693: #define RD(q) ((q)->other < (q) ? (q->other) : q)
694: #define WR(q) ((q)->other > (q) ? (q->other) : q)
695: #define STREAMTYPE(x) ((x)&0x1f)
696: #define STREAMID(x) (((x)&~CHDIR)>>5)
697: #define STREAMQID(i,t) (((i)<<5)|(t))
698: #define PUTTHIS(q,b) (*(q)->put)((q), b)
699: #define PUTNEXT(q,b) (*(q)->next->put)((q)->next, b)
700: #define BLEN(b) ((b)->wptr - (b)->rptr)
701: #define QFULL(q) ((q)->flag & QHIWAT)
702: #define FLOWCTL(q,b) { if(QFULL(q->next)) flowctl(q,b); else PUTNEXT(q,b);}
703:
704: /*
705: * stream file qid's & high water mark
706: */
707: enum
708: {
709: Shighqid = STREAMQID(1,0) - 1,
710: Sdataqid = Shighqid,
711: Sctlqid = Sdataqid-1,
712: Slowqid = Sctlqid,
713: Streamhi = (32*1024), /* byte count high water mark */
714: Streambhi = 128, /* block count high water mark */
715: };
716:
717: /*
718: * a multiplexed network
719: */
720: struct Netprot
721: {
722: int id;
723: Netprot *next; /* linked list of protections */
724: ulong mode;
725: char owner[NAMELEN];
726: };
727:
728: struct Netinf
729: {
730: char *name;
731: void (*fill)(Chan*, char*, int);
732: };
733:
734: struct Network
735: {
736: Lock;
737: char *name;
738: int nconv; /* max # of conversations */
739: Qinfo *devp; /* device end line disc */
740: Qinfo *protop; /* protocol line disc */
741: int (*listen)(Chan*);
742: int (*clone)(Chan*);
743: int ninfo;
744: Netinf info[5];
745: Netprot *prot; /* linked list of protections */
746: };
747:
748: /*
749: * Parallax for pen pointers
750: */
751: struct Parallax
752: {
753: int xoff;
754: int xnum;
755: int xdenom;
756:
757: int yoff;
758: int ynum;
759: int ydenom;
760: };
761:
762: enum
763: {
764: PRINTSIZE = 256,
765: MAXCRYPT = 127,
766: NUMSIZE = 12, /* size of formatted number */
767: MB = (1024*1024),
768: };
769:
770: extern Conf conf;
771: extern char* conffile;
772: extern int cpuserver;
773: extern Rune* devchar;
774: extern Dev devtab[];
775: extern char eve[];
776: extern char hostdomain[];
777: extern int hwcurs;
778: extern uchar initcode[];
779: extern FPsave initfp;
780: extern KIOQ kbdq;
781: extern IOQ lineq;
782: extern IOQ mouseq;
783: extern Ref noteidalloc;
784: extern int nrdy;
785: extern IOQ printq;
786: extern char* statename[];
787: extern Image swapimage;
788: extern char sysname[NAMELEN];
789: extern Talarm talarm;
790: extern Palloc palloc;
791: extern int cpuserver;
792: extern Physseg physseg[];
793:
794: enum
795: {
796: CHDIR = 0x80000000L,
797: CHAPPEND = 0x40000000L,
798: CHEXCL = 0x20000000L,
799: CHMOUNT = 0x10000000L,
800: };
801:
802: /*
803: * auth messages
804: */
805: enum
806: {
807: FScchal = 1,
808: FSschal,
809: FSok,
810: FSctick,
811: FSstick,
812: FSerr,
813:
814: RXschal = 0,
815: RXstick = 1,
816: };
817:
818: /*
819: * mouse types
820: */
821: enum
822: {
823: Mouseother= 0,
824: Mouseserial= 1,
825: MousePS2= 2,
826: Mousekurta= 3,
827: };
828: extern int mouseshifted;
829: extern int mousetype;
830: extern int mouseswap;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.