19ef1f84bSDavid du Colombier typedef struct Alarms Alarms; 29ef1f84bSDavid du Colombier typedef struct Block Block; 39ef1f84bSDavid du Colombier typedef struct Chan Chan; 49ef1f84bSDavid du Colombier typedef struct Cmdbuf Cmdbuf; 59ef1f84bSDavid du Colombier typedef struct Cmdtab Cmdtab; 69ef1f84bSDavid du Colombier typedef struct Confmem Confmem; 79ef1f84bSDavid du Colombier typedef struct Dev Dev; 89ef1f84bSDavid du Colombier typedef struct DevConf DevConf; 99ef1f84bSDavid du Colombier typedef struct Dirtab Dirtab; 109ef1f84bSDavid du Colombier typedef struct Edf Edf; 119ef1f84bSDavid du Colombier typedef struct Egrp Egrp; 129ef1f84bSDavid du Colombier typedef struct Evalue Evalue; 13406c76faSDavid du Colombier typedef struct Execvals Execvals; 149ef1f84bSDavid du Colombier typedef struct Fastcall Fastcall; 159ef1f84bSDavid du Colombier typedef struct Fgrp Fgrp; 169ef1f84bSDavid du Colombier typedef struct Image Image; 179ef1f84bSDavid du Colombier typedef struct Log Log; 189ef1f84bSDavid du Colombier typedef struct Logflag Logflag; 199ef1f84bSDavid du Colombier typedef struct Mntcache Mntcache; 209ef1f84bSDavid du Colombier typedef struct Mount Mount; 219ef1f84bSDavid du Colombier typedef struct Mntrpc Mntrpc; 229ef1f84bSDavid du Colombier typedef struct Mntwalk Mntwalk; 239ef1f84bSDavid du Colombier typedef struct Mnt Mnt; 249ef1f84bSDavid du Colombier typedef struct Mhead Mhead; 259ef1f84bSDavid du Colombier typedef struct Note Note; 269ef1f84bSDavid du Colombier typedef struct Page Page; 279ef1f84bSDavid du Colombier typedef struct Path Path; 289ef1f84bSDavid du Colombier typedef struct Palloc Palloc; 29*094d6818SDavid du Colombier typedef struct Pallocpg Pallocpg; 309ef1f84bSDavid du Colombier typedef struct Perf Perf; 319ef1f84bSDavid du Colombier typedef struct PhysUart PhysUart; 329ef1f84bSDavid du Colombier typedef struct Pgrp Pgrp; 339ef1f84bSDavid du Colombier typedef struct Physseg Physseg; 349ef1f84bSDavid du Colombier typedef struct Proc Proc; 359ef1f84bSDavid du Colombier typedef struct Procalloc Procalloc; 369ef1f84bSDavid du Colombier typedef struct Pte Pte; 379ef1f84bSDavid du Colombier typedef struct QLock QLock; 389ef1f84bSDavid du Colombier typedef struct Queue Queue; 399ef1f84bSDavid du Colombier typedef struct Ref Ref; 409ef1f84bSDavid du Colombier typedef struct Rendez Rendez; 419ef1f84bSDavid du Colombier typedef struct Rgrp Rgrp; 429ef1f84bSDavid du Colombier typedef struct RWlock RWlock; 439ef1f84bSDavid du Colombier typedef struct Schedq Schedq; 449ef1f84bSDavid du Colombier typedef struct Segment Segment; 459ef1f84bSDavid du Colombier typedef struct Sema Sema; 469ef1f84bSDavid du Colombier typedef struct Timer Timer; 479ef1f84bSDavid du Colombier typedef struct Timers Timers; 489ef1f84bSDavid du Colombier typedef struct Uart Uart; 499ef1f84bSDavid du Colombier typedef struct Waitq Waitq; 509ef1f84bSDavid du Colombier typedef struct Walkqid Walkqid; 519ef1f84bSDavid du Colombier typedef struct Watchdog Watchdog; 52277b6efdSDavid du Colombier typedef struct Watermark Watermark; 539ef1f84bSDavid du Colombier typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); 549ef1f84bSDavid du Colombier 559ef1f84bSDavid du Colombier #pragma incomplete DevConf 569ef1f84bSDavid du Colombier #pragma incomplete Edf 579ef1f84bSDavid du Colombier #pragma incomplete Mntcache 589ef1f84bSDavid du Colombier #pragma incomplete Mntrpc 599ef1f84bSDavid du Colombier #pragma incomplete Queue 609ef1f84bSDavid du Colombier #pragma incomplete Timers 619ef1f84bSDavid du Colombier 629ef1f84bSDavid du Colombier #include <fcall.h> 639ef1f84bSDavid du Colombier 649ef1f84bSDavid du Colombier struct Ref 659ef1f84bSDavid du Colombier { 669ef1f84bSDavid du Colombier Lock; 679ef1f84bSDavid du Colombier int ref; 689ef1f84bSDavid du Colombier }; 699ef1f84bSDavid du Colombier 709ef1f84bSDavid du Colombier struct Rendez 719ef1f84bSDavid du Colombier { 729ef1f84bSDavid du Colombier Lock; 739ef1f84bSDavid du Colombier Proc *p; 749ef1f84bSDavid du Colombier }; 759ef1f84bSDavid du Colombier 769ef1f84bSDavid du Colombier struct QLock 779ef1f84bSDavid du Colombier { 789ef1f84bSDavid du Colombier Lock use; /* to access Qlock structure */ 799ef1f84bSDavid du Colombier Proc *head; /* next process waiting for object */ 809ef1f84bSDavid du Colombier Proc *tail; /* last process waiting for object */ 819ef1f84bSDavid du Colombier int locked; /* flag */ 82406c76faSDavid du Colombier uintptr qpc; /* pc of the holder */ 839ef1f84bSDavid du Colombier }; 849ef1f84bSDavid du Colombier 859ef1f84bSDavid du Colombier struct RWlock 869ef1f84bSDavid du Colombier { 879ef1f84bSDavid du Colombier Lock use; 889ef1f84bSDavid du Colombier Proc *head; /* list of waiting processes */ 899ef1f84bSDavid du Colombier Proc *tail; 909ef1f84bSDavid du Colombier uintptr wpc; /* pc of writer */ 919ef1f84bSDavid du Colombier Proc *wproc; /* writing proc */ 929ef1f84bSDavid du Colombier int readers; /* number of readers */ 939ef1f84bSDavid du Colombier int writer; /* number of writers */ 949ef1f84bSDavid du Colombier }; 959ef1f84bSDavid du Colombier 969ef1f84bSDavid du Colombier struct Alarms 979ef1f84bSDavid du Colombier { 989ef1f84bSDavid du Colombier QLock; 999ef1f84bSDavid du Colombier Proc *head; 1009ef1f84bSDavid du Colombier }; 1019ef1f84bSDavid du Colombier 1029ef1f84bSDavid du Colombier /* 1039ef1f84bSDavid du Colombier * Access types in namec & channel flags 1049ef1f84bSDavid du Colombier */ 1059ef1f84bSDavid du Colombier enum 1069ef1f84bSDavid du Colombier { 1079ef1f84bSDavid du Colombier Aaccess, /* as in stat, wstat */ 1089ef1f84bSDavid du Colombier Abind, /* for left-hand-side of bind */ 1099ef1f84bSDavid du Colombier Atodir, /* as in chdir */ 1109ef1f84bSDavid du Colombier Aopen, /* for i/o */ 1119ef1f84bSDavid du Colombier Amount, /* to be mounted or mounted upon */ 1129ef1f84bSDavid du Colombier Acreate, /* is to be created */ 1139ef1f84bSDavid du Colombier Aremove, /* will be removed by caller */ 1149ef1f84bSDavid du Colombier 1159ef1f84bSDavid du Colombier COPEN = 0x0001, /* for i/o */ 1169ef1f84bSDavid du Colombier CMSG = 0x0002, /* the message channel for a mount */ 1179ef1f84bSDavid du Colombier /*rsc CCREATE = 0x0004, /* permits creation if c->mnt */ 1189ef1f84bSDavid du Colombier CCEXEC = 0x0008, /* close on exec */ 1199ef1f84bSDavid du Colombier CFREE = 0x0010, /* not in use */ 1209ef1f84bSDavid du Colombier CRCLOSE = 0x0020, /* remove on close */ 1219ef1f84bSDavid du Colombier CCACHE = 0x0080, /* client cache */ 1229ef1f84bSDavid du Colombier }; 1239ef1f84bSDavid du Colombier 1249ef1f84bSDavid du Colombier /* flag values */ 1259ef1f84bSDavid du Colombier enum 1269ef1f84bSDavid du Colombier { 1279ef1f84bSDavid du Colombier BINTR = (1<<0), 1289ef1f84bSDavid du Colombier 1299ef1f84bSDavid du Colombier Bipck = (1<<2), /* ip checksum */ 1309ef1f84bSDavid du Colombier Budpck = (1<<3), /* udp checksum */ 1319ef1f84bSDavid du Colombier Btcpck = (1<<4), /* tcp checksum */ 1329ef1f84bSDavid du Colombier Bpktck = (1<<5), /* packet checksum */ 1339ef1f84bSDavid du Colombier }; 1349ef1f84bSDavid du Colombier 1359ef1f84bSDavid du Colombier struct Block 1369ef1f84bSDavid du Colombier { 1379ef1f84bSDavid du Colombier Block* next; 1389ef1f84bSDavid du Colombier Block* list; 1399ef1f84bSDavid du Colombier uchar* rp; /* first unconsumed byte */ 1409ef1f84bSDavid du Colombier uchar* wp; /* first empty byte */ 1419ef1f84bSDavid du Colombier uchar* lim; /* 1 past the end of the buffer */ 1429ef1f84bSDavid du Colombier uchar* base; /* start of the buffer */ 1439ef1f84bSDavid du Colombier void (*free)(Block*); 1449ef1f84bSDavid du Colombier ushort flag; 1459ef1f84bSDavid du Colombier ushort checksum; /* IP checksum of complete packet (minus media header) */ 146406c76faSDavid du Colombier ulong magic; 1479ef1f84bSDavid du Colombier }; 1489ef1f84bSDavid du Colombier #define BLEN(s) ((s)->wp - (s)->rp) 1499ef1f84bSDavid du Colombier #define BALLOC(s) ((s)->lim - (s)->base) 1509ef1f84bSDavid du Colombier 1519ef1f84bSDavid du Colombier struct Chan 1529ef1f84bSDavid du Colombier { 1539ef1f84bSDavid du Colombier Ref; /* the Lock in this Ref is also Chan's lock */ 1549ef1f84bSDavid du Colombier Chan* next; /* allocation */ 1559ef1f84bSDavid du Colombier Chan* link; 1569ef1f84bSDavid du Colombier vlong offset; /* in fd */ 1579ef1f84bSDavid du Colombier vlong devoffset; /* in underlying device; see read */ 1589ef1f84bSDavid du Colombier Dev* dev; 1599ef1f84bSDavid du Colombier uint devno; 1609ef1f84bSDavid du Colombier ushort mode; /* read/write */ 1619ef1f84bSDavid du Colombier ushort flag; 1629ef1f84bSDavid du Colombier Qid qid; 1639ef1f84bSDavid du Colombier int fid; /* for devmnt */ 1649ef1f84bSDavid du Colombier ulong iounit; /* chunk size for i/o; 0==default */ 1659ef1f84bSDavid du Colombier Mhead* umh; /* mount point that derived Chan; used in unionread */ 1669ef1f84bSDavid du Colombier Chan* umc; /* channel in union; held for union read */ 1679ef1f84bSDavid du Colombier QLock umqlock; /* serialize unionreads */ 1689ef1f84bSDavid du Colombier int uri; /* union read index */ 1699ef1f84bSDavid du Colombier int dri; /* devdirread index */ 1709ef1f84bSDavid du Colombier uchar* dirrock; /* directory entry rock for translations */ 1719ef1f84bSDavid du Colombier int nrock; 1729ef1f84bSDavid du Colombier int mrock; 1739ef1f84bSDavid du Colombier QLock rockqlock; 1749ef1f84bSDavid du Colombier int ismtpt; 1759ef1f84bSDavid du Colombier Mntcache*mc; /* Mount cache pointer */ 1769ef1f84bSDavid du Colombier Mnt* mux; /* Mnt for clients using me for messages */ 1779ef1f84bSDavid du Colombier union { 1789ef1f84bSDavid du Colombier void* aux; 1799ef1f84bSDavid du Colombier Qid pgrpid; /* for #p/notepg */ 1809ef1f84bSDavid du Colombier ulong mid; /* for ns in devproc */ 1819ef1f84bSDavid du Colombier }; 1829ef1f84bSDavid du Colombier Chan* mchan; /* channel to mounted server */ 1839ef1f84bSDavid du Colombier Qid mqid; /* qid of root of mount point */ 1849ef1f84bSDavid du Colombier Path* path; 1859ef1f84bSDavid du Colombier }; 1869ef1f84bSDavid du Colombier 1879ef1f84bSDavid du Colombier struct Path 1889ef1f84bSDavid du Colombier { 1899ef1f84bSDavid du Colombier Ref; 1909ef1f84bSDavid du Colombier char* s; 1919ef1f84bSDavid du Colombier Chan** mtpt; /* mtpt history */ 1929ef1f84bSDavid du Colombier int len; /* strlen(s) */ 1939ef1f84bSDavid du Colombier int alen; /* allocated length of s */ 1949ef1f84bSDavid du Colombier int mlen; /* number of path elements */ 1959ef1f84bSDavid du Colombier int malen; /* allocated length of mtpt */ 1969ef1f84bSDavid du Colombier }; 1979ef1f84bSDavid du Colombier 1989ef1f84bSDavid du Colombier struct Dev 1999ef1f84bSDavid du Colombier { 2009ef1f84bSDavid du Colombier int dc; 2019ef1f84bSDavid du Colombier char* name; 2029ef1f84bSDavid du Colombier 2039ef1f84bSDavid du Colombier void (*reset)(void); 2049ef1f84bSDavid du Colombier void (*init)(void); 2059ef1f84bSDavid du Colombier void (*shutdown)(void); 2069ef1f84bSDavid du Colombier Chan* (*attach)(char*); 2079ef1f84bSDavid du Colombier Walkqid*(*walk)(Chan*, Chan*, char**, int); 2089ef1f84bSDavid du Colombier long (*stat)(Chan*, uchar*, long); 2099ef1f84bSDavid du Colombier Chan* (*open)(Chan*, int); 2109ef1f84bSDavid du Colombier void (*create)(Chan*, char*, int, int); 2119ef1f84bSDavid du Colombier void (*close)(Chan*); 2129ef1f84bSDavid du Colombier long (*read)(Chan*, void*, long, vlong); 2139ef1f84bSDavid du Colombier Block* (*bread)(Chan*, long, vlong); 2149ef1f84bSDavid du Colombier long (*write)(Chan*, void*, long, vlong); 2159ef1f84bSDavid du Colombier long (*bwrite)(Chan*, Block*, vlong); 2169ef1f84bSDavid du Colombier void (*remove)(Chan*); 2179ef1f84bSDavid du Colombier long (*wstat)(Chan*, uchar*, long); 2189ef1f84bSDavid du Colombier void (*power)(int); /* power mgt: power(1) => on, power (0) => off */ 2199ef1f84bSDavid du Colombier int (*config)(int, char*, DevConf*); /* returns 0 on error */ 2209ef1f84bSDavid du Colombier }; 2219ef1f84bSDavid du Colombier 2229ef1f84bSDavid du Colombier struct Dirtab 2239ef1f84bSDavid du Colombier { 2249ef1f84bSDavid du Colombier char name[KNAMELEN]; 2259ef1f84bSDavid du Colombier Qid qid; 2269ef1f84bSDavid du Colombier vlong length; 2279ef1f84bSDavid du Colombier long perm; 2289ef1f84bSDavid du Colombier }; 2299ef1f84bSDavid du Colombier 2309ef1f84bSDavid du Colombier struct Walkqid 2319ef1f84bSDavid du Colombier { 2329ef1f84bSDavid du Colombier Chan *clone; 2339ef1f84bSDavid du Colombier int nqid; 2349ef1f84bSDavid du Colombier Qid qid[1]; 2359ef1f84bSDavid du Colombier }; 2369ef1f84bSDavid du Colombier 2379ef1f84bSDavid du Colombier enum 2389ef1f84bSDavid du Colombier { 2399ef1f84bSDavid du Colombier NSMAX = 1000, 2409ef1f84bSDavid du Colombier NSLOG = 7, 2419ef1f84bSDavid du Colombier NSCACHE = (1<<NSLOG), 2429ef1f84bSDavid du Colombier }; 2439ef1f84bSDavid du Colombier 2449ef1f84bSDavid du Colombier struct Mntwalk /* state for /proc/#/ns */ 2459ef1f84bSDavid du Colombier { 2469ef1f84bSDavid du Colombier int cddone; 2479ef1f84bSDavid du Colombier Mhead* mh; 2489ef1f84bSDavid du Colombier Mount* cm; 2499ef1f84bSDavid du Colombier }; 2509ef1f84bSDavid du Colombier 2519ef1f84bSDavid du Colombier struct Mount 2529ef1f84bSDavid du Colombier { 2539ef1f84bSDavid du Colombier int mountid; 2549ef1f84bSDavid du Colombier Mount* next; 2559ef1f84bSDavid du Colombier Mhead* head; 2569ef1f84bSDavid du Colombier Mount* copy; 2579ef1f84bSDavid du Colombier Mount* order; 2589ef1f84bSDavid du Colombier Chan* to; /* channel replacing channel */ 2599ef1f84bSDavid du Colombier int mflag; 2609ef1f84bSDavid du Colombier char *spec; 2619ef1f84bSDavid du Colombier }; 2629ef1f84bSDavid du Colombier 2639ef1f84bSDavid du Colombier struct Mhead 2649ef1f84bSDavid du Colombier { 2659ef1f84bSDavid du Colombier Ref; 2669ef1f84bSDavid du Colombier RWlock lock; 2679ef1f84bSDavid du Colombier Chan* from; /* channel mounted upon */ 2689ef1f84bSDavid du Colombier Mount* mount; /* what's mounted upon it */ 2699ef1f84bSDavid du Colombier Mhead* hash; /* Hash chain */ 2709ef1f84bSDavid du Colombier }; 2719ef1f84bSDavid du Colombier 2729ef1f84bSDavid du Colombier struct Mnt 2739ef1f84bSDavid du Colombier { 2749ef1f84bSDavid du Colombier Lock; 2759ef1f84bSDavid du Colombier /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */ 2769ef1f84bSDavid du Colombier Chan *c; /* Channel to file service */ 2779ef1f84bSDavid du Colombier Proc *rip; /* Reader in progress */ 2789ef1f84bSDavid du Colombier Mntrpc *queue; /* Queue of pending requests on this channel */ 2799ef1f84bSDavid du Colombier uint id; /* Multiplexer id for channel check */ 2809ef1f84bSDavid du Colombier Mnt *list; /* Free list */ 2819ef1f84bSDavid du Colombier int flags; /* cache */ 2829ef1f84bSDavid du Colombier int msize; /* data + IOHDRSZ */ 2839ef1f84bSDavid du Colombier char *version; /* 9P version */ 2849ef1f84bSDavid du Colombier Queue *q; /* input queue */ 2859ef1f84bSDavid du Colombier }; 2869ef1f84bSDavid du Colombier 2879ef1f84bSDavid du Colombier enum 2889ef1f84bSDavid du Colombier { 2899ef1f84bSDavid du Colombier NUser, /* note provided externally */ 2909ef1f84bSDavid du Colombier NExit, /* deliver note quietly */ 2919ef1f84bSDavid du Colombier NDebug, /* print debug message */ 2929ef1f84bSDavid du Colombier }; 2939ef1f84bSDavid du Colombier 2949ef1f84bSDavid du Colombier struct Note 2959ef1f84bSDavid du Colombier { 2969ef1f84bSDavid du Colombier char msg[ERRMAX]; 2979ef1f84bSDavid du Colombier int flag; /* whether system posted it */ 2989ef1f84bSDavid du Colombier }; 2999ef1f84bSDavid du Colombier 3009ef1f84bSDavid du Colombier enum 3019ef1f84bSDavid du Colombier { 3029ef1f84bSDavid du Colombier PG_NOFLUSH = 0, 3039ef1f84bSDavid du Colombier PG_TXTFLUSH = 1, /* flush dcache and invalidate icache */ 3049ef1f84bSDavid du Colombier PG_DATFLUSH = 2, /* flush both i & d caches (UNUSED) */ 3059ef1f84bSDavid du Colombier PG_NEWCOL = 3, /* page has been recolored */ 3069ef1f84bSDavid du Colombier 3079ef1f84bSDavid du Colombier PG_MOD = 0x01, /* software modified bit */ 3089ef1f84bSDavid du Colombier PG_REF = 0x02, /* software referenced bit */ 3099ef1f84bSDavid du Colombier }; 3109ef1f84bSDavid du Colombier 3119ef1f84bSDavid du Colombier struct Page 3129ef1f84bSDavid du Colombier { 3139ef1f84bSDavid du Colombier Lock; 3149ef1f84bSDavid du Colombier uintptr pa; /* Physical address in memory */ 3159ef1f84bSDavid du Colombier uintptr va; /* Virtual address for user */ 3169ef1f84bSDavid du Colombier ulong daddr; /* Disc address in file */ 3179ef1f84bSDavid du Colombier int ref; /* Reference count */ 3189ef1f84bSDavid du Colombier uchar modref; /* Simulated modify/reference bits */ 3199ef1f84bSDavid du Colombier uchar color; /* Cache coloring */ 3209ef1f84bSDavid du Colombier uchar lg2size; /* log2(pagesize) */ 3219ef1f84bSDavid du Colombier char cachectl[MACHMAX]; /* Cache flushing control for mmuput */ 3229ef1f84bSDavid du Colombier Image *image; /* Associated image (text) */ 3239ef1f84bSDavid du Colombier Page *next; /* Lru free list */ 3249ef1f84bSDavid du Colombier Page *prev; 3259ef1f84bSDavid du Colombier Page *hash; /* Image hash chains */ 3269ef1f84bSDavid du Colombier }; 3279ef1f84bSDavid du Colombier 328a2a67f40SDavid du Colombier #define pagesize(p) (1<<(p)->lg2size) 329a2a67f40SDavid du Colombier 3309ef1f84bSDavid du Colombier struct Image 3319ef1f84bSDavid du Colombier { 3329ef1f84bSDavid du Colombier Ref; 3339ef1f84bSDavid du Colombier Chan *c; /* channel to text file */ 3349ef1f84bSDavid du Colombier Qid qid; /* Qid for page cache coherence */ 3359ef1f84bSDavid du Colombier Qid mqid; 3369ef1f84bSDavid du Colombier Chan *mchan; 3379ef1f84bSDavid du Colombier int dc; /* Device type of owning channel */ 3389ef1f84bSDavid du Colombier //subtype 3399ef1f84bSDavid du Colombier Segment *s; /* TEXT segment for image if running */ 3409ef1f84bSDavid du Colombier Image *hash; /* Qid hash chains */ 3419ef1f84bSDavid du Colombier Image *next; /* Free list */ 3429ef1f84bSDavid du Colombier int notext; /* no file associated */ 343*094d6818SDavid du Colombier int color; 3449ef1f84bSDavid du Colombier }; 3459ef1f84bSDavid du Colombier 3469ef1f84bSDavid du Colombier struct Pte 3479ef1f84bSDavid du Colombier { 3489ef1f84bSDavid du Colombier Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */ 3499ef1f84bSDavid du Colombier Page **first; /* First used entry */ 3509ef1f84bSDavid du Colombier Page **last; /* Last used entry */ 3519ef1f84bSDavid du Colombier }; 3529ef1f84bSDavid du Colombier 3539ef1f84bSDavid du Colombier /* Segment types */ 3549ef1f84bSDavid du Colombier enum 3559ef1f84bSDavid du Colombier { 3569ef1f84bSDavid du Colombier SG_TYPE = 07, /* Mask type of segment */ 3579ef1f84bSDavid du Colombier SG_TEXT = 00, 3589ef1f84bSDavid du Colombier SG_DATA = 01, 3599ef1f84bSDavid du Colombier SG_BSS = 02, 3609ef1f84bSDavid du Colombier SG_STACK = 03, 3619ef1f84bSDavid du Colombier SG_SHARED = 04, 3629ef1f84bSDavid du Colombier SG_PHYSICAL = 05, 3639ef1f84bSDavid du Colombier 3641247705eSDavid du Colombier SG_CACHED = 0020, /* Physseg can be cached */ 3659ef1f84bSDavid du Colombier SG_RONLY = 0040, /* Segment is read only */ 3669ef1f84bSDavid du Colombier SG_CEXEC = 0100, /* Detach at exec */ 3679ef1f84bSDavid du Colombier }; 3689ef1f84bSDavid du Colombier #define pagedout(s) ((s) == nil) /* only on demand, no swap */ 3699ef1f84bSDavid du Colombier 3709ef1f84bSDavid du Colombier #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) 3719ef1f84bSDavid du Colombier 3729ef1f84bSDavid du Colombier struct Physseg 3739ef1f84bSDavid du Colombier { 3749ef1f84bSDavid du Colombier ulong attr; /* Segment attributes */ 3759ef1f84bSDavid du Colombier char *name; /* Attach name */ 3769ef1f84bSDavid du Colombier uintptr pa; /* Physical address */ 3779ef1f84bSDavid du Colombier usize size; /* Maximum segment size in pages */ 3789ef1f84bSDavid du Colombier Page *(*pgalloc)(Segment*, uintptr); /* Allocation if we need it */ 3799ef1f84bSDavid du Colombier void (*pgfree)(Page*); 3809ef1f84bSDavid du Colombier uchar lg2pgsize; /* log2(size of pages in segment) */ 3819ef1f84bSDavid du Colombier }; 3829ef1f84bSDavid du Colombier 383c171dac4SDavid du Colombier #define physsegpgsize(ps) (1<<(ps)->lg2pgsize) 384c171dac4SDavid du Colombier 3859ef1f84bSDavid du Colombier struct Sema 3869ef1f84bSDavid du Colombier { 3879ef1f84bSDavid du Colombier Rendez; 3889ef1f84bSDavid du Colombier int* addr; 3899ef1f84bSDavid du Colombier int waiting; 3909ef1f84bSDavid du Colombier Sema* next; 3919ef1f84bSDavid du Colombier Sema* prev; 3929ef1f84bSDavid du Colombier }; 3939ef1f84bSDavid du Colombier 394*094d6818SDavid du Colombier #define NOCOLOR -1 395*094d6818SDavid du Colombier 3969ef1f84bSDavid du Colombier struct Segment 3979ef1f84bSDavid du Colombier { 3989ef1f84bSDavid du Colombier Ref; 3999ef1f84bSDavid du Colombier QLock lk; 4009ef1f84bSDavid du Colombier ushort steal; /* Page stealer lock */ 4019ef1f84bSDavid du Colombier ushort type; /* segment type */ 402*094d6818SDavid du Colombier int color; 4039ef1f84bSDavid du Colombier uintptr base; /* virtual base */ 4049ef1f84bSDavid du Colombier uintptr top; /* virtual top */ 4059ef1f84bSDavid du Colombier usize size; /* size in pages */ 4069ef1f84bSDavid du Colombier ulong fstart; /* start address in file for demand load */ 4079ef1f84bSDavid du Colombier ulong flen; /* length of segment in file */ 4089ef1f84bSDavid du Colombier uchar lg2pgsize; /* log2(size of pages in segment) */ 4099ef1f84bSDavid du Colombier int flushme; /* maintain icache for this segment */ 4109ef1f84bSDavid du Colombier Image *image; /* text in file attached to this segment */ 4119ef1f84bSDavid du Colombier Physseg *pseg; 4129ef1f84bSDavid du Colombier ulong* profile; /* Tick profile area */ 4139ef1f84bSDavid du Colombier uintptr ptemapmem; /* space mapped by one Pte in this segment */ 4149ef1f84bSDavid du Colombier Pte **map; 4159ef1f84bSDavid du Colombier int mapsize; 4169ef1f84bSDavid du Colombier Pte *ssegmap[SSEGMAPSIZE]; 4179ef1f84bSDavid du Colombier Lock semalock; 4189ef1f84bSDavid du Colombier Sema sema; 4199ef1f84bSDavid du Colombier }; 4209ef1f84bSDavid du Colombier 42157fe3081SDavid du Colombier #define segpgsize(s) (1<<(s)->lg2pgsize) 42257fe3081SDavid du Colombier 4239ef1f84bSDavid du Colombier enum 4249ef1f84bSDavid du Colombier { 4259ef1f84bSDavid du Colombier RENDLOG = 5, 4269ef1f84bSDavid du Colombier RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */ 4279ef1f84bSDavid du Colombier MNTLOG = 5, 4289ef1f84bSDavid du Colombier MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */ 4299ef1f84bSDavid du Colombier NFD = 100, /* per process file descriptors */ 4309ef1f84bSDavid du Colombier PGHLOG = 9, 4319ef1f84bSDavid du Colombier PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */ 4329ef1f84bSDavid du Colombier }; 4339ef1f84bSDavid du Colombier #define REND(p,s) ((p)->rendhash[(s)&((1<<RENDLOG)-1)]) 4349ef1f84bSDavid du Colombier #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)]) 4359ef1f84bSDavid du Colombier 4369ef1f84bSDavid du Colombier struct Pgrp 4379ef1f84bSDavid du Colombier { 4389ef1f84bSDavid du Colombier Ref; /* also used as a lock when mounting */ 4399ef1f84bSDavid du Colombier int noattach; 4409ef1f84bSDavid du Colombier ulong pgrpid; 4419ef1f84bSDavid du Colombier QLock debug; /* single access via devproc.c */ 4429ef1f84bSDavid du Colombier RWlock ns; /* Namespace n read/one write lock */ 4439ef1f84bSDavid du Colombier Mhead *mnthash[MNTHASH]; 4449ef1f84bSDavid du Colombier }; 4459ef1f84bSDavid du Colombier 4469ef1f84bSDavid du Colombier struct Rgrp 4479ef1f84bSDavid du Colombier { 4489ef1f84bSDavid du Colombier Ref; /* the Ref's lock is also the Rgrp's lock */ 4499ef1f84bSDavid du Colombier Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */ 4509ef1f84bSDavid du Colombier }; 4519ef1f84bSDavid du Colombier 4529ef1f84bSDavid du Colombier struct Egrp 4539ef1f84bSDavid du Colombier { 4549ef1f84bSDavid du Colombier Ref; 4559ef1f84bSDavid du Colombier RWlock; 4569ef1f84bSDavid du Colombier Evalue **ent; 4579ef1f84bSDavid du Colombier int nent; 4589ef1f84bSDavid du Colombier int ment; 4599ef1f84bSDavid du Colombier ulong path; /* qid.path of next Evalue to be allocated */ 4609ef1f84bSDavid du Colombier ulong vers; /* of Egrp */ 4619ef1f84bSDavid du Colombier }; 4629ef1f84bSDavid du Colombier 4639ef1f84bSDavid du Colombier struct Evalue 4649ef1f84bSDavid du Colombier { 4659ef1f84bSDavid du Colombier char *name; 4669ef1f84bSDavid du Colombier char *value; 4679ef1f84bSDavid du Colombier int len; 4689ef1f84bSDavid du Colombier Evalue *link; 4699ef1f84bSDavid du Colombier Qid qid; 4709ef1f84bSDavid du Colombier }; 4719ef1f84bSDavid du Colombier 4729ef1f84bSDavid du Colombier struct Fgrp 4739ef1f84bSDavid du Colombier { 4749ef1f84bSDavid du Colombier Ref; 4759ef1f84bSDavid du Colombier Chan **fd; 4769ef1f84bSDavid du Colombier int nfd; /* number allocated */ 4779ef1f84bSDavid du Colombier int maxfd; /* highest fd in use */ 4789ef1f84bSDavid du Colombier int exceed; /* debugging */ 4799ef1f84bSDavid du Colombier }; 4809ef1f84bSDavid du Colombier 4819ef1f84bSDavid du Colombier enum 4829ef1f84bSDavid du Colombier { 4839ef1f84bSDavid du Colombier DELTAFD = 20 /* incremental increase in Fgrp.fd's */ 4849ef1f84bSDavid du Colombier }; 4859ef1f84bSDavid du Colombier 486*094d6818SDavid du Colombier struct Pallocpg 4879ef1f84bSDavid du Colombier { 488*094d6818SDavid du Colombier Page *head; /* most recently used */ 489*094d6818SDavid du Colombier Page *tail; /* least recently used */ 490*094d6818SDavid du Colombier ulong count; /* how many pages made */ 491*094d6818SDavid du Colombier ulong freecount; /* how many pages on free list now */ 4929ef1f84bSDavid du Colombier }; 4939ef1f84bSDavid du Colombier 4949ef1f84bSDavid du Colombier struct Palloc 4959ef1f84bSDavid du Colombier { 4969ef1f84bSDavid du Colombier Lock; 497*094d6818SDavid du Colombier Pallocpg avail[32]; /* indexed by log2 of page size (Page.lgsize) */ 4989ef1f84bSDavid du Colombier ulong user; /* how many user pages */ 4999ef1f84bSDavid du Colombier Page *hash[PGHSIZE]; 5009ef1f84bSDavid du Colombier Lock hashlock; 5019ef1f84bSDavid du Colombier Rendez r; /* Sleep for free mem */ 5029ef1f84bSDavid du Colombier QLock pwait; /* Queue of procs waiting for memory */ 5039ef1f84bSDavid du Colombier }; 5049ef1f84bSDavid du Colombier 5059ef1f84bSDavid du Colombier struct Waitq 5069ef1f84bSDavid du Colombier { 5079ef1f84bSDavid du Colombier Waitmsg w; 5089ef1f84bSDavid du Colombier Waitq *next; 5099ef1f84bSDavid du Colombier }; 5109ef1f84bSDavid du Colombier 5119ef1f84bSDavid du Colombier /* 5129ef1f84bSDavid du Colombier * fasttick timer interrupts 5139ef1f84bSDavid du Colombier */ 5149ef1f84bSDavid du Colombier enum { 5159ef1f84bSDavid du Colombier /* Mode */ 5169ef1f84bSDavid du Colombier Trelative, /* timer programmed in ns from now */ 5179ef1f84bSDavid du Colombier Tperiodic, /* periodic timer, period in ns */ 5189ef1f84bSDavid du Colombier }; 5199ef1f84bSDavid du Colombier 5209ef1f84bSDavid du Colombier struct Timer 5219ef1f84bSDavid du Colombier { 5229ef1f84bSDavid du Colombier /* Public interface */ 5239ef1f84bSDavid du Colombier int tmode; /* See above */ 5249ef1f84bSDavid du Colombier vlong tns; /* meaning defined by mode */ 5259ef1f84bSDavid du Colombier void (*tf)(Ureg*, Timer*); 5269ef1f84bSDavid du Colombier void *ta; 5279ef1f84bSDavid du Colombier /* Internal */ 5289ef1f84bSDavid du Colombier Lock; 5299ef1f84bSDavid du Colombier Timers *tt; /* Timers queue this timer runs on */ 530406c76faSDavid du Colombier Tval tticks; /* tns converted to ticks */ 531406c76faSDavid du Colombier Tval twhen; /* ns represented in fastticks */ 5329ef1f84bSDavid du Colombier Timer *tnext; 5339ef1f84bSDavid du Colombier }; 5349ef1f84bSDavid du Colombier 5359ef1f84bSDavid du Colombier enum 5369ef1f84bSDavid du Colombier { 5379ef1f84bSDavid du Colombier RFNAMEG = (1<<0), 5389ef1f84bSDavid du Colombier RFENVG = (1<<1), 5399ef1f84bSDavid du Colombier RFFDG = (1<<2), 5409ef1f84bSDavid du Colombier RFNOTEG = (1<<3), 5419ef1f84bSDavid du Colombier RFPROC = (1<<4), 5429ef1f84bSDavid du Colombier RFMEM = (1<<5), 5439ef1f84bSDavid du Colombier RFNOWAIT = (1<<6), 5449ef1f84bSDavid du Colombier RFCNAMEG = (1<<10), 5459ef1f84bSDavid du Colombier RFCENVG = (1<<11), 5469ef1f84bSDavid du Colombier RFCFDG = (1<<12), 5479ef1f84bSDavid du Colombier RFREND = (1<<13), 5489ef1f84bSDavid du Colombier RFNOMNT = (1<<14), 5499ef1f84bSDavid du Colombier }; 5509ef1f84bSDavid du Colombier 5519ef1f84bSDavid du Colombier /* 5529ef1f84bSDavid du Colombier * process memory segments - NSEG always last ! 5539ef1f84bSDavid du Colombier */ 5549ef1f84bSDavid du Colombier enum 5559ef1f84bSDavid du Colombier { 5569ef1f84bSDavid du Colombier SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG 5579ef1f84bSDavid du Colombier }; 5589ef1f84bSDavid du Colombier 5599ef1f84bSDavid du Colombier enum 5609ef1f84bSDavid du Colombier { 5619ef1f84bSDavid du Colombier Dead = 0, /* Process states */ 5629ef1f84bSDavid du Colombier Moribund, 5639ef1f84bSDavid du Colombier Ready, 5649ef1f84bSDavid du Colombier Scheding, 5659ef1f84bSDavid du Colombier Running, 5669ef1f84bSDavid du Colombier Queueing, 5679ef1f84bSDavid du Colombier QueueingR, 5689ef1f84bSDavid du Colombier QueueingW, 5699ef1f84bSDavid du Colombier Wakeme, 5709ef1f84bSDavid du Colombier Broken, 5719ef1f84bSDavid du Colombier Stopped, 5729ef1f84bSDavid du Colombier Rendezvous, 5739ef1f84bSDavid du Colombier Waitrelease, 5749ef1f84bSDavid du Colombier 5759ef1f84bSDavid du Colombier Proc_stopme = 1, /* devproc requests */ 5769ef1f84bSDavid du Colombier Proc_exitme, 5779ef1f84bSDavid du Colombier Proc_traceme, 5789ef1f84bSDavid du Colombier Proc_exitbig, 5799ef1f84bSDavid du Colombier Proc_tracesyscall, 5809ef1f84bSDavid du Colombier 5819ef1f84bSDavid du Colombier TUser = 0, /* Proc.time */ 5829ef1f84bSDavid du Colombier TSys, 5839ef1f84bSDavid du Colombier TReal, 5849ef1f84bSDavid du Colombier TCUser, 5859ef1f84bSDavid du Colombier TCSys, 5869ef1f84bSDavid du Colombier TCReal, 5879ef1f84bSDavid du Colombier 5889ef1f84bSDavid du Colombier NERR = 64, 5899ef1f84bSDavid du Colombier NNOTE = 5, 5909ef1f84bSDavid du Colombier 5919ef1f84bSDavid du Colombier Npriq = 20, /* number of scheduler priority levels */ 5929ef1f84bSDavid du Colombier Nrq = Npriq+2, /* number of priority levels including real time */ 5939ef1f84bSDavid du Colombier PriRelease = Npriq, /* released edf processes */ 5949ef1f84bSDavid du Colombier PriEdf = Npriq+1, /* active edf processes */ 5959ef1f84bSDavid du Colombier PriNormal = 10, /* base priority for normal processes */ 5969ef1f84bSDavid du Colombier PriExtra = Npriq-1, /* edf processes at high best-effort pri */ 5979ef1f84bSDavid du Colombier PriKproc = 13, /* base priority for kernel processes */ 5989ef1f84bSDavid du Colombier PriRoot = 13, /* base priority for root processes */ 5999ef1f84bSDavid du Colombier }; 6009ef1f84bSDavid du Colombier 6019ef1f84bSDavid du Colombier struct Schedq 6029ef1f84bSDavid du Colombier { 6039ef1f84bSDavid du Colombier Lock; 6049ef1f84bSDavid du Colombier Proc* head; 6059ef1f84bSDavid du Colombier Proc* tail; 6069ef1f84bSDavid du Colombier int n; 6079ef1f84bSDavid du Colombier }; 6089ef1f84bSDavid du Colombier 6099ef1f84bSDavid du Colombier typedef union Ar0 Ar0; 6109ef1f84bSDavid du Colombier union Ar0 { 6115cdedb5bSDavid du Colombier uintptr i; 6125cdedb5bSDavid du Colombier uintptr l; 6139ef1f84bSDavid du Colombier uintptr p; 6149ef1f84bSDavid du Colombier usize u; 6159ef1f84bSDavid du Colombier void* v; 6169ef1f84bSDavid du Colombier vlong vl; 6179ef1f84bSDavid du Colombier }; 6189ef1f84bSDavid du Colombier 6199ef1f84bSDavid du Colombier struct Proc 6209ef1f84bSDavid du Colombier { 6219ef1f84bSDavid du Colombier Label sched; /* known to l.s */ 6229ef1f84bSDavid du Colombier char *kstack; /* known to l.s */ 6239ef1f84bSDavid du Colombier Mach *mach; /* machine running this proc */ 6249ef1f84bSDavid du Colombier char *text; 6259ef1f84bSDavid du Colombier char *user; 6269ef1f84bSDavid du Colombier char *args; 6279ef1f84bSDavid du Colombier int nargs; /* number of bytes of args */ 6289ef1f84bSDavid du Colombier Proc *rnext; /* next process in run queue */ 6299ef1f84bSDavid du Colombier Proc *qnext; /* next process on queue for a QLock */ 6309ef1f84bSDavid du Colombier QLock *qlock; /* addr of qlock being queued for DEBUG */ 6319ef1f84bSDavid du Colombier int state; 6329ef1f84bSDavid du Colombier char *psstate; /* What /proc/#/status reports */ 6339ef1f84bSDavid du Colombier Segment *seg[NSEG]; 6349ef1f84bSDavid du Colombier QLock seglock; /* locked whenever seg[] changes */ 6359ef1f84bSDavid du Colombier int pid; 6369ef1f84bSDavid du Colombier int index; /* index (slot) in proc array */ 6379ef1f84bSDavid du Colombier int ref; /* indirect reference */ 6389ef1f84bSDavid du Colombier int noteid; /* Equivalent of note group */ 6399ef1f84bSDavid du Colombier Proc *pidhash; /* next proc in pid hash */ 6409ef1f84bSDavid du Colombier 6419ef1f84bSDavid du Colombier Lock exl; /* Lock count and waitq */ 6429ef1f84bSDavid du Colombier Waitq *waitq; /* Exited processes wait children */ 6439ef1f84bSDavid du Colombier int nchild; /* Number of living children */ 6449ef1f84bSDavid du Colombier int nwait; /* Number of uncollected wait records */ 6459ef1f84bSDavid du Colombier QLock qwaitr; 6469ef1f84bSDavid du Colombier Rendez waitr; /* Place to hang out in wait */ 6479ef1f84bSDavid du Colombier Proc *parent; 6489ef1f84bSDavid du Colombier 6499ef1f84bSDavid du Colombier Pgrp *pgrp; /* Process group for namespace */ 6509ef1f84bSDavid du Colombier Egrp *egrp; /* Environment group */ 6519ef1f84bSDavid du Colombier Fgrp *fgrp; /* File descriptor group */ 6529ef1f84bSDavid du Colombier Rgrp *rgrp; /* Rendez group */ 6539ef1f84bSDavid du Colombier 6549ef1f84bSDavid du Colombier Fgrp *closingfgrp; /* used during teardown */ 6559ef1f84bSDavid du Colombier 6569ef1f84bSDavid du Colombier int parentpid; 6579ef1f84bSDavid du Colombier ulong time[6]; /* User, Sys, Real; child U, S, R */ 6589ef1f84bSDavid du Colombier 6599ef1f84bSDavid du Colombier uvlong kentry; /* Kernel entry time stamp (for profiling) */ 6609ef1f84bSDavid du Colombier /* 6619ef1f84bSDavid du Colombier * pcycles: cycles spent in this process (updated on procsave/restore) 6629ef1f84bSDavid du Colombier * when this is the current proc and we're in the kernel 6639ef1f84bSDavid du Colombier * (procrestores outnumber procsaves by one) 6649ef1f84bSDavid du Colombier * the number of cycles spent in the proc is pcycles + cycles() 6659ef1f84bSDavid du Colombier * when this is not the current process or we're in user mode 6669ef1f84bSDavid du Colombier * (procrestores and procsaves balance), it is pcycles. 6679ef1f84bSDavid du Colombier */ 6689ef1f84bSDavid du Colombier vlong pcycles; 6699ef1f84bSDavid du Colombier 6709ef1f84bSDavid du Colombier int insyscall; 6719ef1f84bSDavid du Colombier 6729ef1f84bSDavid du Colombier QLock debug; /* to access debugging elements of User */ 6739ef1f84bSDavid du Colombier Proc *pdbg; /* the debugging process */ 6749ef1f84bSDavid du Colombier ulong procmode; /* proc device file mode */ 6759ef1f84bSDavid du Colombier ulong privatemem; /* proc does not let anyone read mem */ 6769ef1f84bSDavid du Colombier int hang; /* hang at next exec for debug */ 6779ef1f84bSDavid du Colombier int procctl; /* Control for /proc debugging */ 6789ef1f84bSDavid du Colombier uintptr pc; /* DEBUG only */ 6799ef1f84bSDavid du Colombier 6809ef1f84bSDavid du Colombier Lock rlock; /* sync sleep/wakeup with postnote */ 6819ef1f84bSDavid du Colombier Rendez *r; /* rendezvous point slept on */ 6829ef1f84bSDavid du Colombier Rendez sleep; /* place for syssleep/debug */ 6839ef1f84bSDavid du Colombier int notepending; /* note issued but not acted on */ 6849ef1f84bSDavid du Colombier int kp; /* true if a kernel process */ 6859ef1f84bSDavid du Colombier Proc *palarm; /* Next alarm time */ 6869ef1f84bSDavid du Colombier ulong alarm; /* Time of call */ 6879ef1f84bSDavid du Colombier int newtlb; /* Pager has changed my pte's, I must flush */ 6889ef1f84bSDavid du Colombier 6899ef1f84bSDavid du Colombier uintptr rendtag; /* Tag for rendezvous */ 6909ef1f84bSDavid du Colombier uintptr rendval; /* Value for rendezvous */ 6919ef1f84bSDavid du Colombier Proc *rendhash; /* Hash list for tag values */ 6929ef1f84bSDavid du Colombier 6939ef1f84bSDavid du Colombier Timer; /* For tsleep and real-time */ 6949ef1f84bSDavid du Colombier Rendez *trend; 6959ef1f84bSDavid du Colombier int (*tfn)(void*); 6969ef1f84bSDavid du Colombier void (*kpfun)(void*); 6979ef1f84bSDavid du Colombier void *kparg; 6989ef1f84bSDavid du Colombier 6999ef1f84bSDavid du Colombier int scallnr; /* system call number */ 7009ef1f84bSDavid du Colombier uchar arg[MAXSYSARG*sizeof(void*)]; /* system call arguments */ 7019ef1f84bSDavid du Colombier int nerrlab; 7029ef1f84bSDavid du Colombier Label errlab[NERR]; 7039ef1f84bSDavid du Colombier char *syserrstr; /* last error from a system call, errbuf0 or 1 */ 7049ef1f84bSDavid du Colombier char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ 7059ef1f84bSDavid du Colombier char errbuf0[ERRMAX]; 7069ef1f84bSDavid du Colombier char errbuf1[ERRMAX]; 7079ef1f84bSDavid du Colombier char genbuf[128]; /* buffer used e.g. for last name element from namec */ 7089ef1f84bSDavid du Colombier Chan *slash; 7099ef1f84bSDavid du Colombier Chan *dot; 7109ef1f84bSDavid du Colombier 7119ef1f84bSDavid du Colombier Note note[NNOTE]; 7129ef1f84bSDavid du Colombier short nnote; 7139ef1f84bSDavid du Colombier short notified; /* sysnoted is due */ 7149ef1f84bSDavid du Colombier Note lastnote; 7159ef1f84bSDavid du Colombier void (*notify)(void*, char*); 7169ef1f84bSDavid du Colombier 7179ef1f84bSDavid du Colombier Lock *lockwait; 7189ef1f84bSDavid du Colombier Lock *lastlock; /* debugging */ 7199ef1f84bSDavid du Colombier Lock *lastilock; /* debugging */ 7209ef1f84bSDavid du Colombier 7219ef1f84bSDavid du Colombier Mach *wired; 7229ef1f84bSDavid du Colombier Mach *mp; /* machine this process last ran on */ 7239ef1f84bSDavid du Colombier int nlocks; /* number of locks held by proc */ 7249ef1f84bSDavid du Colombier ulong delaysched; 7259ef1f84bSDavid du Colombier ulong priority; /* priority level */ 7269ef1f84bSDavid du Colombier ulong basepri; /* base priority level */ 7279ef1f84bSDavid du Colombier int fixedpri; /* priority level does not change */ 7289ef1f84bSDavid du Colombier ulong cpu; /* cpu average */ 7299ef1f84bSDavid du Colombier ulong lastupdate; 7309ef1f84bSDavid du Colombier ulong readytime; /* time process came ready */ 7319ef1f84bSDavid du Colombier ulong movetime; /* last time process switched processors */ 7329ef1f84bSDavid du Colombier int preempted; /* true if this process hasn't finished the interrupt 7339ef1f84bSDavid du Colombier * that last preempted it 7349ef1f84bSDavid du Colombier */ 7359ef1f84bSDavid du Colombier Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */ 7369ef1f84bSDavid du Colombier int trace; /* process being traced? */ 7379ef1f84bSDavid du Colombier 7389ef1f84bSDavid du Colombier uintptr qpc; /* pc calling last blocking qlock */ 7399ef1f84bSDavid du Colombier 7409ef1f84bSDavid du Colombier int setargs; 7419ef1f84bSDavid du Colombier 7429ef1f84bSDavid du Colombier void *ureg; /* User registers for notes */ 7439ef1f84bSDavid du Colombier void *dbgreg; /* User registers for devproc */ 744*094d6818SDavid du Colombier int color; 7459ef1f84bSDavid du Colombier 7469ef1f84bSDavid du Colombier Fastcall* fc; 7479ef1f84bSDavid du Colombier int fcount; 7489ef1f84bSDavid du Colombier char* syscalltrace; 7499ef1f84bSDavid du Colombier 7509ef1f84bSDavid du Colombier /* 7519ef1f84bSDavid du Colombier * machine specific fpu, mmu and notify 7529ef1f84bSDavid du Colombier */ 7539ef1f84bSDavid du Colombier PFPU; 7549ef1f84bSDavid du Colombier PMMU; 7559ef1f84bSDavid du Colombier PNOTIFY; 7569ef1f84bSDavid du Colombier }; 7579ef1f84bSDavid du Colombier 7589ef1f84bSDavid du Colombier enum 7599ef1f84bSDavid du Colombier { 7609ef1f84bSDavid du Colombier PROCMAX = 2000, /* maximum number of processes */ 7619ef1f84bSDavid du Colombier }; 7629ef1f84bSDavid du Colombier 7639ef1f84bSDavid du Colombier struct Procalloc 7649ef1f84bSDavid du Colombier { 7659ef1f84bSDavid du Colombier Lock; 7669ef1f84bSDavid du Colombier Proc* ht[128]; 7679ef1f84bSDavid du Colombier Proc* arena; 7689ef1f84bSDavid du Colombier Proc* free; 7699ef1f84bSDavid du Colombier }; 7709ef1f84bSDavid du Colombier 7719ef1f84bSDavid du Colombier enum 7729ef1f84bSDavid du Colombier { 7739ef1f84bSDavid du Colombier PRINTSIZE = 256, 7749ef1f84bSDavid du Colombier NUMSIZE = 12, /* size of formatted number */ 7759ef1f84bSDavid du Colombier /* READSTR was 1000, which is way too small for usb's ctl file */ 7769ef1f84bSDavid du Colombier READSTR = 4000, /* temporary buffer size for device reads */ 7779ef1f84bSDavid du Colombier }; 7789ef1f84bSDavid du Colombier 779406c76faSDavid du Colombier struct Execvals { 780406c76faSDavid du Colombier uvlong entry; 781406c76faSDavid du Colombier ulong textsize; 782406c76faSDavid du Colombier ulong datasize; 783406c76faSDavid du Colombier }; 784406c76faSDavid du Colombier 7859ef1f84bSDavid du Colombier extern char* conffile; 7869ef1f84bSDavid du Colombier extern char configfile[]; 7879ef1f84bSDavid du Colombier extern int cpuserver; 7889ef1f84bSDavid du Colombier extern char* eve; 7899ef1f84bSDavid du Colombier extern char hostdomain[]; 7909ef1f84bSDavid du Colombier extern uchar initcode[]; 7919ef1f84bSDavid du Colombier extern int kbdbuttons; 7929ef1f84bSDavid du Colombier extern Ref noteidalloc; 7939ef1f84bSDavid du Colombier extern int nphysseg; 7949ef1f84bSDavid du Colombier extern int nsyscall; 7959ef1f84bSDavid du Colombier extern Palloc palloc; 796406c76faSDavid du Colombier int (*parseboothdr)(Chan *, ulong, Execvals *); 7979ef1f84bSDavid du Colombier extern Physseg physseg[]; 7989ef1f84bSDavid du Colombier extern Procalloc procalloc; 7999ef1f84bSDavid du Colombier extern uint qiomaxatomic; 8009ef1f84bSDavid du Colombier extern char* statename[]; 8019ef1f84bSDavid du Colombier extern char* sysname; 8029ef1f84bSDavid du Colombier extern struct { 8039ef1f84bSDavid du Colombier char* n; 8049ef1f84bSDavid du Colombier void (*f)(Ar0*, va_list); 8059ef1f84bSDavid du Colombier Ar0 r; 8069ef1f84bSDavid du Colombier } systab[]; 8079ef1f84bSDavid du Colombier 8089ef1f84bSDavid du Colombier enum 8099ef1f84bSDavid du Colombier { 8109ef1f84bSDavid du Colombier LRESPROF = 3, 8119ef1f84bSDavid du Colombier }; 8129ef1f84bSDavid du Colombier 8139ef1f84bSDavid du Colombier /* 8149ef1f84bSDavid du Colombier * action log 8159ef1f84bSDavid du Colombier */ 8169ef1f84bSDavid du Colombier struct Log { 8179ef1f84bSDavid du Colombier Lock; 8189ef1f84bSDavid du Colombier int opens; 8199ef1f84bSDavid du Colombier char* buf; 8209ef1f84bSDavid du Colombier char *end; 8219ef1f84bSDavid du Colombier char *rptr; 8229ef1f84bSDavid du Colombier int len; 8239ef1f84bSDavid du Colombier int nlog; 8249ef1f84bSDavid du Colombier int minread; 8259ef1f84bSDavid du Colombier 8269ef1f84bSDavid du Colombier int logmask; /* mask of things to debug */ 8279ef1f84bSDavid du Colombier 8289ef1f84bSDavid du Colombier QLock readq; 8299ef1f84bSDavid du Colombier Rendez readr; 8309ef1f84bSDavid du Colombier }; 8319ef1f84bSDavid du Colombier 8329ef1f84bSDavid du Colombier struct Logflag { 8339ef1f84bSDavid du Colombier char* name; 8349ef1f84bSDavid du Colombier int mask; 8359ef1f84bSDavid du Colombier }; 8369ef1f84bSDavid du Colombier 8379ef1f84bSDavid du Colombier enum 8389ef1f84bSDavid du Colombier { 8399ef1f84bSDavid du Colombier NCMDFIELD = 128 8409ef1f84bSDavid du Colombier }; 8419ef1f84bSDavid du Colombier 8429ef1f84bSDavid du Colombier struct Cmdbuf 8439ef1f84bSDavid du Colombier { 8449ef1f84bSDavid du Colombier char *buf; 8459ef1f84bSDavid du Colombier char **f; 8469ef1f84bSDavid du Colombier int nf; 8479ef1f84bSDavid du Colombier }; 8489ef1f84bSDavid du Colombier 8499ef1f84bSDavid du Colombier struct Cmdtab 8509ef1f84bSDavid du Colombier { 8519ef1f84bSDavid du Colombier int index; /* used by client to switch on result */ 8529ef1f84bSDavid du Colombier char *cmd; /* command name */ 8539ef1f84bSDavid du Colombier int narg; /* expected #args; 0 ==> variadic */ 8549ef1f84bSDavid du Colombier }; 8559ef1f84bSDavid du Colombier 8569ef1f84bSDavid du Colombier /* 8579ef1f84bSDavid du Colombier * routines to access UART hardware 8589ef1f84bSDavid du Colombier */ 8599ef1f84bSDavid du Colombier struct PhysUart 8609ef1f84bSDavid du Colombier { 8619ef1f84bSDavid du Colombier char* name; 8629ef1f84bSDavid du Colombier Uart* (*pnp)(void); 8639ef1f84bSDavid du Colombier void (*enable)(Uart*, int); 8649ef1f84bSDavid du Colombier void (*disable)(Uart*); 8659ef1f84bSDavid du Colombier void (*kick)(Uart*); 8669ef1f84bSDavid du Colombier void (*dobreak)(Uart*, int); 8679ef1f84bSDavid du Colombier int (*baud)(Uart*, int); 8689ef1f84bSDavid du Colombier int (*bits)(Uart*, int); 8699ef1f84bSDavid du Colombier int (*stop)(Uart*, int); 8709ef1f84bSDavid du Colombier int (*parity)(Uart*, int); 8719ef1f84bSDavid du Colombier void (*modemctl)(Uart*, int); 8729ef1f84bSDavid du Colombier void (*rts)(Uart*, int); 8739ef1f84bSDavid du Colombier void (*dtr)(Uart*, int); 8749ef1f84bSDavid du Colombier long (*status)(Uart*, void*, long, long); 8759ef1f84bSDavid du Colombier void (*fifo)(Uart*, int); 8769ef1f84bSDavid du Colombier void (*power)(Uart*, int); 8779ef1f84bSDavid du Colombier int (*getc)(Uart*); /* polling version for rdb */ 8789ef1f84bSDavid du Colombier void (*putc)(Uart*, int); /* polling version for iprint */ 8799ef1f84bSDavid du Colombier void (*poll)(Uart*); /* polled interrupt routine */ 8809ef1f84bSDavid du Colombier }; 8819ef1f84bSDavid du Colombier 8829ef1f84bSDavid du Colombier enum { 8839ef1f84bSDavid du Colombier Stagesize= 2048 8849ef1f84bSDavid du Colombier }; 8859ef1f84bSDavid du Colombier 8869ef1f84bSDavid du Colombier /* 8879ef1f84bSDavid du Colombier * software UART 8889ef1f84bSDavid du Colombier */ 8899ef1f84bSDavid du Colombier struct Uart 8909ef1f84bSDavid du Colombier { 8919ef1f84bSDavid du Colombier void* regs; /* hardware stuff */ 8929ef1f84bSDavid du Colombier void* saveregs; /* place to put registers on power down */ 8939ef1f84bSDavid du Colombier char* name; /* internal name */ 8949ef1f84bSDavid du Colombier ulong freq; /* clock frequency */ 8959ef1f84bSDavid du Colombier int bits; /* bits per character */ 8969ef1f84bSDavid du Colombier int stop; /* stop bits */ 8979ef1f84bSDavid du Colombier int parity; /* even, odd or no parity */ 8989ef1f84bSDavid du Colombier int baud; /* baud rate */ 8999ef1f84bSDavid du Colombier PhysUart*phys; 9009ef1f84bSDavid du Colombier int console; /* used as a serial console */ 9019ef1f84bSDavid du Colombier int special; /* internal kernel device */ 9029ef1f84bSDavid du Colombier Uart* next; /* list of allocated uarts */ 9039ef1f84bSDavid du Colombier 9049ef1f84bSDavid du Colombier QLock; 9059ef1f84bSDavid du Colombier int type; /* ?? */ 9069ef1f84bSDavid du Colombier int dev; 9079ef1f84bSDavid du Colombier int opens; 9089ef1f84bSDavid du Colombier 9099ef1f84bSDavid du Colombier int enabled; 9109ef1f84bSDavid du Colombier Uart *elist; /* next enabled interface */ 9119ef1f84bSDavid du Colombier 9129ef1f84bSDavid du Colombier int perr; /* parity errors */ 9139ef1f84bSDavid du Colombier int ferr; /* framing errors */ 9149ef1f84bSDavid du Colombier int oerr; /* rcvr overruns */ 9159ef1f84bSDavid du Colombier int berr; /* no input buffers */ 9169ef1f84bSDavid du Colombier int serr; /* input queue overflow */ 9179ef1f84bSDavid du Colombier 9189ef1f84bSDavid du Colombier /* buffers */ 9199ef1f84bSDavid du Colombier int (*putc)(Queue*, int); 9209ef1f84bSDavid du Colombier Queue *iq; 9219ef1f84bSDavid du Colombier Queue *oq; 9229ef1f84bSDavid du Colombier 9239ef1f84bSDavid du Colombier Lock rlock; 9249ef1f84bSDavid du Colombier uchar istage[Stagesize]; 9259ef1f84bSDavid du Colombier uchar *iw; 9269ef1f84bSDavid du Colombier uchar *ir; 9279ef1f84bSDavid du Colombier uchar *ie; 9289ef1f84bSDavid du Colombier 9299ef1f84bSDavid du Colombier Lock tlock; /* transmit */ 9309ef1f84bSDavid du Colombier uchar ostage[Stagesize]; 9319ef1f84bSDavid du Colombier uchar *op; 9329ef1f84bSDavid du Colombier uchar *oe; 9339ef1f84bSDavid du Colombier int drain; 9349ef1f84bSDavid du Colombier 9359ef1f84bSDavid du Colombier int modem; /* hardware flow control on */ 9369ef1f84bSDavid du Colombier int xonoff; /* software flow control on */ 9379ef1f84bSDavid du Colombier int blocked; 9389ef1f84bSDavid du Colombier int cts, dsr, dcd; /* keep track of modem status */ 9399ef1f84bSDavid du Colombier int ctsbackoff; 9409ef1f84bSDavid du Colombier int hup_dsr, hup_dcd; /* send hangup upstream? */ 9419ef1f84bSDavid du Colombier int dohup; 9429ef1f84bSDavid du Colombier 9439ef1f84bSDavid du Colombier Rendez r; 9449ef1f84bSDavid du Colombier }; 9459ef1f84bSDavid du Colombier 9469ef1f84bSDavid du Colombier extern Uart* consuart; 9479ef1f84bSDavid du Colombier 948406c76faSDavid du Colombier void (*lprint)(char *, int); 949406c76faSDavid du Colombier 9509ef1f84bSDavid du Colombier /* 9519ef1f84bSDavid du Colombier * performance timers, all units in perfticks 9529ef1f84bSDavid du Colombier */ 9539ef1f84bSDavid du Colombier struct Perf 9549ef1f84bSDavid du Colombier { 9559ef1f84bSDavid du Colombier ulong intrts; /* time of last interrupt */ 9569ef1f84bSDavid du Colombier ulong inintr; /* time since last clock tick in interrupt handlers */ 9579ef1f84bSDavid du Colombier ulong avg_inintr; /* avg time per clock tick in interrupt handlers */ 9589ef1f84bSDavid du Colombier ulong inidle; /* time since last clock tick in idle loop */ 9599ef1f84bSDavid du Colombier ulong avg_inidle; /* avg time per clock tick in idle loop */ 9609ef1f84bSDavid du Colombier ulong last; /* value of perfticks() at last clock tick */ 9619ef1f84bSDavid du Colombier ulong period; /* perfticks() per clock tick */ 9629ef1f84bSDavid du Colombier }; 9639ef1f84bSDavid du Colombier 9649ef1f84bSDavid du Colombier struct Watchdog 9659ef1f84bSDavid du Colombier { 9669ef1f84bSDavid du Colombier void (*enable)(void); /* watchdog enable */ 9679ef1f84bSDavid du Colombier void (*disable)(void); /* watchdog disable */ 9689ef1f84bSDavid du Colombier void (*restart)(void); /* watchdog restart */ 9699ef1f84bSDavid du Colombier void (*stat)(char*, char*); /* watchdog statistics */ 9709ef1f84bSDavid du Colombier }; 9719ef1f84bSDavid du Colombier 972277b6efdSDavid du Colombier struct Watermark 973277b6efdSDavid du Colombier { 974277b6efdSDavid du Colombier int highwater; 975277b6efdSDavid du Colombier int curr; 976277b6efdSDavid du Colombier int max; 977277b6efdSDavid du Colombier int hitmax; /* count: how many times hit max? */ 978277b6efdSDavid du Colombier char *name; 979277b6efdSDavid du Colombier }; 980277b6efdSDavid du Colombier 981277b6efdSDavid du Colombier 9829ef1f84bSDavid du Colombier /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ 9839ef1f84bSDavid du Colombier enum 9849ef1f84bSDavid du Colombier { 9859ef1f84bSDavid du Colombier /* Queue.state */ 9869ef1f84bSDavid du Colombier Qstarve = (1<<0), /* consumer starved */ 9879ef1f84bSDavid du Colombier Qmsg = (1<<1), /* message stream */ 9889ef1f84bSDavid du Colombier Qclosed = (1<<2), /* queue has been closed/hungup */ 9899ef1f84bSDavid du Colombier Qflow = (1<<3), /* producer flow controlled */ 9909ef1f84bSDavid du Colombier Qcoalesce = (1<<4), /* coalesce packets on read */ 9919ef1f84bSDavid du Colombier Qkick = (1<<5), /* always call the kick routine after qwrite */ 9929ef1f84bSDavid du Colombier }; 9939ef1f84bSDavid du Colombier 9949ef1f84bSDavid du Colombier #define DEVDOTDOT -1 9959ef1f84bSDavid du Colombier 9969ef1f84bSDavid du Colombier #pragma varargck type "I" uchar* 9979ef1f84bSDavid du Colombier #pragma varargck type "V" uchar* 9989ef1f84bSDavid du Colombier #pragma varargck type "E" uchar* 9999ef1f84bSDavid du Colombier #pragma varargck type "M" uchar* 10009ef1f84bSDavid du Colombier 10019ef1f84bSDavid du Colombier #pragma varargck type "m" Mreg 10026dbdd466SDavid du Colombier #pragma varargck type "P" uintmem 1003