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 void (*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 ushort ref; /* Reference count */ 320 char modref; /* Simulated modify/reference bits */ 321 char color; /* Cache coloring */ 322 char cachectl[MAXMACH]; /* Cache flushing control for putmmu */ 323 Image *image; /* Associated text or swap image */ 324 Page *next; /* Lru free list */ 325 Page *prev; 326 Page *hash; /* Image hash chains */ 327 }; 328 329 struct Swapalloc 330 { 331 Lock; /* Free map lock */ 332 int free; /* currently free swap pages */ 333 uchar* swmap; /* Base of swap map in memory */ 334 uchar* alloc; /* Round robin allocator */ 335 uchar* last; /* Speed swap allocation */ 336 uchar* top; /* Top of swap map */ 337 Rendez r; /* Pager kproc idle sleep */ 338 ulong highwater; /* Pager start threshold */ 339 ulong headroom; /* Space pager frees under highwater */ 340 }swapalloc; 341 342 struct Image 343 { 344 Ref; 345 Chan *c; /* channel to text file */ 346 Qid qid; /* Qid for page cache coherence */ 347 Qid mqid; 348 Chan *mchan; 349 ushort type; /* Device type of owning channel */ 350 Segment *s; /* TEXT segment for image if running */ 351 Image *hash; /* Qid hash chains */ 352 Image *next; /* Free list */ 353 int notext; /* no file associated */ 354 }; 355 356 struct Pte 357 { 358 Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */ 359 Page **first; /* First used entry */ 360 Page **last; /* Last used entry */ 361 }; 362 363 /* Segment types */ 364 enum 365 { 366 SG_TYPE = 07, /* Mask type of segment */ 367 SG_TEXT = 00, 368 SG_DATA = 01, 369 SG_BSS = 02, 370 SG_STACK = 03, 371 SG_SHARED = 04, 372 SG_PHYSICAL = 05, 373 374 SG_RONLY = 0040, /* Segment is read only */ 375 SG_CEXEC = 0100, /* Detach at exec */ 376 }; 377 378 #define PG_ONSWAP 1 379 #define onswap(s) (((ulong)s)&PG_ONSWAP) 380 #define pagedout(s) (((ulong)s)==0 || onswap(s)) 381 #define swapaddr(s) (((ulong)s)&~PG_ONSWAP) 382 383 #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) 384 385 struct Physseg 386 { 387 ulong attr; /* Segment attributes */ 388 char *name; /* Attach name */ 389 ulong pa; /* Physical address */ 390 ulong size; /* Maximum segment size in pages */ 391 Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */ 392 void (*pgfree)(Page*); 393 }; 394 395 struct Sema 396 { 397 Rendez; 398 long *addr; 399 int waiting; 400 Sema *next; 401 Sema *prev; 402 }; 403 404 struct Segment 405 { 406 Ref; 407 QLock lk; 408 ushort steal; /* Page stealer lock */ 409 ushort type; /* segment type */ 410 ulong base; /* virtual base */ 411 ulong top; /* virtual top */ 412 ulong size; /* size in pages */ 413 ulong fstart; /* start address in file for demand load */ 414 ulong flen; /* length of segment in file */ 415 int flushme; /* maintain icache for this segment */ 416 Image *image; /* text in file attached to this segment */ 417 Physseg *pseg; 418 ulong* profile; /* Tick profile area */ 419 Pte **map; 420 int mapsize; 421 Pte *ssegmap[SSEGMAPSIZE]; 422 Lock semalock; 423 Sema sema; 424 ulong mark; /* portcountrefs */ 425 }; 426 427 enum 428 { 429 RENDLOG = 5, 430 RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */ 431 MNTLOG = 5, 432 MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */ 433 NFD = 100, /* per process file descriptors */ 434 PGHLOG = 9, 435 PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */ 436 }; 437 #define REND(p,s) ((p)->rendhash[(s)&((1<<RENDLOG)-1)]) 438 #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)]) 439 440 struct Pgrp 441 { 442 Ref; /* also used as a lock when mounting */ 443 int noattach; 444 ulong pgrpid; 445 QLock debug; /* single access via devproc.c */ 446 RWlock ns; /* Namespace n read/one write lock */ 447 Mhead *mnthash[MNTHASH]; 448 }; 449 450 struct Rgrp 451 { 452 Ref; /* the Ref's lock is also the Rgrp's lock */ 453 Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */ 454 }; 455 456 struct Egrp 457 { 458 Ref; 459 RWlock; 460 Evalue **ent; 461 int nent; 462 int ment; 463 ulong path; /* qid.path of next Evalue to be allocated */ 464 ulong vers; /* of Egrp */ 465 }; 466 467 struct Evalue 468 { 469 char *name; 470 char *value; 471 int len; 472 Evalue *link; 473 Qid qid; 474 }; 475 476 struct Fgrp 477 { 478 Ref; 479 Chan **fd; 480 int nfd; /* number allocated */ 481 int maxfd; /* highest fd in use */ 482 int exceed; /* debugging */ 483 }; 484 485 enum 486 { 487 DELTAFD = 20 /* incremental increase in Fgrp.fd's */ 488 }; 489 490 struct Pallocmem 491 { 492 ulong base; 493 ulong npage; 494 }; 495 496 struct Palloc 497 { 498 Lock; 499 Pallocmem mem[4]; 500 Page *head; /* most recently used */ 501 Page *tail; /* least recently used */ 502 ulong freecount; /* how many pages on free list now */ 503 Page *pages; /* array of all pages */ 504 ulong user; /* how many user pages */ 505 Page *hash[PGHSIZE]; 506 Lock hashlock; 507 Rendez r; /* Sleep for free mem */ 508 QLock pwait; /* Queue of procs waiting for memory */ 509 }; 510 511 struct Waitq 512 { 513 Waitmsg w; 514 Waitq *next; 515 }; 516 517 /* 518 * fasttick timer interrupts 519 */ 520 enum { 521 /* Mode */ 522 Trelative, /* timer programmed in ns from now */ 523 Tperiodic, /* periodic timer, period in ns */ 524 }; 525 526 struct Timer 527 { 528 /* Public interface */ 529 int tmode; /* See above */ 530 vlong tns; /* meaning defined by mode */ 531 void (*tf)(Ureg*, Timer*); 532 void *ta; 533 /* Internal */ 534 Lock; 535 Timers *tt; /* Timers queue this timer runs on */ 536 Tval tticks; /* tns converted to ticks */ 537 Tval twhen; /* ns represented in fastticks */ 538 Timer *tnext; 539 }; 540 541 enum 542 { 543 RFNAMEG = (1<<0), 544 RFENVG = (1<<1), 545 RFFDG = (1<<2), 546 RFNOTEG = (1<<3), 547 RFPROC = (1<<4), 548 RFMEM = (1<<5), 549 RFNOWAIT = (1<<6), 550 RFCNAMEG = (1<<10), 551 RFCENVG = (1<<11), 552 RFCFDG = (1<<12), 553 RFREND = (1<<13), 554 RFNOMNT = (1<<14), 555 }; 556 557 /* 558 * process memory segments - NSEG always last ! 559 */ 560 enum 561 { 562 SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG 563 }; 564 565 enum 566 { 567 Dead = 0, /* Process states */ 568 Moribund, 569 Ready, 570 Scheding, 571 Running, 572 Queueing, 573 QueueingR, 574 QueueingW, 575 Wakeme, 576 Broken, 577 Stopped, 578 Rendezvous, 579 Waitrelease, 580 581 Proc_stopme = 1, /* devproc requests */ 582 Proc_exitme, 583 Proc_traceme, 584 Proc_exitbig, 585 Proc_tracesyscall, 586 587 TUser = 0, /* Proc.time */ 588 TSys, 589 TReal, 590 TCUser, 591 TCSys, 592 TCReal, 593 594 NERR = 64, 595 NNOTE = 5, 596 597 Npriq = 20, /* number of scheduler priority levels */ 598 Nrq = Npriq+2, /* number of priority levels including real time */ 599 PriRelease = Npriq, /* released edf processes */ 600 PriEdf = Npriq+1, /* active edf processes */ 601 PriNormal = 10, /* base priority for normal processes */ 602 PriExtra = Npriq-1, /* edf processes at high best-effort pri */ 603 PriKproc = 13, /* base priority for kernel processes */ 604 PriRoot = 13, /* base priority for root processes */ 605 }; 606 607 struct Schedq 608 { 609 Lock; 610 Proc* head; 611 Proc* tail; 612 int n; 613 }; 614 615 struct Proc 616 { 617 Label sched; /* known to l.s */ 618 char *kstack; /* known to l.s */ 619 Mach *mach; /* machine running this proc */ 620 char *text; 621 char *user; 622 char *args; 623 int nargs; /* number of bytes of args */ 624 Proc *rnext; /* next process in run queue */ 625 Proc *qnext; /* next process on queue for a QLock */ 626 QLock *qlock; /* addr of qlock being queued for DEBUG */ 627 int state; 628 char *psstate; /* What /proc/#/status reports */ 629 Segment *seg[NSEG]; 630 QLock seglock; /* locked whenever seg[] changes */ 631 ulong pid; 632 ulong noteid; /* Equivalent of note group */ 633 Proc *pidhash; /* next proc in pid hash */ 634 635 Lock exl; /* Lock count and waitq */ 636 Waitq *waitq; /* Exited processes wait children */ 637 int nchild; /* Number of living children */ 638 int nwait; /* Number of uncollected wait records */ 639 QLock qwaitr; 640 Rendez waitr; /* Place to hang out in wait */ 641 Proc *parent; 642 643 Pgrp *pgrp; /* Process group for namespace */ 644 Egrp *egrp; /* Environment group */ 645 Fgrp *fgrp; /* File descriptor group */ 646 Rgrp *rgrp; /* Rendez group */ 647 648 Fgrp *closingfgrp; /* used during teardown */ 649 650 ulong parentpid; 651 ulong time[6]; /* User, Sys, Real; child U, S, R */ 652 653 uvlong kentry; /* Kernel entry time stamp (for profiling) */ 654 /* 655 * pcycles: cycles spent in this process (updated on procsave/restore) 656 * when this is the current proc and we're in the kernel 657 * (procrestores outnumber procsaves by one) 658 * the number of cycles spent in the proc is pcycles + cycles() 659 * when this is not the current process or we're in user mode 660 * (procrestores and procsaves balance), it is pcycles. 661 */ 662 vlong pcycles; 663 664 int insyscall; 665 int fpstate; 666 667 QLock debug; /* to access debugging elements of User */ 668 Proc *pdbg; /* the debugging process */ 669 ulong procmode; /* proc device file mode */ 670 ulong privatemem; /* proc does not let anyone read mem */ 671 int hang; /* hang at next exec for debug */ 672 int procctl; /* Control for /proc debugging */ 673 ulong pc; /* DEBUG only */ 674 675 Lock rlock; /* sync sleep/wakeup with postnote */ 676 Rendez *r; /* rendezvous point slept on */ 677 Rendez sleep; /* place for syssleep/debug */ 678 int notepending; /* note issued but not acted on */ 679 int kp; /* true if a kernel process */ 680 Proc *palarm; /* Next alarm time */ 681 ulong alarm; /* Time of call */ 682 int newtlb; /* Pager has changed my pte's, I must flush */ 683 int noswap; /* process is not swappable */ 684 685 uintptr rendtag; /* Tag for rendezvous */ 686 uintptr rendval; /* Value for rendezvous */ 687 Proc *rendhash; /* Hash list for tag values */ 688 689 Timer; /* For tsleep and real-time */ 690 Rendez *trend; 691 int (*tfn)(void*); 692 void (*kpfun)(void*); 693 void *kparg; 694 695 FPsave fpsave; /* address of this is known by db */ 696 int scallnr; /* sys call number - known by db */ 697 Sargs s; /* address of this is known by db */ 698 int nerrlab; 699 Label errlab[NERR]; 700 char *syserrstr; /* last error from a system call, errbuf0 or 1 */ 701 char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ 702 char errbuf0[ERRMAX]; 703 char errbuf1[ERRMAX]; 704 char genbuf[128]; /* buffer used e.g. for last name element from namec */ 705 Chan *slash; 706 Chan *dot; 707 708 Note note[NNOTE]; 709 short nnote; 710 short notified; /* sysnoted is due */ 711 Note lastnote; 712 int (*notify)(void*, char*); 713 714 Lock *lockwait; 715 Lock *lastlock; /* debugging */ 716 Lock *lastilock; /* debugging */ 717 718 Mach *wired; 719 Mach *mp; /* machine this process last ran on */ 720 Ref nlocks; /* number of locks held by proc */ 721 ulong delaysched; 722 ulong priority; /* priority level */ 723 ulong basepri; /* base priority level */ 724 uchar fixedpri; /* priority level deson't change */ 725 ulong cpu; /* cpu average */ 726 ulong lastupdate; 727 uchar yield; /* non-zero if the process just did a sleep(0) */ 728 ulong readytime; /* time process came ready */ 729 ulong movetime; /* last time process switched processors */ 730 int preempted; /* true if this process hasn't finished the interrupt 731 * that last preempted it 732 */ 733 Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */ 734 int trace; /* process being traced? */ 735 736 ulong qpc; /* pc calling last blocking qlock */ 737 738 int setargs; 739 740 void *ureg; /* User registers for notes */ 741 void *dbgreg; /* User registers for devproc */ 742 Notsave; 743 744 /* 745 * machine specific MMU 746 */ 747 PMMU; 748 }; 749 750 enum 751 { 752 PRINTSIZE = 256, 753 MAXCRYPT = 127, 754 NUMSIZE = 12, /* size of formatted number */ 755 MB = (1024*1024), 756 READSTR = 1000, /* temporary buffer size for device reads */ 757 }; 758 759 extern Conf conf; 760 extern char* conffile; 761 extern int cpuserver; 762 extern Dev* devtab[]; 763 extern char* eve; 764 extern char hostdomain[]; 765 extern uchar initcode[]; 766 extern int kbdbuttons; 767 extern Queue* kbdq; 768 extern Queue* kprintoq; 769 extern Ref noteidalloc; 770 extern int nsyscall; 771 extern Palloc palloc; 772 extern Queue* serialoq; 773 extern char* statename[]; 774 extern Image swapimage; 775 extern char* sysname; 776 extern uint qiomaxatomic; 777 778 enum 779 { 780 LRESPROF = 3, 781 }; 782 783 /* 784 * action log 785 */ 786 struct Log { 787 Lock; 788 int opens; 789 char* buf; 790 char *end; 791 char *rptr; 792 int len; 793 int nlog; 794 int minread; 795 796 int logmask; /* mask of things to debug */ 797 798 QLock readq; 799 Rendez readr; 800 }; 801 802 struct Logflag { 803 char* name; 804 int mask; 805 }; 806 807 enum 808 { 809 NCMDFIELD = 128 810 }; 811 812 struct Cmdbuf 813 { 814 char *buf; 815 char **f; 816 int nf; 817 }; 818 819 struct Cmdtab 820 { 821 int index; /* used by client to switch on result */ 822 char *cmd; /* command name */ 823 int narg; /* expected #args; 0 ==> variadic */ 824 }; 825 826 /* 827 * routines to access UART hardware 828 */ 829 struct PhysUart 830 { 831 char* name; 832 Uart* (*pnp)(void); 833 void (*enable)(Uart*, int); 834 void (*disable)(Uart*); 835 void (*kick)(Uart*); 836 void (*dobreak)(Uart*, int); 837 int (*baud)(Uart*, int); 838 int (*bits)(Uart*, int); 839 int (*stop)(Uart*, int); 840 int (*parity)(Uart*, int); 841 void (*modemctl)(Uart*, int); 842 void (*rts)(Uart*, int); 843 void (*dtr)(Uart*, int); 844 long (*status)(Uart*, void*, long, long); 845 void (*fifo)(Uart*, int); 846 void (*power)(Uart*, int); 847 int (*getc)(Uart*); /* polling versions, for iprint, rdb */ 848 void (*putc)(Uart*, int); 849 }; 850 851 enum { 852 Stagesize= 2048 853 }; 854 855 /* 856 * software UART 857 */ 858 struct Uart 859 { 860 void* regs; /* hardware stuff */ 861 void* saveregs; /* place to put registers on power down */ 862 char* name; /* internal name */ 863 ulong freq; /* clock frequency */ 864 int bits; /* bits per character */ 865 int stop; /* stop bits */ 866 int parity; /* even, odd or no parity */ 867 int baud; /* baud rate */ 868 PhysUart*phys; 869 int console; /* used as a serial console */ 870 int special; /* internal kernel device */ 871 Uart* next; /* list of allocated uarts */ 872 873 QLock; 874 int type; /* ?? */ 875 int dev; 876 int opens; 877 878 int enabled; 879 Uart *elist; /* next enabled interface */ 880 881 int perr; /* parity errors */ 882 int ferr; /* framing errors */ 883 int oerr; /* rcvr overruns */ 884 int berr; /* no input buffers */ 885 int serr; /* input queue overflow */ 886 887 /* buffers */ 888 int (*putc)(Queue*, int); 889 Queue *iq; 890 Queue *oq; 891 892 Lock rlock; 893 uchar istage[Stagesize]; 894 uchar *iw; 895 uchar *ir; 896 uchar *ie; 897 898 Lock tlock; /* transmit */ 899 uchar ostage[Stagesize]; 900 uchar *op; 901 uchar *oe; 902 int drain; 903 904 int modem; /* hardware flow control on */ 905 int xonoff; /* software flow control on */ 906 int blocked; 907 int cts, dsr, dcd; /* keep track of modem status */ 908 int ctsbackoff; 909 int hup_dsr, hup_dcd; /* send hangup upstream? */ 910 int dohup; 911 912 Rendez r; 913 }; 914 915 extern Uart* consuart; 916 917 /* 918 * performance timers, all units in perfticks 919 */ 920 struct Perf 921 { 922 ulong intrts; /* time of last interrupt */ 923 ulong inintr; /* time since last clock tick in interrupt handlers */ 924 ulong avg_inintr; /* avg time per clock tick in interrupt handlers */ 925 ulong inidle; /* time since last clock tick in idle loop */ 926 ulong avg_inidle; /* avg time per clock tick in idle loop */ 927 ulong last; /* value of perfticks() at last clock tick */ 928 ulong period; /* perfticks() per clock tick */ 929 }; 930 931 struct Watchdog 932 { 933 void (*enable)(void); /* watchdog enable */ 934 void (*disable)(void); /* watchdog disable */ 935 void (*restart)(void); /* watchdog restart */ 936 void (*stat)(char*, char*); /* watchdog statistics */ 937 }; 938 939 940 /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ 941 enum 942 { 943 /* Queue.state */ 944 Qstarve = (1<<0), /* consumer starved */ 945 Qmsg = (1<<1), /* message stream */ 946 Qclosed = (1<<2), /* queue has been closed/hungup */ 947 Qflow = (1<<3), /* producer flow controlled */ 948 Qcoalesce = (1<<4), /* coallesce packets on read */ 949 Qkick = (1<<5), /* always call the kick routine after qwrite */ 950 }; 951 952 953 #define DEVDOTDOT -1 954 955 #pragma varargck argpos print 1 956 #pragma varargck argpos snprint 3 957 #pragma varargck argpos sprint 2 958 #pragma varargck argpos fprint 2 959 #pragma varargck argpos panic 1 960 961 #pragma varargck type "lld" vlong 962 #pragma varargck type "llx" vlong 963 #pragma varargck type "lld" uvlong 964 #pragma varargck type "llx" uvlong 965 #pragma varargck type "lx" void* 966 #pragma varargck type "ld" long 967 #pragma varargck type "lx" long 968 #pragma varargck type "ld" ulong 969 #pragma varargck type "lx" ulong 970 #pragma varargck type "d" int 971 #pragma varargck type "x" int 972 #pragma varargck type "c" int 973 #pragma varargck type "C" int 974 #pragma varargck type "d" uint 975 #pragma varargck type "x" uint 976 #pragma varargck type "c" uint 977 #pragma varargck type "C" uint 978 #pragma varargck type "s" char* 979 #pragma varargck type "S" Rune* 980 #pragma varargck type "r" void 981 #pragma varargck type "%" void 982 #pragma varargck type "I" uchar* 983 #pragma varargck type "V" uchar* 984 #pragma varargck type "E" uchar* 985 #pragma varargck type "M" uchar* 986 #pragma varargck type "p" uintptr 987 #pragma varargck type "p" void* 988 #pragma varargck type "q" char* 989 #pragma varargck flag ',' 990