1 typedef struct Alarms Alarms; 2 typedef struct Block Block; 3 typedef struct Bkpt Bkpt; 4 typedef struct BkptCond BkptCond; 5 typedef struct Chan Chan; 6 typedef struct Cmdbuf Cmdbuf; 7 typedef struct Cmdtab Cmdtab; 8 typedef struct Cname Cname; 9 typedef struct Crypt Crypt; 10 typedef struct Dev Dev; 11 typedef struct DevConf DevConf; 12 typedef struct Dirtab Dirtab; 13 typedef struct Edf Edf; 14 typedef struct Egrp Egrp; 15 typedef struct Evalue Evalue; 16 typedef struct Fgrp Fgrp; 17 typedef struct List List; 18 typedef struct Log Log; 19 typedef struct Logflag Logflag; 20 typedef struct Mntcache Mntcache; 21 typedef struct Mntparam Mntparam; 22 typedef struct Mount Mount; 23 typedef struct Mntrpc Mntrpc; 24 typedef struct Mntwalk Mntwalk; 25 typedef struct Mnt Mnt; 26 typedef struct Mhead Mhead; 27 typedef struct Osenv Osenv; 28 typedef struct Pgrp Pgrp; 29 typedef struct Proc Proc; 30 typedef struct QLock QLock; 31 typedef struct Queue Queue; 32 typedef struct Ref Ref; 33 typedef struct Rendez Rendez; 34 typedef struct Rept Rept; 35 typedef struct Rootdata Rootdata; 36 typedef struct RWlock RWlock; 37 typedef struct Signerkey Signerkey; 38 typedef struct Skeyset Skeyset; 39 typedef struct Talarm Talarm; 40 typedef struct Timer Timer; 41 typedef struct Timers Timers; 42 typedef struct Uart Uart; 43 typedef struct Walkqid Walkqid; 44 typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); 45 46 #pragma incomplete DevConf 47 #pragma incomplete Edf 48 #pragma incomplete Mntcache 49 #pragma incomplete Mntrpc 50 #pragma incomplete Queue 51 #pragma incomplete Timers 52 53 #include "fcall.h" 54 #include <pool.h> 55 56 struct Ref 57 { 58 Lock l; 59 long ref; 60 }; 61 62 struct Rendez 63 { 64 Lock; 65 Proc *p; 66 }; 67 68 struct Rept 69 { 70 Lock l; 71 Rendez r; 72 void *o; 73 int t; 74 int (*active)(void*); 75 int (*ck)(void*, int); 76 void (*f)(void*); /* called with VM acquire()'d */ 77 }; 78 79 struct Osenv 80 { 81 char *syserrstr; /* last error from a system call, errbuf0 or 1 */ 82 char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ 83 char errbuf0[ERRMAX]; 84 char errbuf1[ERRMAX]; 85 Pgrp* pgrp; /* Ref to namespace, working dir and root */ 86 Fgrp* fgrp; /* Ref to file descriptors */ 87 Egrp* egrp; /* Environment vars */ 88 Skeyset* sigs; /* Signed module keys */ 89 Rendez* rend; /* Synchro point */ 90 Queue* waitq; /* Info about dead children */ 91 Queue* childq; /* Info about children for debuggers */ 92 void* debug; /* Debugging master */ 93 int uid; /* Numeric user id for system */ 94 int gid; /* Numeric group id for system */ 95 char* user; /* Inferno user name */ 96 FPenv fpu; /* Floating point thread state */ 97 }; 98 99 enum 100 { 101 Nopin = -1 102 }; 103 104 struct QLock 105 { 106 Lock use; /* to access Qlock structure */ 107 Proc *head; /* next process waiting for object */ 108 Proc *tail; /* last process waiting for object */ 109 int locked; /* flag */ 110 }; 111 112 struct RWlock 113 { 114 Lock; /* Lock modify lock */ 115 QLock x; /* Mutual exclusion lock */ 116 QLock k; /* Lock for waiting writers */ 117 int readers; /* Count of readers in lock */ 118 }; 119 120 struct Talarm 121 { 122 Lock; 123 Proc* list; 124 }; 125 126 struct Alarms 127 { 128 QLock; 129 Proc* head; 130 }; 131 132 struct Rootdata 133 { 134 int dotdot; 135 void *ptr; 136 int size; 137 int *sizep; 138 }; 139 140 /* 141 * Access types in namec & channel flags 142 */ 143 enum 144 { 145 Aaccess, /* as in stat, wstat */ 146 Abind, /* for left-hand-side of bind */ 147 Atodir, /* as in chdir */ 148 Aopen, /* for i/o */ 149 Amount, /* to be mounted or mounted upon */ 150 Acreate, /* is to be created */ 151 Aremove, /* will be removed by caller */ 152 153 COPEN = 0x0001, /* for i/o */ 154 CMSG = 0x0002, /* the message channel for a mount */ 155 CCEXEC = 0x0008, /* close on exec */ 156 CFREE = 0x0010, /* not in use */ 157 CRCLOSE = 0x0020, /* remove on close */ 158 CCACHE = 0x0080, /* client cache */ 159 }; 160 161 enum 162 { 163 BINTR = (1<<0), 164 BFREE = (1<<1), 165 Bipck = (1<<2), /* ip checksum */ 166 Budpck = (1<<3), /* udp checksum */ 167 Btcpck = (1<<4), /* tcp checksum */ 168 Bpktck = (1<<5), /* packet checksum */ 169 }; 170 171 struct Block 172 { 173 Block* next; 174 Block* list; 175 uchar* rp; /* first unconsumed byte */ 176 uchar* wp; /* first empty byte */ 177 uchar* lim; /* 1 past the end of the buffer */ 178 uchar* base; /* start of the buffer */ 179 void (*free)(Block*); 180 ushort flag; 181 ushort checksum; /* IP checksum of complete packet (minus media header) */ 182 }; 183 #define BLEN(s) ((s)->wp - (s)->rp) 184 #define BALLOC(s) ((s)->lim - (s)->base) 185 186 struct Chan 187 { 188 Lock; 189 Ref; 190 Chan* next; /* allocation */ 191 Chan* link; 192 vlong offset; /* in file */ 193 ushort type; 194 ulong dev; 195 ushort mode; /* read/write */ 196 ushort flag; 197 Qid qid; 198 int fid; /* for devmnt */ 199 ulong iounit; /* chunk size for i/o; 0==default */ 200 Mhead* umh; /* mount point that derived Chan; used in unionread */ 201 Chan* umc; /* channel in union; held for union read */ 202 QLock umqlock; /* serialize unionreads */ 203 int uri; /* union read index */ 204 int dri; /* devdirread index */ 205 ulong mountid; 206 Mntcache *mcp; /* Mount cache pointer */ 207 Mnt *mux; /* Mnt for clients using me for messages */ 208 union { 209 void* aux; 210 char tag[4]; /* for iproute */ 211 }; 212 Chan* mchan; /* channel to mounted server */ 213 Qid mqid; /* qid of root of mount point */ 214 Cname *name; 215 }; 216 217 struct Cname 218 { 219 Ref; 220 int alen; /* allocated length */ 221 int len; /* strlen(s) */ 222 char *s; 223 }; 224 225 struct Dev 226 { 227 int dc; 228 char* name; 229 230 void (*reset)(void); 231 void (*init)(void); 232 void (*shutdown)(void); 233 Chan* (*attach)(char*); 234 Walkqid* (*walk)(Chan*, Chan*, char**, int); 235 int (*stat)(Chan*, uchar*, int); 236 Chan* (*open)(Chan*, int); 237 void (*create)(Chan*, char*, int, ulong); 238 void (*close)(Chan*); 239 long (*read)(Chan*, void*, long, vlong); 240 Block* (*bread)(Chan*, long, ulong); 241 long (*write)(Chan*, void*, long, vlong); 242 long (*bwrite)(Chan*, Block*, ulong); 243 void (*remove)(Chan*); 244 int (*wstat)(Chan*, uchar*, int); 245 void (*power)(int); /* power mgt: power(1) → on, power (0) → off */ 246 int (*config)(int, char*, DevConf*); 247 }; 248 249 struct Dirtab 250 { 251 char name[KNAMELEN]; 252 Qid qid; 253 vlong length; 254 long perm; 255 }; 256 257 struct Walkqid 258 { 259 Chan *clone; 260 int nqid; 261 Qid qid[1]; 262 }; 263 264 enum 265 { 266 NSMAX = 1000, 267 NSLOG = 7, 268 NSCACHE = (1<<NSLOG), 269 }; 270 271 struct Mntwalk /* state for /proc/#/ns */ 272 { 273 int cddone; 274 ulong id; 275 Mhead* mh; 276 Mount* cm; 277 }; 278 279 struct Mount 280 { 281 ulong mountid; 282 Mount* next; 283 Mhead* head; 284 Mount* copy; 285 Mount* order; 286 Chan* to; /* channel replacing channel */ 287 int mflag; 288 char *spec; 289 }; 290 291 struct Mhead 292 { 293 Ref; 294 RWlock lock; 295 Chan* from; /* channel mounted upon */ 296 Mount* mount; /* what's mounted upon it */ 297 Mhead* hash; /* Hash chain */ 298 }; 299 300 struct Mnt 301 { 302 Lock; 303 /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */ 304 Chan *c; /* Channel to file service */ 305 Proc *rip; /* Reader in progress */ 306 Mntrpc *queue; /* Queue of pending requests on this channel */ 307 ulong id; /* Multiplexer id for channel check */ 308 Mnt *list; /* Free list */ 309 int flags; /* cache */ 310 int msize; /* data + IOHDRSZ */ 311 char *version; /* 9P version */ 312 Queue *q; /* input queue */ 313 }; 314 315 enum 316 { 317 RENDLOG = 5, 318 RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */ 319 MNTLOG = 5, 320 MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */ 321 DELTAFD= 20, /* allocation quantum for process file descriptors */ 322 MAXNFD = 4000, /* max per process file descriptors */ 323 MAXKEY = 8, /* keys for signed modules */ 324 }; 325 #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)]) 326 327 struct Mntparam { 328 Chan* chan; 329 Chan* authchan; 330 char* spec; 331 int flags; 332 }; 333 334 struct Pgrp 335 { 336 Ref; /* also used as a lock when mounting */ 337 ulong pgrpid; 338 QLock debug; /* single access via devproc.c */ 339 RWlock ns; /* Namespace n read/one write lock */ 340 QLock nsh; 341 Mhead* mnthash[MNTHASH]; 342 int progmode; 343 Chan* dot; 344 Chan* slash; 345 int nodevs; 346 int pin; 347 }; 348 349 struct Fgrp 350 { 351 Lock; 352 Ref; 353 Chan** fd; 354 int nfd; /* number of fd slots */ 355 int maxfd; /* highest fd in use */ 356 int minfd; /* lower bound on free fd */ 357 }; 358 359 struct Evalue 360 { 361 char *var; 362 char *val; 363 int len; 364 Qid qid; 365 Evalue *next; 366 }; 367 368 struct Egrp 369 { 370 Ref; 371 QLock; 372 Evalue *entries; 373 ulong path; /* qid.path of next Evalue to be allocated */ 374 ulong vers; /* of Egrp */ 375 }; 376 377 struct Signerkey 378 { 379 Ref; 380 char* owner; 381 ushort footprint; 382 ulong expires; 383 void* alg; 384 void* pk; 385 void (*pkfree)(void*); 386 }; 387 388 struct Skeyset 389 { 390 Ref; 391 QLock; 392 ulong flags; 393 char* devs; 394 int nkey; 395 Signerkey *keys[MAXKEY]; 396 }; 397 398 /* 399 * fasttick timer interrupts 400 */ 401 enum { 402 /* Mode */ 403 Trelative, /* timer programmed in ns from now */ 404 Tabsolute, /* timer programmed in ns since epoch */ 405 Tperiodic, /* periodic timer, period in ns */ 406 }; 407 408 struct Timer 409 { 410 /* Public interface */ 411 int tmode; /* See above */ 412 vlong tns; /* meaning defined by mode */ 413 void (*tf)(Ureg*, Timer*); 414 void *ta; 415 /* Internal */ 416 Lock; 417 Timers *tt; /* Timers queue this timer runs on */ 418 vlong twhen; /* ns represented in fastticks */ 419 Timer *tnext; 420 }; 421 422 enum 423 { 424 Dead = 0, /* Process states */ 425 Moribund, 426 Ready, 427 Scheding, 428 Running, 429 Queueing, 430 Wakeme, 431 Broken, 432 Stopped, 433 Rendezvous, 434 Waitrelease, 435 436 Proc_stopme = 1, /* devproc requests */ 437 Proc_exitme, 438 Proc_traceme, 439 Proc_exitbig, 440 441 NERR = 30, 442 443 Unknown = 0, 444 IdleGC, 445 Interp, 446 BusyGC, 447 448 PriLock = 0, /* Holding Spin lock */ 449 PriEdf, /* active edf processes */ 450 PriRelease, /* released edf processes */ 451 PriRealtime, /* Video telephony */ 452 PriHicodec, /* MPEG codec */ 453 PriLocodec, /* Audio codec */ 454 PriHi, /* Important task */ 455 PriNormal, 456 PriLo, 457 PriBackground, 458 PriExtra, /* edf processes we don't care about */ 459 Nrq 460 }; 461 462 struct Proc 463 { 464 Label sched; /* known to l.s */ 465 char* kstack; /* known to l.s */ 466 Mach* mach; /* machine running this proc */ 467 char text[KNAMELEN]; 468 Proc* rnext; /* next process in run queue */ 469 Proc* qnext; /* next process on queue for a QLock */ 470 QLock* qlock; /* addrof qlock being queued for DEBUG */ 471 int state; 472 int type; 473 void* prog; /* Dummy Prog for interp release */ 474 void* iprog; 475 Osenv* env; 476 Osenv defenv; 477 int swipend; /* software interrupt pending for Prog */ 478 Lock sysio; /* note handler lock */ 479 char* psstate; /* What /proc/#/status reports */ 480 ulong pid; 481 int fpstate; 482 int procctl; /* Control for /proc debugging */ 483 ulong pc; /* DEBUG only */ 484 Lock rlock; /* sync between sleep/swiproc for r */ 485 Rendez* r; /* rendezvous point slept on */ 486 Rendez sleep; /* place for syssleep/debug */ 487 int killed; /* by swiproc */ 488 int kp; /* true if a kernel process */ 489 ulong alarm; /* Time of call */ 490 int pri; /* scheduler priority */ 491 ulong twhen; 492 Rendez* trend; 493 Proc* tlink; 494 int (*tfn)(void*); 495 void (*kpfun)(void*); 496 void* arg; 497 FPU fpsave; 498 int scallnr; 499 int nerrlab; 500 Label errlab[NERR]; 501 char genbuf[128]; /* buffer used e.g. for last name element from namec */ 502 Mach* mp; /* machine this process last ran on */ 503 Mach* wired; 504 ulong movetime; /* next time process should switch processors */ 505 ulong delaysched; 506 int preempted; /* process yielding in interrupt */ 507 ulong qpc; /* last call that blocked in qlock */ 508 void* dbgreg; /* User registers for devproc */ 509 int dbgstop; /* don't run this kproc */ 510 Edf* edf; /* if non-null, real-time proc, edf contains scheduling params */ 511 }; 512 513 enum 514 { 515 /* kproc flags */ 516 KPDUPPG = (1<<0), 517 KPDUPFDG = (1<<1), 518 KPDUPENVG = (1<<2), 519 KPDUP = KPDUPPG | KPDUPFDG | KPDUPENVG 520 }; 521 522 enum { 523 BrkSched, 524 BrkNoSched, 525 }; 526 527 struct BkptCond 528 { 529 uchar op; 530 ulong val; 531 BkptCond *next; 532 }; 533 534 struct Bkpt 535 { 536 int id; 537 ulong addr; 538 BkptCond *conditions; 539 Instr instr; 540 void (*handler)(Bkpt*); 541 void *aux; 542 Bkpt *next; 543 Bkpt *link; 544 }; 545 546 enum 547 { 548 PRINTSIZE = 256, 549 NUMSIZE = 12, /* size of formatted number */ 550 MB = (1024*1024), 551 READSTR = 1000, /* temporary buffer size for device reads */ 552 }; 553 554 extern Conf conf; 555 extern char* conffile; 556 extern int consoleprint; 557 extern Dev* devtab[]; 558 extern char* eve; 559 extern int hwcurs; 560 extern FPU initfp; 561 extern Queue *kbdq; 562 extern Queue *kscanq; 563 extern Ref noteidalloc; 564 extern Queue *printq; 565 extern uint qiomaxatomic; 566 extern char* statename[]; 567 extern char* sysname; 568 extern Talarm talarm; 569 570 /* 571 * action log 572 */ 573 struct Log { 574 Lock; 575 int opens; 576 char* buf; 577 char *end; 578 char *rptr; 579 int len; 580 int nlog; 581 int minread; 582 583 int logmask; /* mask of things to debug */ 584 585 QLock readq; 586 Rendez readr; 587 }; 588 589 struct Logflag { 590 char* name; 591 int mask; 592 }; 593 594 struct Cmdbuf 595 { 596 char *buf; 597 char **f; 598 int nf; 599 }; 600 601 struct Cmdtab 602 { 603 int index; /* used by client to switch on result */ 604 char *cmd; /* command name */ 605 int narg; /* expected #args; 0 ==> variadic */ 606 }; 607 608 enum 609 { 610 MAXPOOL = 8, 611 }; 612 613 extern Pool* mainmem; 614 extern Pool* heapmem; 615 extern Pool* imagmem; 616 617 /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ 618 enum 619 { 620 /* Queue.state */ 621 Qstarve = (1<<0), /* consumer starved */ 622 Qmsg = (1<<1), /* message stream */ 623 Qclosed = (1<<2), /* queue has been closed/hungup */ 624 Qflow = (1<<3), /* producer flow controlled */ 625 Qcoalesce = (1<<4), /* coallesce packets on read */ 626 Qkick = (1<<5), /* always call the kick routine after qwrite */ 627 }; 628 629 #define DEVDOTDOT -1 630 631 #pragma varargck argpos print 1 632 #pragma varargck argpos snprint 3 633 #pragma varargck argpos seprint 3 634 #pragma varargck argpos sprint 2 635 #pragma varargck argpos fprint 2 636 #pragma varargck argpos iprint 1 637 #pragma varargck argpos panic 1 638 #pragma varargck argpos kwerrstr 1 639 #pragma varargck argpos kprint 1 640 641 #pragma varargck type "lld" vlong 642 #pragma varargck type "llx" vlong 643 #pragma varargck type "lld" uvlong 644 #pragma varargck type "llx" uvlong 645 #pragma varargck type "lx" void* 646 #pragma varargck type "ld" long 647 #pragma varargck type "lx" long 648 #pragma varargck type "ld" ulong 649 #pragma varargck type "lx" ulong 650 #pragma varargck type "d" int 651 #pragma varargck type "x" int 652 #pragma varargck type "c" int 653 #pragma varargck type "C" int 654 #pragma varargck type "d" uint 655 #pragma varargck type "x" uint 656 #pragma varargck type "c" uint 657 #pragma varargck type "C" uint 658 #pragma varargck type "f" double 659 #pragma varargck type "e" double 660 #pragma varargck type "g" double 661 #pragma varargck type "s" char* 662 #pragma varargck type "S" Rune* 663 #pragma varargck type "r" void 664 #pragma varargck type "%" void 665 #pragma varargck type "I" uchar* 666 #pragma varargck type "V" uchar* 667 #pragma varargck type "E" uchar* 668 #pragma varargck type "M" uchar* 669 #pragma varargck type "p" void* 670 #pragma varargck type "q" char* 671