]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/portdat.h
alarm: run checkalarms() only on cpu0 (from eriks alarm-once patch)
[plan9front.git] / sys / src / 9 / port / portdat.h
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 Mntrpc   Mntrpc;
20 typedef struct Mntwalk  Mntwalk;
21 typedef struct Mnt      Mnt;
22 typedef struct Mhead    Mhead;
23 typedef struct Note     Note;
24 typedef struct Page     Page;
25 typedef struct Path     Path;
26 typedef struct Palloc   Palloc;
27 typedef struct Pallocmem        Pallocmem;
28 typedef struct Perf     Perf;
29 typedef struct PhysUart PhysUart;
30 typedef struct Pgrp     Pgrp;
31 typedef struct Physseg  Physseg;
32 typedef struct Proc     Proc;
33 typedef struct Pte      Pte;
34 typedef struct QLock    QLock;
35 typedef struct Queue    Queue;
36 typedef struct Ref      Ref;
37 typedef struct Rendez   Rendez;
38 typedef struct Rgrp     Rgrp;
39 typedef struct RWlock   RWlock;
40 typedef struct Sargs    Sargs;
41 typedef struct Schedq   Schedq;
42 typedef struct Segment  Segment;
43 typedef struct Sema     Sema;
44 typedef struct Timer    Timer;
45 typedef struct Timers   Timers;
46 typedef struct Uart     Uart;
47 typedef struct Waitq    Waitq;
48 typedef struct Walkqid  Walkqid;
49 typedef struct Watchdog Watchdog;
50 typedef int    Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
51
52 #pragma incomplete DevConf
53 #pragma incomplete Edf
54 #pragma incomplete Mntcache
55 #pragma incomplete Mntrpc
56 #pragma incomplete Queue
57 #pragma incomplete Timers
58
59 #include <fcall.h>
60
61 struct Ref
62 {
63         Lock;
64         long    ref;
65 };
66
67 struct Rendez
68 {
69         Lock;
70         Proc    *p;
71 };
72
73 struct QLock
74 {
75         Lock    use;            /* to access Qlock structure */
76         Proc    *head;          /* next process waiting for object */
77         Proc    *tail;          /* last process waiting for object */
78         int     locked;         /* flag */
79 };
80
81 struct RWlock
82 {
83         Lock    use;
84         Proc    *head;          /* list of waiting processes */
85         Proc    *tail;
86         ulong   wpc;            /* pc of writer */
87         Proc    *wproc;         /* writing proc */
88         int     readers;        /* number of readers */
89         int     writer;         /* number of writers */
90 };
91
92 struct Alarms
93 {
94         QLock;
95         Proc    *head;
96 };
97
98 struct Sargs
99 {
100         ulong   args[MAXSYSARG];
101 };
102
103 /*
104  * Access types in namec & channel flags
105  */
106 enum
107 {
108         Aaccess,                        /* as in stat, wstat */
109         Abind,                          /* for left-hand-side of bind */
110         Atodir,                         /* as in chdir */
111         Aopen,                          /* for i/o */
112         Amount,                         /* to be mounted or mounted upon */
113         Acreate,                        /* is to be created */
114         Aremove,                        /* will be removed by caller */
115
116         COPEN   = 0x0001,               /* for i/o */
117         CMSG    = 0x0002,               /* the message channel for a mount */
118 /*rsc   CCREATE = 0x0004,               /* permits creation if c->mnt */
119         CCEXEC  = 0x0008,               /* close on exec */
120         CFREE   = 0x0010,               /* not in use */
121         CRCLOSE = 0x0020,               /* remove on close */
122         CCACHE  = 0x0080,               /* client cache */
123 };
124
125 /* flag values */
126 enum
127 {
128         BINTR   =       (1<<0),
129         BFREE   =       (1<<1),
130         Bipck   =       (1<<2),         /* ip checksum */
131         Budpck  =       (1<<3),         /* udp checksum */
132         Btcpck  =       (1<<4),         /* tcp checksum */
133         Bpktck  =       (1<<5),         /* packet checksum */
134 };
135
136 struct Block
137 {
138         long    ref;
139         Block*  next;
140         Block*  list;
141         uchar*  rp;                     /* first unconsumed byte */
142         uchar*  wp;                     /* first empty byte */
143         uchar*  lim;                    /* 1 past the end of the buffer */
144         uchar*  base;                   /* start of the buffer */
145         void    (*free)(Block*);
146         ushort  flag;
147         ushort  checksum;               /* IP checksum of complete packet (minus media header) */
148 };
149
150 #define BLEN(s) ((s)->wp - (s)->rp)
151 #define BALLOC(s) ((s)->lim - (s)->base)
152
153 struct Chan
154 {
155         Ref;                            /* the Lock in this Ref is also Chan's lock */
156         Chan*   next;                   /* allocation */
157         Chan*   link;
158         vlong   offset;                 /* in fd */
159         vlong   devoffset;              /* in underlying device; see read */
160         ushort  type;
161         ulong   dev;
162         ushort  mode;                   /* read/write */
163         ushort  flag;
164         Qid     qid;
165         int     fid;                    /* for devmnt */
166         ulong   iounit;                 /* chunk size for i/o; 0==default */
167         Mhead*  umh;                    /* mount point that derived Chan; used in unionread */
168         Chan*   umc;                    /* channel in union; held for union read */
169         QLock   umqlock;                /* serialize unionreads */
170         int     uri;                    /* union read index */
171         int     dri;                    /* devdirread index */
172         uchar*  dirrock;                /* directory entry rock for translations */
173         int     nrock;
174         int     mrock;
175         QLock   rockqlock;
176         int     ismtpt;
177         Mntcache*mcp;                   /* Mount cache pointer */
178         Mnt*    mux;                    /* Mnt for clients using me for messages */
179         union {
180                 void*   aux;
181                 Qid     pgrpid;         /* for #p/notepg */
182                 ulong   mid;            /* for ns in devproc */
183         };
184         Chan*   mchan;                  /* channel to mounted server */
185         Qid     mqid;                   /* qid of root of mount point */
186         Path*   path;
187 };
188
189 struct Path
190 {
191         Ref;
192         char    *s;
193         Chan    **mtpt;                 /* mtpt history */
194         int     len;                    /* strlen(s) */
195         int     alen;                   /* allocated length of s */
196         int     mlen;                   /* number of path elements */
197         int     malen;                  /* allocated length of mtpt */
198 };
199
200 struct Dev
201 {
202         int     dc;
203         char*   name;
204
205         void    (*reset)(void);
206         void    (*init)(void);
207         void    (*shutdown)(void);
208         Chan*   (*attach)(char*);
209         Walkqid*(*walk)(Chan*, Chan*, char**, int);
210         int     (*stat)(Chan*, uchar*, int);
211         Chan*   (*open)(Chan*, int);
212         Chan*   (*create)(Chan*, char*, int, ulong);
213         void    (*close)(Chan*);
214         long    (*read)(Chan*, void*, long, vlong);
215         Block*  (*bread)(Chan*, long, ulong);
216         long    (*write)(Chan*, void*, long, vlong);
217         long    (*bwrite)(Chan*, Block*, ulong);
218         void    (*remove)(Chan*);
219         int     (*wstat)(Chan*, uchar*, int);
220         void    (*power)(int);  /* power mgt: power(1) => on, power (0) => off */
221         int     (*config)(int, char*, DevConf*);        /* returns nil on error */
222 };
223
224 struct Dirtab
225 {
226         char    name[KNAMELEN];
227         Qid     qid;
228         vlong   length;
229         long    perm;
230 };
231
232 struct Walkqid
233 {
234         Chan    *clone;
235         int     nqid;
236         Qid     qid[1];
237 };
238
239 enum
240 {
241         NSMAX   =       1000,
242         NSLOG   =       7,
243         NSCACHE =       (1<<NSLOG),
244 };
245
246 struct Mntwalk                          /* state for /proc/#/ns */
247 {
248         int     cddone;
249         Mhead*  mh;
250         Mount*  cm;
251 };
252
253 struct Mount
254 {
255         ulong   mountid;
256         Mount*  next;
257         Mhead*  head;
258         Mount*  copy;
259         Mount*  order;
260         Chan*   to;                     /* channel replacing channel */
261         int     mflag;
262         char    *spec;
263 };
264
265 struct Mhead
266 {
267         Ref;
268         RWlock  lock;
269         Chan*   from;                   /* channel mounted upon */
270         Mount*  mount;                  /* what's mounted upon it */
271         Mhead*  hash;                   /* Hash chain */
272 };
273
274 struct Mnt
275 {
276         Lock;
277         /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
278         Chan    *c;             /* Channel to file service */
279         Proc    *rip;           /* Reader in progress */
280         Mntrpc  *queue;         /* Queue of pending requests on this channel */
281         ulong   id;             /* Multiplexer id for channel check */
282         Mnt     *list;          /* Free list */
283         int     flags;          /* cache */
284         int     msize;          /* data + IOHDRSZ */
285         char    *version;       /* 9P version */
286         Queue   *q;             /* input queue */
287 };
288
289 enum
290 {
291         NUser,                          /* note provided externally */
292         NExit,                          /* deliver note quietly */
293         NDebug,                         /* print debug message */
294 };
295
296 struct Note
297 {
298         char    msg[ERRMAX];
299         int     flag;                   /* whether system posted it */
300 };
301
302 enum
303 {
304         PG_NOFLUSH      = 0,
305         PG_TXTFLUSH     = 1,            /* flush dcache and invalidate icache */
306         PG_DATFLUSH     = 2,            /* flush both i & d caches (UNUSED) */
307         PG_NEWCOL       = 3,            /* page has been recolored */
308
309         PG_MOD          = 0x01,         /* software modified bit */
310         PG_REF          = 0x02,         /* software referenced bit */
311 };
312
313 struct Page
314 {
315         Lock;
316         ulong   pa;                     /* Physical address in memory */
317         ulong   va;                     /* Virtual address for user */
318         ulong   daddr;                  /* Disc address on swap */
319         ulong   gen;                    /* Generation counter for swap */
320         ushort  ref;                    /* Reference count */
321         char    modref;                 /* Simulated modify/reference bits */
322         char    color;                  /* Cache coloring */
323         char    cachectl[MAXMACH];      /* Cache flushing control for putmmu */
324         Image   *image;                 /* Associated text or swap image */
325         Page    *next;                  /* Lru free list */
326         Page    *prev;
327         Page    *hash;                  /* Image hash chains */
328 };
329
330 struct Swapalloc
331 {
332         Lock;                           /* Free map lock */
333         int     free;                   /* currently free swap pages */
334         uchar*  swmap;                  /* Base of swap map in memory */
335         uchar*  alloc;                  /* Round robin allocator */
336         uchar*  last;                   /* Speed swap allocation */
337         uchar*  top;                    /* Top of swap map */
338         Rendez  r;                      /* Pager kproc idle sleep */
339         ulong   highwater;              /* Pager start threshold */
340         ulong   headroom;               /* Space pager frees under highwater */
341         ulong   xref;                   /* Ref count for all map refs >= 255 */
342 }swapalloc;
343
344 struct Image
345 {
346         Ref;
347         Chan    *c;                     /* channel to text file */
348         Qid     qid;                    /* Qid for page cache coherence */
349         Qid     mqid;
350         Chan    *mchan;
351         ushort  type;                   /* Device type of owning channel */
352         Segment *s;                     /* TEXT segment for image if running */
353         Image   *hash;                  /* Qid hash chains */
354         Image   *next;                  /* Free list */
355         int     notext;                 /* no file associated */
356 };
357
358 struct Pte
359 {
360         Page    *pages[PTEPERTAB];      /* Page map for this chunk of pte */
361         Page    **first;                /* First used entry */
362         Page    **last;                 /* Last used entry */
363 };
364
365 /* Segment types */
366 enum
367 {
368         SG_TYPE         = 07,           /* Mask type of segment */
369         SG_TEXT         = 00,
370         SG_DATA         = 01,
371         SG_BSS          = 02,
372         SG_STACK        = 03,
373         SG_SHARED       = 04,
374         SG_PHYSICAL     = 05,
375
376         SG_RONLY        = 0040,         /* Segment is read only */
377         SG_CEXEC        = 0100,         /* Detach at exec */
378 };
379
380 #define PG_ONSWAP       1
381 #define onswap(s)       (((ulong)s)&PG_ONSWAP)
382 #define pagedout(s)     (((ulong)s)==0 || onswap(s))
383 #define swapaddr(s)     (((ulong)s)&~PG_ONSWAP)
384
385 #define SEGMAXSIZE      (SEGMAPSIZE*PTEMAPMEM)
386
387 struct Physseg
388 {
389         ulong   attr;                   /* Segment attributes */
390         char    *name;                  /* Attach name */
391         ulong   pa;                     /* Physical address */
392         ulong   size;                   /* Maximum segment size in pages */
393         Page    *(*pgalloc)(Segment*, ulong);   /* Allocation if we need it */
394         void    (*pgfree)(Page*);
395 };
396
397 struct Sema
398 {
399         Rendez;
400         long    *addr;
401         int     waiting;
402         Sema    *next;
403         Sema    *prev;
404 };
405
406 struct Segment
407 {
408         Ref;
409         QLock   lk;
410         ushort  steal;          /* Page stealer lock */
411         ushort  type;           /* segment type */
412         ulong   base;           /* virtual base */
413         ulong   top;            /* virtual top */
414         ulong   size;           /* size in pages */
415         ulong   fstart;         /* start address in file for demand load */
416         ulong   flen;           /* length of segment in file */
417         int     flushme;        /* maintain icache for this segment */
418         Image   *image;         /* text in file attached to this segment */
419         Physseg *pseg;
420         ulong*  profile;        /* Tick profile area */
421         Pte     **map;
422         int     mapsize;
423         Pte     *ssegmap[SSEGMAPSIZE];
424         Sema    sema;
425         ulong   mark;           /* portcountrefs */
426 };
427
428 enum
429 {
430         RENDLOG =       5,
431         RENDHASH =      1<<RENDLOG,     /* Hash to lookup rendezvous tags */
432         MNTLOG  =       5,
433         MNTHASH =       1<<MNTLOG,      /* Hash to walk mount table */
434         NFD =           100,            /* per process file descriptors */
435         PGHLOG  =       9,
436         PGHSIZE =       1<<PGHLOG,      /* Page hash for image lookup */
437 };
438 #define REND(p,s)       ((p)->rendhash[(s)&((1<<RENDLOG)-1)])
439 #define MOUNTH(p,qid)   ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
440
441 struct Pgrp
442 {
443         Ref;                            /* also used as a lock when mounting */
444         int     noattach;
445         ulong   pgrpid;
446         QLock   debug;                  /* single access via devproc.c */
447         RWlock  ns;                     /* Namespace n read/one write lock */
448         Mhead   *mnthash[MNTHASH];
449 };
450
451 struct Rgrp
452 {
453         Ref;                            /* the Ref's lock is also the Rgrp's lock */
454         Proc    *rendhash[RENDHASH];    /* Rendezvous tag hash */
455 };
456
457 struct Egrp
458 {
459         Ref;
460         RWlock;
461         Evalue  **ent;
462         int     nent;
463         int     ment;
464         ulong   path;   /* qid.path of next Evalue to be allocated */
465         ulong   vers;   /* of Egrp */
466 };
467
468 struct Evalue
469 {
470         char    *name;
471         char    *value;
472         int     len;
473         Evalue  *link;
474         Qid     qid;
475 };
476
477 struct Fgrp
478 {
479         Ref;
480         Chan    **fd;
481         int     nfd;                    /* number allocated */
482         int     maxfd;                  /* highest fd in use */
483         int     exceed;                 /* debugging */
484 };
485
486 enum
487 {
488         DELTAFD = 20            /* incremental increase in Fgrp.fd's */
489 };
490
491 struct Pallocmem
492 {
493         ulong base;
494         ulong npage;
495 };
496
497 struct Palloc
498 {
499         Lock;
500         Pallocmem       mem[4];
501         Page    *head;                  /* most recently used */
502         Page    *tail;                  /* least recently used */
503         ulong   freecount;              /* how many pages on free list now */
504         Page    *pages;                 /* array of all pages */
505         ulong   user;                   /* how many user pages */
506         Page    *hash[PGHSIZE];
507         Lock    hashlock;
508         Rendez  r;                      /* Sleep for free mem */
509         QLock   pwait;                  /* Queue of procs waiting for memory */
510 };
511
512 struct Waitq
513 {
514         Waitmsg w;
515         Waitq   *next;
516 };
517
518 /*
519  * fasttick timer interrupts
520  */
521 enum {
522         /* Mode */
523         Trelative,      /* timer programmed in ns from now */
524         Tperiodic,      /* periodic timer, period in ns */
525 };
526
527 struct Timer
528 {
529         /* Public interface */
530         int     tmode;          /* See above */
531         vlong   tns;            /* meaning defined by mode */
532         void    (*tf)(Ureg*, Timer*);
533         void    *ta;
534         /* Internal */
535         Lock;
536         Timers  *tt;            /* Timers queue this timer runs on */
537         Tval    tticks;         /* tns converted to ticks */
538         Tval    twhen;          /* ns represented in fastticks */
539         Timer   *tnext;
540 };
541
542 enum
543 {
544         RFNAMEG         = (1<<0),
545         RFENVG          = (1<<1),
546         RFFDG           = (1<<2),
547         RFNOTEG         = (1<<3),
548         RFPROC          = (1<<4),
549         RFMEM           = (1<<5),
550         RFNOWAIT        = (1<<6),
551         RFCNAMEG        = (1<<10),
552         RFCENVG         = (1<<11),
553         RFCFDG          = (1<<12),
554         RFREND          = (1<<13),
555         RFNOMNT         = (1<<14),
556 };
557
558 /*
559  *  process memory segments - NSEG always last !
560  */
561 enum
562 {
563         SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG
564 };
565
566 enum
567 {
568         Dead = 0,               /* Process states */
569         Moribund,
570         Ready,
571         Scheding,
572         Running,
573         Queueing,
574         QueueingR,
575         QueueingW,
576         Wakeme,
577         Broken,
578         Stopped,
579         Rendezvous,
580         Waitrelease,
581
582         Proc_stopme = 1,        /* devproc requests */
583         Proc_exitme,
584         Proc_traceme,
585         Proc_exitbig,
586         Proc_tracesyscall,
587
588         TUser = 0,              /* Proc.time */
589         TSys,
590         TReal,
591         TCUser,
592         TCSys,
593         TCReal,
594
595         NERR = 64,
596         NNOTE = 5,
597
598         Npriq           = 20,           /* number of scheduler priority levels */
599         Nrq             = Npriq+2,      /* number of priority levels including real time */
600         PriRelease      = Npriq,        /* released edf processes */
601         PriEdf          = Npriq+1,      /* active edf processes */
602         PriNormal       = 10,           /* base priority for normal processes */
603         PriExtra        = Npriq-1,      /* edf processes at high best-effort pri */
604         PriKproc        = 13,           /* base priority for kernel processes */
605         PriRoot         = 13,           /* base priority for root processes */
606 };
607
608 struct Schedq
609 {
610         Lock;
611         Proc*   head;
612         Proc*   tail;
613         int     n;
614 };
615
616 struct Proc
617 {
618         Label   sched;          /* known to l.s */
619         char    *kstack;        /* known to l.s */
620         Mach    *mach;          /* machine running this proc */
621         char    *text;
622         char    *user;
623         char    *args;
624         int     nargs;          /* number of bytes of args */
625         Proc    *rnext;         /* next process in run queue */
626         Proc    *qnext;         /* next process on queue for a QLock */
627         QLock   *qlock;         /* addr of qlock being queued for DEBUG */
628         int     state;
629         char    *psstate;       /* What /proc/#/status reports */
630         Segment *seg[NSEG];
631         QLock   seglock;        /* locked whenever seg[] changes */
632         ulong   pid;
633         ulong   noteid;         /* Equivalent of note group */
634         Proc    *pidhash;       /* next proc in pid hash */
635
636         Lock    exl;            /* Lock count and waitq */
637         Waitq   *waitq;         /* Exited processes wait children */
638         int     nchild;         /* Number of living children */
639         int     nwait;          /* Number of uncollected wait records */
640         QLock   qwaitr;
641         Rendez  waitr;          /* Place to hang out in wait */
642         Proc    *parent;
643
644         Pgrp    *pgrp;          /* Process group for namespace */
645         Egrp    *egrp;          /* Environment group */
646         Fgrp    *fgrp;          /* File descriptor group */
647         Rgrp    *rgrp;          /* Rendez group */
648
649         Fgrp    *closingfgrp;   /* used during teardown */
650
651         ulong   parentpid;
652         ulong   time[6];        /* User, Sys, Real; child U, S, R */
653
654         uvlong  kentry;         /* Kernel entry time stamp (for profiling) */
655         /*
656          * pcycles: cycles spent in this process (updated on procsave/restore)
657          * when this is the current proc and we're in the kernel
658          * (procrestores outnumber procsaves by one)
659          * the number of cycles spent in the proc is pcycles + cycles()
660          * when this is not the current process or we're in user mode
661          * (procrestores and procsaves balance), it is pcycles.
662          */
663         vlong   pcycles;
664
665         int     insyscall;
666         int     fpstate;
667
668         QLock   debug;          /* to access debugging elements of User */
669         Proc    *pdbg;          /* the debugging process */
670         ulong   procmode;       /* proc device default file mode */
671         ulong   privatemem;     /* proc does not let anyone read mem */
672         int     hang;           /* hang at next exec for debug */
673         int     procctl;        /* Control for /proc debugging */
674         ulong   pc;             /* DEBUG only */
675
676         Lock    rlock;          /* sync sleep/wakeup with postnote */
677         Rendez  *r;             /* rendezvous point slept on */
678         Rendez  sleep;          /* place for syssleep/debug */
679         int     notepending;    /* note issued but not acted on */
680         int     kp;             /* true if a kernel process */
681         Proc    *palarm;        /* Next alarm time */
682         ulong   alarm;          /* Time of call */
683         int     newtlb;         /* Pager has changed my pte's, I must flush */
684         int     noswap;         /* process is not swappable */
685
686         uintptr rendtag;        /* Tag for rendezvous */
687         uintptr rendval;        /* Value for rendezvous */
688         Proc    *rendhash;      /* Hash list for tag values */
689
690         Timer;                  /* For tsleep and real-time */
691         Rendez  *trend;
692         int     (*tfn)(void*);
693         void    (*kpfun)(void*);
694         void    *kparg;
695
696         FPsave  fpsave;         /* address of this is known by db */
697         int     scallnr;        /* sys call number - known by db */
698         Sargs   s;              /* address of this is known by db */
699         int     nerrlab;
700         Label   errlab[NERR];
701         char    *syserrstr;     /* last error from a system call, errbuf0 or 1 */
702         char    *errstr;        /* reason we're unwinding the error stack, errbuf1 or 0 */
703         char    errbuf0[ERRMAX];
704         char    errbuf1[ERRMAX];
705         char    genbuf[128];    /* buffer used e.g. for last name element from namec */
706         Chan    *slash;
707         Chan    *dot;
708
709         Note    note[NNOTE];
710         short   nnote;
711         short   notified;       /* sysnoted is due */
712         Note    lastnote;
713         int     (*notify)(void*, char*);
714
715         Lock    *lockwait;
716         Lock    *lastlock;      /* debugging */
717         Lock    *lastilock;     /* debugging */
718
719         Mach    *wired;
720         Mach    *mp;            /* machine this process last ran on */
721         Ref     nlocks;         /* number of locks held by proc */
722         ulong   delaysched;
723         ulong   priority;       /* priority level */
724         ulong   basepri;        /* base priority level */
725         uchar   fixedpri;       /* priority level deson't change */
726         ulong   cpu;            /* cpu average */
727         ulong   lastupdate;
728         uchar   yield;          /* non-zero if the process just did a sleep(0) */
729         ulong   readytime;      /* time process came ready */
730         ulong   movetime;       /* last time process switched processors */
731         int     preempted;      /* true if this process hasn't finished the interrupt
732                                  *  that last preempted it
733                                  */
734         Edf     *edf;           /* if non-null, real-time proc, edf contains scheduling params */
735         int     trace;          /* process being traced? */
736
737         ulong   qpc;            /* pc calling last blocking qlock */
738         QLock   *eql;           /* interruptable eqlock */
739
740         int     setargs;
741
742         void    *ureg;          /* User registers for notes */
743         void    *dbgreg;        /* User registers for devproc */
744         Notsave;
745
746         /*
747          *  machine specific MMU
748          */
749         PMMU;
750         char    *syscalltrace;  /* syscall trace */
751 };
752
753 enum
754 {
755         PRINTSIZE =     256,
756         MAXCRYPT =      127,
757         NUMSIZE =       12,             /* size of formatted number */
758         MB =            (1024*1024),
759         /* READSTR was 1000, which is way too small for usb's ctl file */
760         READSTR =       4000,           /* temporary buffer size for device reads */
761 };
762
763 extern  Conf    conf;
764 extern  char*   conffile;
765 extern  int     cpuserver;
766 extern  Dev*    devtab[];
767 extern  char*   eve;
768 extern  char    hostdomain[];
769 extern  uchar   initcode[];
770 extern  Queue*  kprintoq;
771 extern  int     nsyscall;
772 extern  Palloc  palloc;
773 extern  Queue*  serialoq;
774 extern  char*   statename[];
775 extern  Image   swapimage;
776 extern  char*   sysname;
777 extern  uint    qiomaxatomic;
778 extern  char*   sysctab[];
779
780 enum
781 {
782         LRESPROF        = 3,
783 };
784
785 /*
786  *  action log
787  */
788 struct Log {
789         Lock;
790         int     opens;
791         char*   buf;
792         char    *end;
793         char    *rptr;
794         int     len;
795         int     nlog;
796         int     minread;
797
798         int     logmask;        /* mask of things to debug */
799
800         QLock   readq;
801         Rendez  readr;
802 };
803
804 struct Logflag {
805         char*   name;
806         int     mask;
807 };
808
809 enum
810 {
811         NCMDFIELD = 128
812 };
813
814 struct Cmdbuf
815 {
816         char    *buf;
817         char    **f;
818         int     nf;
819 };
820
821 struct Cmdtab
822 {
823         int     index;  /* used by client to switch on result */
824         char    *cmd;   /* command name */
825         int     narg;   /* expected #args; 0 ==> variadic */
826 };
827
828 /*
829  *  routines to access UART hardware
830  */
831 struct PhysUart
832 {
833         char*   name;
834         Uart*   (*pnp)(void);
835         void    (*enable)(Uart*, int);
836         void    (*disable)(Uart*);
837         void    (*kick)(Uart*);
838         void    (*dobreak)(Uart*, int);
839         int     (*baud)(Uart*, int);
840         int     (*bits)(Uart*, int);
841         int     (*stop)(Uart*, int);
842         int     (*parity)(Uart*, int);
843         void    (*modemctl)(Uart*, int);
844         void    (*rts)(Uart*, int);
845         void    (*dtr)(Uart*, int);
846         long    (*status)(Uart*, void*, long, long);
847         void    (*fifo)(Uart*, int);
848         void    (*power)(Uart*, int);
849         int     (*getc)(Uart*); /* polling versions, for iprint, rdb */
850         void    (*putc)(Uart*, int);
851 };
852
853 enum {
854         Stagesize=      2048
855 };
856
857 /*
858  *  software UART
859  */
860 struct Uart
861 {
862         void*   regs;                   /* hardware stuff */
863         void*   saveregs;               /* place to put registers on power down */
864         char*   name;                   /* internal name */
865         ulong   freq;                   /* clock frequency */
866         int     bits;                   /* bits per character */
867         int     stop;                   /* stop bits */
868         int     parity;                 /* even, odd or no parity */
869         int     baud;                   /* baud rate */
870         PhysUart*phys;
871         int     console;                /* used as a serial console */
872         int     special;                /* internal kernel device */
873         Uart*   next;                   /* list of allocated uarts */
874
875         QLock;
876         int     type;                   /* ?? */
877         int     dev;
878         int     opens;
879
880         int     enabled;
881         Uart    *elist;                 /* next enabled interface */
882
883         int     perr;                   /* parity errors */
884         int     ferr;                   /* framing errors */
885         int     oerr;                   /* rcvr overruns */
886         int     berr;                   /* no input buffers */
887         int     serr;                   /* input queue overflow */
888
889         /* buffers */
890         int     (*putc)(Queue*, int);
891         Queue   *iq;
892         Queue   *oq;
893
894         Lock    rlock;
895         uchar   istage[Stagesize];
896         uchar   *iw;
897         uchar   *ir;
898         uchar   *ie;
899
900         Lock    tlock;                  /* transmit */
901         uchar   ostage[Stagesize];
902         uchar   *op;
903         uchar   *oe;
904         int     drain;
905
906         int     modem;                  /* hardware flow control on */
907         int     xonoff;                 /* software flow control on */
908         int     blocked;
909         int     cts, dsr, dcd;  /* keep track of modem status */ 
910         int     ctsbackoff;
911         int     hup_dsr, hup_dcd;       /* send hangup upstream? */
912         int     dohup;
913
914         Rendez  r;
915 };
916
917 extern  Uart*   consuart;
918
919 /*
920  *  performance timers, all units in perfticks
921  */
922 struct Perf
923 {
924         ulong   intrts;         /* time of last interrupt */
925         ulong   inintr;         /* time since last clock tick in interrupt handlers */
926         ulong   avg_inintr;     /* avg time per clock tick in interrupt handlers */
927         ulong   inidle;         /* time since last clock tick in idle loop */
928         ulong   avg_inidle;     /* avg time per clock tick in idle loop */
929         ulong   last;           /* value of perfticks() at last clock tick */
930         ulong   period;         /* perfticks() per clock tick */
931 };
932
933 struct Watchdog
934 {
935         void    (*enable)(void);        /* watchdog enable */
936         void    (*disable)(void);       /* watchdog disable */
937         void    (*restart)(void);       /* watchdog restart */
938         void    (*stat)(char*, char*);  /* watchdog statistics */
939 };
940
941
942 /* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
943 enum
944 {
945         /* Queue.state */
946         Qstarve         = (1<<0),       /* consumer starved */
947         Qmsg            = (1<<1),       /* message stream */
948         Qclosed         = (1<<2),       /* queue has been closed/hungup */
949         Qflow           = (1<<3),       /* producer flow controlled */
950         Qcoalesce       = (1<<4),       /* coallesce packets on read */
951         Qkick           = (1<<5),       /* always call the kick routine after qwrite */
952 };
953
954 #define DEVDOTDOT -1
955
956 #pragma varargck        type    "I"     uchar*
957 #pragma varargck        type    "V"     uchar*
958 #pragma varargck        type    "E"     uchar*
959 #pragma varargck        type    "M"     uchar*