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