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