1 typedef struct Alarms Alarms;
2 typedef struct Block Block;
3 typedef struct Chan Chan;
4 typedef struct Cmdbuf Cmdbuf;
5 typedef struct Cmdtab Cmdtab;
6 typedef struct Confmem Confmem;
7 typedef struct Dev Dev;
8 typedef struct Dirtab Dirtab;
9 typedef struct Edf Edf;
10 typedef struct Egrp Egrp;
11 typedef struct Evalue Evalue;
12 typedef struct Fgrp Fgrp;
13 typedef struct DevConf DevConf;
14 typedef struct Image Image;
15 typedef struct Log Log;
16 typedef struct Logflag Logflag;
17 typedef struct Mntcache Mntcache;
18 typedef struct Mount Mount;
19 typedef struct Mntrah Mntrah;
20 typedef struct Mntrpc Mntrpc;
21 typedef struct Mntproc Mntproc;
22 typedef struct Mnt Mnt;
23 typedef struct Mhead Mhead;
24 typedef struct Note Note;
25 typedef struct Page Page;
26 typedef struct Path Path;
27 typedef struct Palloc Palloc;
28 typedef struct Pallocmem Pallocmem;
29 typedef struct Perf Perf;
30 typedef struct PhysUart PhysUart;
31 typedef struct Pgrp Pgrp;
32 typedef struct Physseg Physseg;
33 typedef struct Proc Proc;
34 typedef struct Pte Pte;
35 typedef struct QLock QLock;
36 typedef struct Queue Queue;
37 typedef struct Ref Ref;
38 typedef struct Rendez Rendez;
39 typedef struct Rendezq Rendezq;
40 typedef struct Rgrp Rgrp;
41 typedef struct RWlock RWlock;
42 typedef struct Sargs Sargs;
43 typedef struct Schedq Schedq;
44 typedef struct Segment Segment;
45 typedef struct Segio Segio;
46 typedef struct Sema Sema;
47 typedef struct Timer Timer;
48 typedef struct Timers Timers;
49 typedef struct Uart Uart;
50 typedef struct Waitq Waitq;
51 typedef struct Walkqid Walkqid;
52 typedef struct Watchpt Watchpt;
53 typedef struct Watchdog Watchdog;
54 typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
56 #pragma incomplete DevConf
57 #pragma incomplete Edf
58 #pragma incomplete Mntcache
59 #pragma incomplete Mntrpc
60 #pragma incomplete Queue
61 #pragma incomplete Timers
78 Lock use; /* to access Qlock structure */
79 Proc *head; /* next process waiting for object */
80 Proc *tail; /* last process waiting for object */
81 int locked; /* flag */
93 Proc *head; /* list of waiting processes */
95 uintptr wpc; /* pc of writer */
96 Proc *wproc; /* writing proc */
97 int readers; /* number of readers */
98 int writer; /* number of writers */
109 uchar args[MAXSYSARG*BY2WD];
113 * Access types in namec & channel flags
117 Aaccess, /* as in stat, wstat */
118 Abind, /* for left-hand-side of bind */
119 Atodir, /* as in chdir */
121 Amount, /* to be mounted or mounted upon */
122 Acreate, /* is to be created */
123 Aremove, /* will be removed by caller */
125 COPEN = 0x0001, /* for i/o */
126 CMSG = 0x0002, /* the message channel for a mount */
127 /*rsc CCREATE = 0x0004, /* permits creation if c->mnt */
128 CCEXEC = 0x0008, /* close on exec */
129 CFREE = 0x0010, /* not in use */
130 CRCLOSE = 0x0020, /* remove on close */
131 CCACHE = 0x0080, /* client cache */
139 Bipck = (1<<2), /* ip checksum */
140 Budpck = (1<<3), /* udp checksum */
141 Btcpck = (1<<4), /* tcp checksum */
142 Bpktck = (1<<5), /* packet checksum */
149 uchar* rp; /* first unconsumed byte */
150 uchar* wp; /* first empty byte */
151 uchar* lim; /* 1 past the end of the buffer */
152 uchar* base; /* start of the buffer */
153 void (*free)(Block*);
155 ushort checksum; /* IP checksum of complete packet (minus media header) */
158 #define BLEN(s) ((s)->wp - (s)->rp)
159 #define BALLOC(s) ((s)->lim - (s)->base)
165 Chan* next; /* allocation */
167 vlong offset; /* in fd */
168 vlong devoffset; /* in underlying device; see read */
171 ushort mode; /* read/write */
174 int fid; /* for devmnt */
175 ulong iounit; /* chunk size for i/o; 0==default */
176 Mhead* umh; /* mount point that derived Chan; used in unionread */
177 Chan* umc; /* channel in union; held for union read */
178 QLock umqlock; /* serialize unionreads */
179 int uri; /* union read index */
180 int dri; /* devdirread index */
181 uchar* dirrock; /* directory entry rock for translations */
186 Mntcache*mcp; /* Mount cache pointer */
187 Mnt* mux; /* Mnt for clients using me for messages */
190 Qid pgrpid; /* for #p/notepg */
191 ulong mid; /* for ns in devproc */
193 Chan* mchan; /* channel to mounted server */
194 Qid mqid; /* qid of root of mount point */
202 Chan **mtpt; /* mtpt history */
203 int len; /* strlen(s) */
204 int alen; /* allocated length of s */
205 int mlen; /* number of path elements */
206 int malen; /* allocated length of mtpt */
216 void (*shutdown)(void);
217 Chan* (*attach)(char*);
218 Walkqid*(*walk)(Chan*, Chan*, char**, int);
219 int (*stat)(Chan*, uchar*, int);
220 Chan* (*open)(Chan*, int);
221 Chan* (*create)(Chan*, char*, int, ulong);
222 void (*close)(Chan*);
223 long (*read)(Chan*, void*, long, vlong);
224 Block* (*bread)(Chan*, long, ulong);
225 long (*write)(Chan*, void*, long, vlong);
226 long (*bwrite)(Chan*, Block*, ulong);
227 void (*remove)(Chan*);
228 int (*wstat)(Chan*, uchar*, int);
229 void (*power)(int); /* power mgt: power(1) => on, power (0) => off */
230 int (*config)(int, char*, DevConf*); /* returns nil on error */
254 Chan* to; /* channel replacing channel */
262 Chan* from; /* channel mounted upon */
263 Mount* mount; /* what's mounted upon it */
264 Mhead* hash; /* Hash chain */
287 void (*f)(Mntrpc*, void*);
293 /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
294 Chan *c; /* Channel to file service */
295 Proc *rip; /* Reader in progress */
296 Mntrpc *queue; /* Queue of pending requests on this channel */
297 Mntproc defered[8]; /* Worker processes for defered RPCs (read ahead) */
298 ulong id; /* Multiplexer id for channel check */
299 Mnt *list; /* Free list */
300 int flags; /* cache */
301 int msize; /* data + IOHDRSZ */
302 char *version; /* 9P version */
303 Queue *q; /* input queue */
308 NUser, /* note provided externally */
309 NExit, /* deliver note quietly */
310 NDebug, /* print debug message */
316 int flag; /* whether system posted it */
321 PG_MOD = 0x01, /* software modified bit */
322 PG_REF = 0x02, /* software referenced bit */
328 Page *next; /* Free list or Hash chains */
329 uintptr pa; /* Physical address in memory */
330 uintptr va; /* Virtual address for user */
331 uintptr daddr; /* Disc address on swap */
332 Image *image; /* Associated text or swap image */
333 ulong txtflush; /* Flush icache for putmmu */
334 ushort refage; /* Swap reference age */
335 char modref; /* Simulated modify/reference bits */
336 char color; /* Cache coloring */
341 Lock; /* Free map lock */
342 int free; /* currently free swap pages */
343 uchar* swmap; /* Base of swap map in memory */
344 uchar* alloc; /* Round robin allocator */
345 uchar* last; /* Speed swap allocation */
346 uchar* top; /* Top of swap map */
347 Rendez r; /* Pager kproc idle sleep */
348 ulong highwater; /* Pager start threshold */
349 ulong headroom; /* Space pager frees under highwater */
350 ulong xref; /* Ref count for all map refs >= 255 */
355 Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */
356 Page **first; /* First used entry */
357 Page **last; /* Last used entry */
363 SG_TYPE = 07, /* Mask type of segment */
373 SG_RONLY = 0040, /* Segment is read only */
374 SG_CEXEC = 0100, /* Detach at exec */
375 SG_FAULT = 0200, /* Fault on access */
379 #define onswap(s) (((uintptr)s)&PG_ONSWAP)
380 #define pagedout(s) (((uintptr)s)==0 || onswap(s))
381 #define swapaddr(s) (((uintptr)s)&~PG_ONSWAP)
383 #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM)
387 int attr; /* Segment attributes */
388 char *name; /* Attach name */
389 uintptr pa; /* Physical address */
390 uintptr size; /* Maximum segment size in bytes */
406 int type; /* segment type */
407 uintptr base; /* virtual base */
408 uintptr top; /* virtual top */
409 ulong size; /* size in pages */
410 uintptr fstart; /* start address in file for demand load */
411 uintptr flen; /* length of segment in file */
412 int flushme; /* maintain icache for this segment */
413 Image *image; /* text in file attached to this segment */
415 ulong* profile; /* Tick profile area */
418 Pte *ssegmap[SSEGMAPSIZE];
420 ulong mark; /* portcountrefs */
429 Proc *p; /* segmentio kproc */
442 RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */
444 MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */
445 NFD = 100, /* per process file descriptors */
447 PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */
449 #define REND(p,s) ((p)->rendhash[(s)&((1<<RENDLOG)-1)])
450 #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
451 #define PGHASH(i,daddr) ((i)->pghash[((daddr)>>PGSHIFT)&(PGHSIZE-1)])
457 Chan *c; /* channel to text file, nil when not used */
458 Qid qid; /* Qid for page cache coherence */
459 ulong dev; /* Device id of owning channel */
460 ushort type; /* Device type of owning channel */
461 char notext; /* no file associated */
462 Segment *s; /* TEXT segment for image if running */
463 Image *hash; /* Qid hash chains */
464 Image *next; /* Free list */
465 long pgref; /* number of cached pages (pgref <= ref) */
466 Page *pghash[PGHSIZE]; /* page cache */
473 RWlock ns; /* Namespace n read/one write lock */
476 Mhead *mnthash[MNTHASH];
483 Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */
493 ulong path; /* qid.path of next Evalue to be allocated */
494 ulong vers; /* of Egrp */
510 int nfd; /* number allocated */
511 int maxfd; /* highest fd in use */
512 int exceed; /* debugging */
517 DELTAFD = 20 /* incremental increase in Fgrp.fd's */
529 Page *head; /* freelist head */
530 ulong freecount; /* how many pages on free list now */
531 Page *pages; /* array of all pages */
532 ulong user; /* how many user pages */
533 Rendezq pwait[2]; /* Queues of procs waiting for memory */
534 Pallocmem mem[16]; /* physical user page banks */
544 * fasttick timer interrupts
548 Trelative, /* timer programmed in ns from now */
549 Tperiodic, /* periodic timer, period in ns */
554 /* Public interface */
555 int tmode; /* See above */
556 vlong tns; /* meaning defined by mode */
557 void (*tf)(Ureg*, Timer*);
561 Mach *tactive; /* The cpu that tf is active on */
562 Timers *tt; /* Timers queue this timer runs on */
563 Tval tticks; /* tns converted to ticks */
564 Tval twhen; /* ns represented in fastticks */
585 * process memory segments - NSEG always last !
589 SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG
594 Dead = 0, /* Process states */
608 Proc_stopme = 1, /* devproc requests */
614 TUser = 0, /* Proc.time */
624 Npriq = 20, /* number of scheduler priority levels */
625 Nrq = Npriq+2, /* number of priority levels including real time */
626 PriRelease = Npriq, /* released edf processes */
627 PriEdf = Npriq+1, /* active edf processes */
628 PriNormal = 10, /* base priority for normal processes */
629 PriExtra = Npriq-1, /* edf processes at high best-effort pri */
630 PriKproc = 13, /* base priority for kernel processes */
631 PriRoot = 13, /* base priority for root processes */
644 Label sched; /* known to l.s */
645 char *kstack; /* known to l.s */
646 Mach *mach; /* machine running this proc */
650 int nargs; /* number of bytes of args */
651 int setargs; /* process changed its args */
652 Proc *rnext; /* next process in run queue */
653 Proc *qnext; /* next process on queue for a QLock */
654 QLock *qlock; /* addr of qlock being queued for DEBUG */
656 char *psstate; /* What /proc/#/status reports */
658 QLock seglock; /* locked whenever seg[] changes */
660 ulong noteid; /* Equivalent of note group */
661 Proc *pidhash; /* next proc in pid hash */
663 Lock exl; /* Lock count and waitq */
664 Waitq *waitq; /* Exited processes wait children */
665 int nchild; /* Number of living children */
666 int nwait; /* Number of uncollected wait records */
668 Rendez waitr; /* Place to hang out in wait */
671 Pgrp *pgrp; /* Process group for namespace */
672 Egrp *egrp; /* Environment group */
673 Fgrp *fgrp; /* File descriptor group */
674 Rgrp *rgrp; /* Rendez group */
676 Fgrp *closingfgrp; /* used during teardown */
681 ulong time[6]; /* User, Sys, Real; child U, S, R */
683 uvlong kentry; /* Kernel entry time stamp (for profiling) */
685 * pcycles: cycles spent in this process (updated on procsave/restore)
686 * when this is the current proc and we're in the kernel
687 * (procrestores outnumber procsaves by one)
688 * the number of cycles spent in the proc is pcycles + cycles()
689 * when this is not the current process or we're in user mode
690 * (procrestores and procsaves balance), it is pcycles.
694 QLock debug; /* to access debugging elements of User */
695 Proc *pdbg; /* the debugging process */
696 ulong procmode; /* proc device default file mode */
697 int privatemem; /* proc does not let anyone read mem */
698 int hang; /* hang at next exec for debug */
699 int procctl; /* Control for /proc debugging */
700 uintptr pc; /* DEBUG only */
702 Lock rlock; /* sync sleep/wakeup with postnote */
703 Rendez *r; /* rendezvous point slept on */
704 Rendez sleep; /* place for syssleep/debug */
705 int notepending; /* note issued but not acted on */
706 int kp; /* true if a kernel process */
707 Proc *palarm; /* Next alarm time */
708 ulong alarm; /* Time of call */
709 int newtlb; /* Pager has changed my pte's, I must flush */
710 int noswap; /* process is not swappable */
712 uintptr rendtag; /* Tag for rendezvous */
713 uintptr rendval; /* Value for rendezvous */
714 Proc *rendhash; /* Hash list for tag values */
716 Timer; /* For tsleep and real-time */
719 void (*kpfun)(void*);
722 int scallnr; /* sys call number */
723 Sargs s; /* syscall arguments */
726 char *syserrstr; /* last error from a system call, errbuf0 or 1 */
727 char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */
728 char errbuf0[ERRMAX];
729 char errbuf1[ERRMAX];
730 char genbuf[128]; /* buffer used e.g. for last name element from namec */
736 short notified; /* sysnoted is due */
738 int (*notify)(void*, char*);
741 Lock *lastlock; /* debugging */
742 Lock *lastilock; /* debugging */
745 Mach *mp; /* machine this process last ran on */
746 int nlocks; /* number of locks held by proc */
748 ulong priority; /* priority level */
749 ulong basepri; /* base priority level */
750 uchar fixedpri; /* priority level deson't change */
751 ulong cpu; /* cpu average */
753 uchar yield; /* non-zero if the process just did a sleep(0) */
754 ulong readytime; /* time process came ready */
755 ulong movetime; /* last time process switched processors */
756 int preempted; /* true if this process hasn't finished the interrupt
757 * that last preempted it
759 Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */
760 int trace; /* process being traced? */
762 uintptr qpc; /* pc calling last blocking qlock */
763 QLock *eql; /* interruptable eqlock */
765 void *ureg; /* User registers for notes */
766 void *dbgreg; /* User registers for devproc */
768 PFPU; /* machine specific fpu state */
769 PMMU; /* machine specific mmu state */
771 char *syscalltrace; /* syscall trace */
773 Watchpt *watchpt; /* watchpoints */
780 NUMSIZE = 12, /* size of formatted number */
782 /* READSTR was 1000, which is way too small for usb's ctl file */
783 READSTR = 8000, /* temporary buffer size for device reads */
787 extern char* conffile;
788 extern int cpuserver;
789 extern Dev* devtab[];
791 extern char hostdomain[];
792 extern uchar initcode[];
793 extern Queue* kprintoq;
795 extern Palloc palloc;
796 extern Queue* serialoq;
797 extern char* statename[];
798 extern Image swapimage;
799 extern Image fscache;
800 extern char* sysname;
801 extern uint qiomaxatomic;
802 extern char* sysctab[];
822 int logmask; /* mask of things to debug */
847 int index; /* used by client to switch on result */
848 char *cmd; /* command name */
849 int narg; /* expected #args; 0 ==> variadic */
853 * routines to access UART hardware
859 void (*enable)(Uart*, int);
860 void (*disable)(Uart*);
862 void (*dobreak)(Uart*, int);
863 int (*baud)(Uart*, int);
864 int (*bits)(Uart*, int);
865 int (*stop)(Uart*, int);
866 int (*parity)(Uart*, int);
867 void (*modemctl)(Uart*, int);
868 void (*rts)(Uart*, int);
869 void (*dtr)(Uart*, int);
870 long (*status)(Uart*, void*, long, long);
871 void (*fifo)(Uart*, int);
872 void (*power)(Uart*, int);
873 int (*getc)(Uart*); /* polling versions, for iprint, rdb */
874 void (*putc)(Uart*, int);
886 void* regs; /* hardware stuff */
887 void* saveregs; /* place to put registers on power down */
888 char* name; /* internal name */
889 ulong freq; /* clock frequency */
890 int bits; /* bits per character */
891 int stop; /* stop bits */
892 int parity; /* even, odd or no parity */
893 int baud; /* baud rate */
895 int console; /* used as a serial console */
896 int special; /* internal kernel device */
897 Uart* next; /* list of allocated uarts */
905 Uart *elist; /* next enabled interface */
907 int perr; /* parity errors */
908 int ferr; /* framing errors */
909 int oerr; /* rcvr overruns */
910 int berr; /* no input buffers */
911 int serr; /* input queue overflow */
914 int (*putc)(Queue*, int);
919 uchar istage[Stagesize];
924 Lock tlock; /* transmit */
925 uchar ostage[Stagesize];
930 int modem; /* hardware flow control on */
931 int xonoff; /* software flow control on */
933 int cts, dsr, dcd; /* keep track of modem status */
935 int hup_dsr, hup_dcd; /* send hangup upstream? */
941 extern Uart* consuart;
944 * performance timers, all units in perfticks
948 ulong intrts; /* time of last interrupt */
949 ulong inintr; /* time since last clock tick in interrupt handlers */
950 ulong avg_inintr; /* avg time per clock tick in interrupt handlers */
951 ulong inidle; /* time since last clock tick in idle loop */
952 ulong avg_inidle; /* avg time per clock tick in idle loop */
953 ulong last; /* value of perfticks() at last clock tick */
954 ulong period; /* perfticks() per clock tick */
959 void (*enable)(void); /* watchdog enable */
960 void (*disable)(void); /* watchdog disable */
961 void (*restart)(void); /* watchdog restart */
962 void (*stat)(char*, char*); /* watchdog statistics */
976 /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */
980 Qstarve = (1<<0), /* consumer starved */
981 Qmsg = (1<<1), /* message stream */
982 Qclosed = (1<<2), /* queue has been closed/hungup */
983 Qflow = (1<<3), /* producer flow controlled */
984 Qcoalesce = (1<<4), /* coallesce packets on read */
985 Qkick = (1<<5), /* always call the kick routine after qwrite */
990 #pragma varargck type "I" uchar*
991 #pragma varargck type "V" uchar*
992 #pragma varargck type "E" uchar*
993 #pragma varargck type "M" uchar*
996 * Log console output so it can be retrieved via /dev/kmesg.
997 * This is good for catching boot-time messages after the fact.