13e12c5d1SDavid du Colombier typedef struct Alarms Alarms; 23e12c5d1SDavid du Colombier typedef struct Block Block; 33e12c5d1SDavid du Colombier typedef struct Chan Chan; 47dd7cddfSDavid du Colombier typedef struct Cmdbuf Cmdbuf; 59a747e4fSDavid du Colombier typedef struct Cmdtab Cmdtab; 64de34a7eSDavid du Colombier typedef struct Confmem Confmem; 73e12c5d1SDavid du Colombier typedef struct Dev Dev; 83e12c5d1SDavid du Colombier typedef struct Dirtab Dirtab; 9e288d156SDavid du Colombier typedef struct Edf Edf; 103e12c5d1SDavid du Colombier typedef struct Egrp Egrp; 113e12c5d1SDavid du Colombier typedef struct Evalue Evalue; 1215bfe97dSDavid du Colombier typedef struct Execvals Execvals; 133e12c5d1SDavid du Colombier typedef struct Fgrp Fgrp; 1480ee5cbfSDavid du Colombier typedef struct DevConf DevConf; 153e12c5d1SDavid du Colombier typedef struct Image Image; 167dd7cddfSDavid du Colombier typedef struct Log Log; 177dd7cddfSDavid du Colombier typedef struct Logflag Logflag; 187dd7cddfSDavid du Colombier typedef struct Mntcache Mntcache; 193e12c5d1SDavid du Colombier typedef struct Mount Mount; 207dd7cddfSDavid du Colombier typedef struct Mntrpc Mntrpc; 217dd7cddfSDavid du Colombier typedef struct Mntwalk Mntwalk; 223e12c5d1SDavid du Colombier typedef struct Mnt Mnt; 233e12c5d1SDavid du Colombier typedef struct Mhead Mhead; 243e12c5d1SDavid du Colombier typedef struct Note Note; 253e12c5d1SDavid du Colombier typedef struct Page Page; 264afe124fSDavid du Colombier typedef struct Path Path; 273e12c5d1SDavid du Colombier typedef struct Palloc Palloc; 284de34a7eSDavid du Colombier typedef struct Pallocmem Pallocmem; 293ff48bf5SDavid du Colombier typedef struct Perf Perf; 309a747e4fSDavid du Colombier typedef struct PhysUart PhysUart; 313e12c5d1SDavid du Colombier typedef struct Pgrp Pgrp; 32219b2ee8SDavid du Colombier typedef struct Physseg Physseg; 333e12c5d1SDavid du Colombier typedef struct Proc Proc; 343e12c5d1SDavid du Colombier typedef struct Pte Pte; 353e12c5d1SDavid du Colombier typedef struct QLock QLock; 363e12c5d1SDavid du Colombier typedef struct Queue Queue; 373e12c5d1SDavid du Colombier typedef struct Ref Ref; 383e12c5d1SDavid du Colombier typedef struct Rendez Rendez; 397dd7cddfSDavid du Colombier typedef struct Rgrp Rgrp; 403e12c5d1SDavid du Colombier typedef struct RWlock RWlock; 413e12c5d1SDavid du Colombier typedef struct Sargs Sargs; 429a747e4fSDavid du Colombier typedef struct Schedq Schedq; 433e12c5d1SDavid du Colombier typedef struct Segment Segment; 443c2ddefeSDavid du Colombier typedef struct Sema Sema; 459a747e4fSDavid du Colombier typedef struct Timer Timer; 4612fd1c83SDavid du Colombier typedef struct Timers Timers; 479a747e4fSDavid du Colombier typedef struct Uart Uart; 483e12c5d1SDavid du Colombier typedef struct Waitq Waitq; 499a747e4fSDavid du Colombier typedef struct Walkqid Walkqid; 50079fe160SDavid du Colombier typedef struct Watchdog Watchdog; 51217e9e83SDavid du Colombier typedef struct Watermark Watermark; 529a747e4fSDavid du Colombier typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*); 537dd7cddfSDavid du Colombier 5412fd1c83SDavid du Colombier #pragma incomplete DevConf 5512fd1c83SDavid du Colombier #pragma incomplete Edf 5612fd1c83SDavid du Colombier #pragma incomplete Mntcache 5712fd1c83SDavid du Colombier #pragma incomplete Mntrpc 5812fd1c83SDavid du Colombier #pragma incomplete Queue 5912fd1c83SDavid du Colombier #pragma incomplete Timers 603e12c5d1SDavid du Colombier 61219b2ee8SDavid du Colombier #include <fcall.h> 623e12c5d1SDavid du Colombier 6312009bffSDavid du Colombier #define HOWMANY(x, y) (((x)+((y)-1))/(y)) 6412009bffSDavid du Colombier #define ROUNDUP(x, y) (HOWMANY((x), (y))*(y)) /* ceiling */ 6512009bffSDavid du Colombier #define ROUNDDN(x, y) (((x)/(y))*(y)) /* floor */ 6612009bffSDavid du Colombier #define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) 6712009bffSDavid du Colombier #define PGROUND(s) ROUNDUP(s, BY2PG) 6812009bffSDavid du Colombier #define MIN(a, b) ((a) < (b)? (a): (b)) 6912009bffSDavid du Colombier #define MAX(a, b) ((a) > (b)? (a): (b)) 7012009bffSDavid du Colombier 7112009bffSDavid du Colombier /* 7212009bffSDavid du Colombier * For multi-bit fields use FIELD(v, o, w) where 'v' is the value 7312009bffSDavid du Colombier * of the bit-field of width 'w' with LSb at bit offset 'o'. 7412009bffSDavid du Colombier */ 7512009bffSDavid du Colombier #define FIELD(v, o, w) (((v) & ((1<<(w))-1))<<(o)) 7612009bffSDavid du Colombier 7712009bffSDavid du Colombier #define FCLR(d, o, w) ((d) & ~(((1<<(w))-1)<<(o))) 7812009bffSDavid du Colombier #define FEXT(d, o, w) (((d)>>(o)) & ((1<<(w))-1)) 7912009bffSDavid du Colombier #define FINS(d, o, w, v) (FCLR((d), (o), (w))|FIELD((v), (o), (w))) 8012009bffSDavid du Colombier #define FSET(d, o, w) ((d)|(((1<<(w))-1)<<(o))) 8112009bffSDavid du Colombier 8212009bffSDavid du Colombier #define FMASK(o, w) (((1<<(w))-1)<<(o)) 8312009bffSDavid du Colombier 8412009bffSDavid du Colombier /* let each port override any of these */ 85cc162d66SDavid du Colombier #ifndef KMESGSIZE 86cc162d66SDavid du Colombier #define KMESGSIZE (16*1024) 87cc162d66SDavid du Colombier #endif 88cc162d66SDavid du Colombier #ifndef PCICONSSIZE 89cc162d66SDavid du Colombier #define PCICONSSIZE (16*1024) 90cc162d66SDavid du Colombier #endif 91cc162d66SDavid du Colombier #ifndef STAGESIZE 92cc162d66SDavid du Colombier #define STAGESIZE 64 93cc162d66SDavid du Colombier #endif 94b65f1be6SDavid du Colombier #ifndef MAXBY2PG 95b65f1be6SDavid du Colombier #define MAXBY2PG BY2PG /* rounding for UTZERO in executables */ 96b65f1be6SDavid du Colombier #endif 97cc162d66SDavid du Colombier 983e12c5d1SDavid du Colombier struct Ref 993e12c5d1SDavid du Colombier { 100fe853e23SDavid du Colombier Lock; 1013e12c5d1SDavid du Colombier long ref; 1023e12c5d1SDavid du Colombier }; 1033e12c5d1SDavid du Colombier 1043e12c5d1SDavid du Colombier struct Rendez 1053e12c5d1SDavid du Colombier { 10659cc4ca5SDavid du Colombier Lock; 1073e12c5d1SDavid du Colombier Proc *p; 1083e12c5d1SDavid du Colombier }; 1093e12c5d1SDavid du Colombier 1103e12c5d1SDavid du Colombier struct QLock 1113e12c5d1SDavid du Colombier { 1123e12c5d1SDavid du Colombier Lock use; /* to access Qlock structure */ 1133e12c5d1SDavid du Colombier Proc *head; /* next process waiting for object */ 1143e12c5d1SDavid du Colombier Proc *tail; /* last process waiting for object */ 1153e12c5d1SDavid du Colombier int locked; /* flag */ 1166bbfed0dSDavid du Colombier uintptr qpc; /* pc of the holder */ 1173e12c5d1SDavid du Colombier }; 1183e12c5d1SDavid du Colombier 1193e12c5d1SDavid du Colombier struct RWlock 1203e12c5d1SDavid du Colombier { 1217dd7cddfSDavid du Colombier Lock use; 1227dd7cddfSDavid du Colombier Proc *head; /* list of waiting processes */ 1237dd7cddfSDavid du Colombier Proc *tail; 1247dd7cddfSDavid du Colombier ulong wpc; /* pc of writer */ 1257dd7cddfSDavid du Colombier Proc *wproc; /* writing proc */ 1267dd7cddfSDavid du Colombier int readers; /* number of readers */ 1277dd7cddfSDavid du Colombier int writer; /* number of writers */ 1283e12c5d1SDavid du Colombier }; 1293e12c5d1SDavid du Colombier 1303e12c5d1SDavid du Colombier struct Alarms 1313e12c5d1SDavid du Colombier { 1323e12c5d1SDavid du Colombier QLock; 1333e12c5d1SDavid du Colombier Proc *head; 1343e12c5d1SDavid du Colombier }; 1353e12c5d1SDavid du Colombier 1363e12c5d1SDavid du Colombier struct Sargs 1373e12c5d1SDavid du Colombier { 1383e12c5d1SDavid du Colombier ulong args[MAXSYSARG]; 1393e12c5d1SDavid du Colombier }; 1403e12c5d1SDavid du Colombier 1413e12c5d1SDavid du Colombier /* 1427dd7cddfSDavid du Colombier * Access types in namec & channel flags 1433e12c5d1SDavid du Colombier */ 1443e12c5d1SDavid du Colombier enum 1453e12c5d1SDavid du Colombier { 1469a747e4fSDavid du Colombier Aaccess, /* as in stat, wstat */ 1479a747e4fSDavid du Colombier Abind, /* for left-hand-side of bind */ 1483e12c5d1SDavid du Colombier Atodir, /* as in chdir */ 1493e12c5d1SDavid du Colombier Aopen, /* for i/o */ 1509a747e4fSDavid du Colombier Amount, /* to be mounted or mounted upon */ 1519a747e4fSDavid du Colombier Acreate, /* is to be created */ 1529a747e4fSDavid du Colombier Aremove, /* will be removed by caller */ 1537dd7cddfSDavid du Colombier 1547dd7cddfSDavid du Colombier COPEN = 0x0001, /* for i/o */ 1557dd7cddfSDavid du Colombier CMSG = 0x0002, /* the message channel for a mount */ 1569a747e4fSDavid du Colombier /*rsc CCREATE = 0x0004, /* permits creation if c->mnt */ 1577dd7cddfSDavid du Colombier CCEXEC = 0x0008, /* close on exec */ 1587dd7cddfSDavid du Colombier CFREE = 0x0010, /* not in use */ 1597dd7cddfSDavid du Colombier CRCLOSE = 0x0020, /* remove on close */ 1607dd7cddfSDavid du Colombier CCACHE = 0x0080, /* client cache */ 1613e12c5d1SDavid du Colombier }; 1623e12c5d1SDavid du Colombier 1636b6b9ac8SDavid du Colombier /* flag values */ 1647dd7cddfSDavid du Colombier enum 1657dd7cddfSDavid du Colombier { 1667dd7cddfSDavid du Colombier BINTR = (1<<0), 1677dd7cddfSDavid du Colombier BFREE = (1<<1), 1686b6b9ac8SDavid du Colombier Bipck = (1<<2), /* ip checksum */ 1696b6b9ac8SDavid du Colombier Budpck = (1<<3), /* udp checksum */ 1706b6b9ac8SDavid du Colombier Btcpck = (1<<4), /* tcp checksum */ 1716b6b9ac8SDavid du Colombier Bpktck = (1<<5), /* packet checksum */ 1727dd7cddfSDavid du Colombier }; 1737dd7cddfSDavid du Colombier 1747dd7cddfSDavid du Colombier struct Block 1757dd7cddfSDavid du Colombier { 17614cc0f53SDavid du Colombier long ref; 1777dd7cddfSDavid du Colombier Block* next; 1787dd7cddfSDavid du Colombier Block* list; 1797dd7cddfSDavid du Colombier uchar* rp; /* first unconsumed byte */ 1807dd7cddfSDavid du Colombier uchar* wp; /* first empty byte */ 1817dd7cddfSDavid du Colombier uchar* lim; /* 1 past the end of the buffer */ 1827dd7cddfSDavid du Colombier uchar* base; /* start of the buffer */ 1837dd7cddfSDavid du Colombier void (*free)(Block*); 1846b6b9ac8SDavid du Colombier ushort flag; 1856b6b9ac8SDavid du Colombier ushort checksum; /* IP checksum of complete packet (minus media header) */ 1866083aa43SDavid du Colombier ulong magic; 1877dd7cddfSDavid du Colombier }; 188ea58ad6fSDavid du Colombier 1897dd7cddfSDavid du Colombier #define BLEN(s) ((s)->wp - (s)->rp) 1907dd7cddfSDavid du Colombier #define BALLOC(s) ((s)->lim - (s)->base) 1913e12c5d1SDavid du Colombier 1923e12c5d1SDavid du Colombier struct Chan 1933e12c5d1SDavid du Colombier { 194fe853e23SDavid du Colombier Ref; /* the Lock in this Ref is also Chan's lock */ 1953e12c5d1SDavid du Colombier Chan* next; /* allocation */ 1967dd7cddfSDavid du Colombier Chan* link; 197dc5a79c1SDavid du Colombier vlong offset; /* in fd */ 198dc5a79c1SDavid du Colombier vlong devoffset; /* in underlying device; see read */ 1993e12c5d1SDavid du Colombier ushort type; 200219b2ee8SDavid du Colombier ulong dev; 2013e12c5d1SDavid du Colombier ushort mode; /* read/write */ 2023e12c5d1SDavid du Colombier ushort flag; 2033e12c5d1SDavid du Colombier Qid qid; 2043e12c5d1SDavid du Colombier int fid; /* for devmnt */ 2059a747e4fSDavid du Colombier ulong iounit; /* chunk size for i/o; 0==default */ 2069a747e4fSDavid du Colombier Mhead* umh; /* mount point that derived Chan; used in unionread */ 2079a747e4fSDavid du Colombier Chan* umc; /* channel in union; held for union read */ 2089a747e4fSDavid du Colombier QLock umqlock; /* serialize unionreads */ 2097dd7cddfSDavid du Colombier int uri; /* union read index */ 2109a747e4fSDavid du Colombier int dri; /* devdirread index */ 211dc5a79c1SDavid du Colombier uchar* dirrock; /* directory entry rock for translations */ 212dc5a79c1SDavid du Colombier int nrock; 213dc5a79c1SDavid du Colombier int mrock; 214dc5a79c1SDavid du Colombier QLock rockqlock; 215dc5a79c1SDavid du Colombier int ismtpt; 2167dd7cddfSDavid du Colombier Mntcache*mcp; /* Mount cache pointer */ 2179a747e4fSDavid du Colombier Mnt* mux; /* Mnt for clients using me for messages */ 2183e12c5d1SDavid du Colombier union { 2193e12c5d1SDavid du Colombier void* aux; 2203e12c5d1SDavid du Colombier Qid pgrpid; /* for #p/notepg */ 2217dd7cddfSDavid du Colombier ulong mid; /* for ns in devproc */ 2223e12c5d1SDavid du Colombier }; 2233e12c5d1SDavid du Colombier Chan* mchan; /* channel to mounted server */ 2243e12c5d1SDavid du Colombier Qid mqid; /* qid of root of mount point */ 2254afe124fSDavid du Colombier Path* path; 2267dd7cddfSDavid du Colombier }; 2277dd7cddfSDavid du Colombier 2284afe124fSDavid du Colombier struct Path 2297dd7cddfSDavid du Colombier { 2307dd7cddfSDavid du Colombier Ref; 2317dd7cddfSDavid du Colombier char *s; 2324afe124fSDavid du Colombier Chan **mtpt; /* mtpt history */ 2334afe124fSDavid du Colombier int len; /* strlen(s) */ 2344afe124fSDavid du Colombier int alen; /* allocated length of s */ 2354afe124fSDavid du Colombier int mlen; /* number of path elements */ 2364afe124fSDavid du Colombier int malen; /* allocated length of mtpt */ 2373e12c5d1SDavid du Colombier }; 2383e12c5d1SDavid du Colombier 2393e12c5d1SDavid du Colombier struct Dev 2403e12c5d1SDavid du Colombier { 2417dd7cddfSDavid du Colombier int dc; 2427dd7cddfSDavid du Colombier char* name; 2437dd7cddfSDavid du Colombier 2443e12c5d1SDavid du Colombier void (*reset)(void); 2453e12c5d1SDavid du Colombier void (*init)(void); 2469a747e4fSDavid du Colombier void (*shutdown)(void); 2473e12c5d1SDavid du Colombier Chan* (*attach)(char*); 2489a747e4fSDavid du Colombier Walkqid*(*walk)(Chan*, Chan*, char**, int); 2499a747e4fSDavid du Colombier int (*stat)(Chan*, uchar*, int); 2503e12c5d1SDavid du Colombier Chan* (*open)(Chan*, int); 2513e12c5d1SDavid du Colombier void (*create)(Chan*, char*, int, ulong); 2523e12c5d1SDavid du Colombier void (*close)(Chan*); 2537dd7cddfSDavid du Colombier long (*read)(Chan*, void*, long, vlong); 2547dd7cddfSDavid du Colombier Block* (*bread)(Chan*, long, ulong); 2557dd7cddfSDavid du Colombier long (*write)(Chan*, void*, long, vlong); 2567dd7cddfSDavid du Colombier long (*bwrite)(Chan*, Block*, ulong); 2573e12c5d1SDavid du Colombier void (*remove)(Chan*); 2589a747e4fSDavid du Colombier int (*wstat)(Chan*, uchar*, int); 2599a747e4fSDavid du Colombier void (*power)(int); /* power mgt: power(1) => on, power (0) => off */ 260ea58ad6fSDavid du Colombier int (*config)(int, char*, DevConf*); /* returns nil on error */ 26191e577b2SDavid du Colombier 26291e577b2SDavid du Colombier /* not initialised */ 26391e577b2SDavid du Colombier int attached; /* debugging */ 2643e12c5d1SDavid du Colombier }; 2653e12c5d1SDavid du Colombier 2663e12c5d1SDavid du Colombier struct Dirtab 2673e12c5d1SDavid du Colombier { 2689a747e4fSDavid du Colombier char name[KNAMELEN]; 2693e12c5d1SDavid du Colombier Qid qid; 27080ee5cbfSDavid du Colombier vlong length; 2713e12c5d1SDavid du Colombier long perm; 2723e12c5d1SDavid du Colombier }; 2733e12c5d1SDavid du Colombier 2749a747e4fSDavid du Colombier struct Walkqid 2759a747e4fSDavid du Colombier { 2769a747e4fSDavid du Colombier Chan *clone; 2779a747e4fSDavid du Colombier int nqid; 2789a747e4fSDavid du Colombier Qid qid[1]; 2799a747e4fSDavid du Colombier }; 2809a747e4fSDavid du Colombier 2813e12c5d1SDavid du Colombier enum 2823e12c5d1SDavid du Colombier { 2837dd7cddfSDavid du Colombier NSMAX = 1000, 2847dd7cddfSDavid du Colombier NSLOG = 7, 2857dd7cddfSDavid du Colombier NSCACHE = (1<<NSLOG), 2863e12c5d1SDavid du Colombier }; 2873e12c5d1SDavid du Colombier 2887dd7cddfSDavid du Colombier struct Mntwalk /* state for /proc/#/ns */ 2893e12c5d1SDavid du Colombier { 2907dd7cddfSDavid du Colombier int cddone; 2917dd7cddfSDavid du Colombier Mhead* mh; 2927dd7cddfSDavid du Colombier Mount* cm; 2933e12c5d1SDavid du Colombier }; 2943e12c5d1SDavid du Colombier 2953e12c5d1SDavid du Colombier struct Mount 2963e12c5d1SDavid du Colombier { 2973e12c5d1SDavid du Colombier ulong mountid; 2983e12c5d1SDavid du Colombier Mount* next; 2993e12c5d1SDavid du Colombier Mhead* head; 3007dd7cddfSDavid du Colombier Mount* copy; 3017dd7cddfSDavid du Colombier Mount* order; 3027dd7cddfSDavid du Colombier Chan* to; /* channel replacing channel */ 3039a747e4fSDavid du Colombier int mflag; 3049a747e4fSDavid du Colombier char *spec; 3053e12c5d1SDavid du Colombier }; 3063e12c5d1SDavid du Colombier 3073e12c5d1SDavid du Colombier struct Mhead 3083e12c5d1SDavid du Colombier { 3097dd7cddfSDavid du Colombier Ref; 3107dd7cddfSDavid du Colombier RWlock lock; 3113e12c5d1SDavid du Colombier Chan* from; /* channel mounted upon */ 3123e12c5d1SDavid du Colombier Mount* mount; /* what's mounted upon it */ 3133e12c5d1SDavid du Colombier Mhead* hash; /* Hash chain */ 3143e12c5d1SDavid du Colombier }; 3153e12c5d1SDavid du Colombier 3167dd7cddfSDavid du Colombier struct Mnt 3177dd7cddfSDavid du Colombier { 3189a747e4fSDavid du Colombier Lock; 3199a747e4fSDavid du Colombier /* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */ 3207dd7cddfSDavid du Colombier Chan *c; /* Channel to file service */ 3217dd7cddfSDavid du Colombier Proc *rip; /* Reader in progress */ 3227dd7cddfSDavid du Colombier Mntrpc *queue; /* Queue of pending requests on this channel */ 3237dd7cddfSDavid du Colombier ulong id; /* Multiplexer id for channel check */ 3247dd7cddfSDavid du Colombier Mnt *list; /* Free list */ 3257dd7cddfSDavid du Colombier int flags; /* cache */ 3269a747e4fSDavid du Colombier int msize; /* data + IOHDRSZ */ 3279a747e4fSDavid du Colombier char *version; /* 9P version */ 3289a747e4fSDavid du Colombier Queue *q; /* input queue */ 3297dd7cddfSDavid du Colombier }; 3307dd7cddfSDavid du Colombier 3313e12c5d1SDavid du Colombier enum 3323e12c5d1SDavid du Colombier { 3333e12c5d1SDavid du Colombier NUser, /* note provided externally */ 3343e12c5d1SDavid du Colombier NExit, /* deliver note quietly */ 3353e12c5d1SDavid du Colombier NDebug, /* print debug message */ 3363e12c5d1SDavid du Colombier }; 3373e12c5d1SDavid du Colombier 3383e12c5d1SDavid du Colombier struct Note 3393e12c5d1SDavid du Colombier { 3409a747e4fSDavid du Colombier char msg[ERRMAX]; 3413e12c5d1SDavid du Colombier int flag; /* whether system posted it */ 3423e12c5d1SDavid du Colombier }; 3433e12c5d1SDavid du Colombier 3443e12c5d1SDavid du Colombier enum 3453e12c5d1SDavid du Colombier { 3467dd7cddfSDavid du Colombier PG_NOFLUSH = 0, 3477dd7cddfSDavid du Colombier PG_TXTFLUSH = 1, /* flush dcache and invalidate icache */ 3487dd7cddfSDavid du Colombier PG_DATFLUSH = 2, /* flush both i & d caches (UNUSED) */ 3497dd7cddfSDavid du Colombier PG_NEWCOL = 3, /* page has been recolored */ 3507dd7cddfSDavid du Colombier 3517dd7cddfSDavid du Colombier PG_MOD = 0x01, /* software modified bit */ 3527dd7cddfSDavid du Colombier PG_REF = 0x02, /* software referenced bit */ 3533e12c5d1SDavid du Colombier }; 3543e12c5d1SDavid du Colombier 3553e12c5d1SDavid du Colombier struct Page 3563e12c5d1SDavid du Colombier { 3573e12c5d1SDavid du Colombier Lock; 3583e12c5d1SDavid du Colombier ulong pa; /* Physical address in memory */ 3593e12c5d1SDavid du Colombier ulong va; /* Virtual address for user */ 3603e12c5d1SDavid du Colombier ulong daddr; /* Disc address on swap */ 361d1be6b08SDavid du Colombier ulong gen; /* Generation counter for swap */ 3623e12c5d1SDavid du Colombier ushort ref; /* Reference count */ 3633e12c5d1SDavid du Colombier char modref; /* Simulated modify/reference bits */ 3647dd7cddfSDavid du Colombier char color; /* Cache coloring */ 3653e12c5d1SDavid du Colombier char cachectl[MAXMACH]; /* Cache flushing control for putmmu */ 3663e12c5d1SDavid du Colombier Image *image; /* Associated text or swap image */ 3673e12c5d1SDavid du Colombier Page *next; /* Lru free list */ 3683e12c5d1SDavid du Colombier Page *prev; 3693e12c5d1SDavid du Colombier Page *hash; /* Image hash chains */ 3703e12c5d1SDavid du Colombier }; 3713e12c5d1SDavid du Colombier 3723e12c5d1SDavid du Colombier struct Swapalloc 3733e12c5d1SDavid du Colombier { 3743e12c5d1SDavid du Colombier Lock; /* Free map lock */ 3757dd7cddfSDavid du Colombier int free; /* currently free swap pages */ 3763e12c5d1SDavid du Colombier uchar* swmap; /* Base of swap map in memory */ 3773e12c5d1SDavid du Colombier uchar* alloc; /* Round robin allocator */ 3783e12c5d1SDavid du Colombier uchar* last; /* Speed swap allocation */ 3793e12c5d1SDavid du Colombier uchar* top; /* Top of swap map */ 3803e12c5d1SDavid du Colombier Rendez r; /* Pager kproc idle sleep */ 3817dd7cddfSDavid du Colombier ulong highwater; /* Pager start threshold */ 3827dd7cddfSDavid du Colombier ulong headroom; /* Space pager frees under highwater */ 3833e12c5d1SDavid du Colombier }swapalloc; 3843e12c5d1SDavid du Colombier 3853e12c5d1SDavid du Colombier struct Image 3863e12c5d1SDavid du Colombier { 3873e12c5d1SDavid du Colombier Ref; 3887dd7cddfSDavid du Colombier Chan *c; /* channel to text file */ 3897dd7cddfSDavid du Colombier Qid qid; /* Qid for page cache coherence */ 3903e12c5d1SDavid du Colombier Qid mqid; 3913e12c5d1SDavid du Colombier Chan *mchan; 3923e12c5d1SDavid du Colombier ushort type; /* Device type of owning channel */ 3933e12c5d1SDavid du Colombier Segment *s; /* TEXT segment for image if running */ 3943e12c5d1SDavid du Colombier Image *hash; /* Qid hash chains */ 3953e12c5d1SDavid du Colombier Image *next; /* Free list */ 3967dd7cddfSDavid du Colombier int notext; /* no file associated */ 3973e12c5d1SDavid du Colombier }; 3983e12c5d1SDavid du Colombier 3993e12c5d1SDavid du Colombier struct Pte 4003e12c5d1SDavid du Colombier { 4013e12c5d1SDavid du Colombier Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */ 4023e12c5d1SDavid du Colombier Page **first; /* First used entry */ 4033e12c5d1SDavid du Colombier Page **last; /* Last used entry */ 4043e12c5d1SDavid du Colombier }; 4053e12c5d1SDavid du Colombier 4063e12c5d1SDavid du Colombier /* Segment types */ 4073e12c5d1SDavid du Colombier enum 4083e12c5d1SDavid du Colombier { 4093e12c5d1SDavid du Colombier SG_TYPE = 07, /* Mask type of segment */ 4103e12c5d1SDavid du Colombier SG_TEXT = 00, 4113e12c5d1SDavid du Colombier SG_DATA = 01, 4123e12c5d1SDavid du Colombier SG_BSS = 02, 4133e12c5d1SDavid du Colombier SG_STACK = 03, 4143e12c5d1SDavid du Colombier SG_SHARED = 04, 4153e12c5d1SDavid du Colombier SG_PHYSICAL = 05, 4163e12c5d1SDavid du Colombier 4177dd7cddfSDavid du Colombier SG_RONLY = 0040, /* Segment is read only */ 418219b2ee8SDavid du Colombier SG_CEXEC = 0100, /* Detach at exec */ 4193e12c5d1SDavid du Colombier }; 4203e12c5d1SDavid du Colombier 4213e12c5d1SDavid du Colombier #define PG_ONSWAP 1 4223e12c5d1SDavid du Colombier #define onswap(s) (((ulong)s)&PG_ONSWAP) 4233e12c5d1SDavid du Colombier #define pagedout(s) (((ulong)s)==0 || onswap(s)) 4243e12c5d1SDavid du Colombier #define swapaddr(s) (((ulong)s)&~PG_ONSWAP) 4253e12c5d1SDavid du Colombier 4263e12c5d1SDavid du Colombier #define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM) 4273e12c5d1SDavid du Colombier 428219b2ee8SDavid du Colombier struct Physseg 429219b2ee8SDavid du Colombier { 430219b2ee8SDavid du Colombier ulong attr; /* Segment attributes */ 431219b2ee8SDavid du Colombier char *name; /* Attach name */ 432219b2ee8SDavid du Colombier ulong pa; /* Physical address */ 433219b2ee8SDavid du Colombier ulong size; /* Maximum segment size in pages */ 434219b2ee8SDavid du Colombier Page *(*pgalloc)(Segment*, ulong); /* Allocation if we need it */ 435219b2ee8SDavid du Colombier void (*pgfree)(Page*); 436219b2ee8SDavid du Colombier }; 437219b2ee8SDavid du Colombier 4383c2ddefeSDavid du Colombier struct Sema 4393c2ddefeSDavid du Colombier { 4403c2ddefeSDavid du Colombier Rendez; 4413c2ddefeSDavid du Colombier long *addr; 4423c2ddefeSDavid du Colombier int waiting; 4433c2ddefeSDavid du Colombier Sema *next; 4443c2ddefeSDavid du Colombier Sema *prev; 4453c2ddefeSDavid du Colombier }; 4463c2ddefeSDavid du Colombier 4473e12c5d1SDavid du Colombier struct Segment 4483e12c5d1SDavid du Colombier { 4493e12c5d1SDavid du Colombier Ref; 4503e12c5d1SDavid du Colombier QLock lk; 4513e12c5d1SDavid du Colombier ushort steal; /* Page stealer lock */ 4523e12c5d1SDavid du Colombier ushort type; /* segment type */ 4533e12c5d1SDavid du Colombier ulong base; /* virtual base */ 4543e12c5d1SDavid du Colombier ulong top; /* virtual top */ 4553e12c5d1SDavid du Colombier ulong size; /* size in pages */ 4563e12c5d1SDavid du Colombier ulong fstart; /* start address in file for demand load */ 4573e12c5d1SDavid du Colombier ulong flen; /* length of segment in file */ 4587dd7cddfSDavid du Colombier int flushme; /* maintain icache for this segment */ 4593e12c5d1SDavid du Colombier Image *image; /* text in file attached to this segment */ 460219b2ee8SDavid du Colombier Physseg *pseg; 4617dd7cddfSDavid du Colombier ulong* profile; /* Tick profile area */ 4627dd7cddfSDavid du Colombier Pte **map; 4637dd7cddfSDavid du Colombier int mapsize; 4647dd7cddfSDavid du Colombier Pte *ssegmap[SSEGMAPSIZE]; 4653c2ddefeSDavid du Colombier Lock semalock; 4663c2ddefeSDavid du Colombier Sema sema; 467ea15f0ccSDavid du Colombier ulong mark; /* portcountrefs */ 4683e12c5d1SDavid du Colombier }; 4693e12c5d1SDavid du Colombier 4703e12c5d1SDavid du Colombier enum 4713e12c5d1SDavid du Colombier { 4729a747e4fSDavid du Colombier RENDLOG = 5, 4739a747e4fSDavid du Colombier RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */ 4749a747e4fSDavid du Colombier MNTLOG = 5, 4759a747e4fSDavid du Colombier MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */ 4767dd7cddfSDavid du Colombier NFD = 100, /* per process file descriptors */ 477bd389b36SDavid du Colombier PGHLOG = 9, 478bd389b36SDavid du Colombier PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */ 4793e12c5d1SDavid du Colombier }; 4809a747e4fSDavid du Colombier #define REND(p,s) ((p)->rendhash[(s)&((1<<RENDLOG)-1)]) 4819a747e4fSDavid du Colombier #define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)]) 4823e12c5d1SDavid du Colombier 4833e12c5d1SDavid du Colombier struct Pgrp 4843e12c5d1SDavid du Colombier { 4853e12c5d1SDavid du Colombier Ref; /* also used as a lock when mounting */ 4867dd7cddfSDavid du Colombier int noattach; 4873e12c5d1SDavid du Colombier ulong pgrpid; 4883e12c5d1SDavid du Colombier QLock debug; /* single access via devproc.c */ 4897dd7cddfSDavid du Colombier RWlock ns; /* Namespace n read/one write lock */ 4903e12c5d1SDavid du Colombier Mhead *mnthash[MNTHASH]; 4917dd7cddfSDavid du Colombier }; 4927dd7cddfSDavid du Colombier 4937dd7cddfSDavid du Colombier struct Rgrp 4947dd7cddfSDavid du Colombier { 495fe853e23SDavid du Colombier Ref; /* the Ref's lock is also the Rgrp's lock */ 4963e12c5d1SDavid du Colombier Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */ 4973e12c5d1SDavid du Colombier }; 4983e12c5d1SDavid du Colombier 4993e12c5d1SDavid du Colombier struct Egrp 5003e12c5d1SDavid du Colombier { 5013e12c5d1SDavid du Colombier Ref; 5029a747e4fSDavid du Colombier RWlock; 503fb7f0c93SDavid du Colombier Evalue **ent; 504fb7f0c93SDavid du Colombier int nent; 505fb7f0c93SDavid du Colombier int ment; 5067dd7cddfSDavid du Colombier ulong path; /* qid.path of next Evalue to be allocated */ 5077dd7cddfSDavid du Colombier ulong vers; /* of Egrp */ 5083e12c5d1SDavid du Colombier }; 5093e12c5d1SDavid du Colombier 5103e12c5d1SDavid du Colombier struct Evalue 5113e12c5d1SDavid du Colombier { 5123e12c5d1SDavid du Colombier char *name; 5133e12c5d1SDavid du Colombier char *value; 5143e12c5d1SDavid du Colombier int len; 5153e12c5d1SDavid du Colombier Evalue *link; 5167dd7cddfSDavid du Colombier Qid qid; 5173e12c5d1SDavid du Colombier }; 5183e12c5d1SDavid du Colombier 5193e12c5d1SDavid du Colombier struct Fgrp 5203e12c5d1SDavid du Colombier { 5213e12c5d1SDavid du Colombier Ref; 5227dd7cddfSDavid du Colombier Chan **fd; 5237dd7cddfSDavid du Colombier int nfd; /* number allocated */ 5243e12c5d1SDavid du Colombier int maxfd; /* highest fd in use */ 525fb7f0c93SDavid du Colombier int exceed; /* debugging */ 5263e12c5d1SDavid du Colombier }; 5273e12c5d1SDavid du Colombier 5287dd7cddfSDavid du Colombier enum 5297dd7cddfSDavid du Colombier { 5307dd7cddfSDavid du Colombier DELTAFD = 20 /* incremental increase in Fgrp.fd's */ 5317dd7cddfSDavid du Colombier }; 5327dd7cddfSDavid du Colombier 5334de34a7eSDavid du Colombier struct Pallocmem 5344de34a7eSDavid du Colombier { 5354de34a7eSDavid du Colombier ulong base; 5364de34a7eSDavid du Colombier ulong npage; 5374de34a7eSDavid du Colombier }; 5384de34a7eSDavid du Colombier 5393e12c5d1SDavid du Colombier struct Palloc 5403e12c5d1SDavid du Colombier { 5413e12c5d1SDavid du Colombier Lock; 5424de34a7eSDavid du Colombier Pallocmem mem[4]; 5433e12c5d1SDavid du Colombier Page *head; /* most recently used */ 5443e12c5d1SDavid du Colombier Page *tail; /* least recently used */ 5453e12c5d1SDavid du Colombier ulong freecount; /* how many pages on free list now */ 546ea15f0ccSDavid du Colombier Page *pages; /* array of all pages */ 5473e12c5d1SDavid du Colombier ulong user; /* how many user pages */ 5483e12c5d1SDavid du Colombier Page *hash[PGHSIZE]; 5493e12c5d1SDavid du Colombier Lock hashlock; 5503e12c5d1SDavid du Colombier Rendez r; /* Sleep for free mem */ 5513e12c5d1SDavid du Colombier QLock pwait; /* Queue of procs waiting for memory */ 5523e12c5d1SDavid du Colombier }; 5533e12c5d1SDavid du Colombier 5543e12c5d1SDavid du Colombier struct Waitq 5553e12c5d1SDavid du Colombier { 5563e12c5d1SDavid du Colombier Waitmsg w; 5573e12c5d1SDavid du Colombier Waitq *next; 5583e12c5d1SDavid du Colombier }; 5593e12c5d1SDavid du Colombier 560e288d156SDavid du Colombier /* 561e288d156SDavid du Colombier * fasttick timer interrupts 562e288d156SDavid du Colombier */ 563e288d156SDavid du Colombier enum { 564e288d156SDavid du Colombier /* Mode */ 565e288d156SDavid du Colombier Trelative, /* timer programmed in ns from now */ 566e288d156SDavid du Colombier Tperiodic, /* periodic timer, period in ns */ 567e288d156SDavid du Colombier }; 56812fd1c83SDavid du Colombier 569e288d156SDavid du Colombier struct Timer 570e288d156SDavid du Colombier { 571e288d156SDavid du Colombier /* Public interface */ 572e288d156SDavid du Colombier int tmode; /* See above */ 573e288d156SDavid du Colombier vlong tns; /* meaning defined by mode */ 574e288d156SDavid du Colombier void (*tf)(Ureg*, Timer*); 575e288d156SDavid du Colombier void *ta; 576e288d156SDavid du Colombier /* Internal */ 5772e976735SDavid du Colombier Lock; 578e288d156SDavid du Colombier Timers *tt; /* Timers queue this timer runs on */ 579ea58ad6fSDavid du Colombier Tval tticks; /* tns converted to ticks */ 580ea58ad6fSDavid du Colombier Tval twhen; /* ns represented in fastticks */ 581e288d156SDavid du Colombier Timer *tnext; 582e288d156SDavid du Colombier }; 583e288d156SDavid du Colombier 5843e12c5d1SDavid du Colombier enum 5853e12c5d1SDavid du Colombier { 5863e12c5d1SDavid du Colombier RFNAMEG = (1<<0), 5873e12c5d1SDavid du Colombier RFENVG = (1<<1), 5883e12c5d1SDavid du Colombier RFFDG = (1<<2), 5893e12c5d1SDavid du Colombier RFNOTEG = (1<<3), 5903e12c5d1SDavid du Colombier RFPROC = (1<<4), 5913e12c5d1SDavid du Colombier RFMEM = (1<<5), 5923e12c5d1SDavid du Colombier RFNOWAIT = (1<<6), 5933e12c5d1SDavid du Colombier RFCNAMEG = (1<<10), 5943e12c5d1SDavid du Colombier RFCENVG = (1<<11), 5957dd7cddfSDavid du Colombier RFCFDG = (1<<12), 5967dd7cddfSDavid du Colombier RFREND = (1<<13), 5977dd7cddfSDavid du Colombier RFNOMNT = (1<<14), 5983e12c5d1SDavid du Colombier }; 5993e12c5d1SDavid du Colombier 6003e12c5d1SDavid du Colombier /* 6013e12c5d1SDavid du Colombier * process memory segments - NSEG always last ! 6023e12c5d1SDavid du Colombier */ 6033e12c5d1SDavid du Colombier enum 6043e12c5d1SDavid du Colombier { 6057dd7cddfSDavid du Colombier SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG 6063e12c5d1SDavid du Colombier }; 6073e12c5d1SDavid du Colombier 6083e12c5d1SDavid du Colombier enum 6093e12c5d1SDavid du Colombier { 6103e12c5d1SDavid du Colombier Dead = 0, /* Process states */ 6113e12c5d1SDavid du Colombier Moribund, 6123e12c5d1SDavid du Colombier Ready, 6133e12c5d1SDavid du Colombier Scheding, 6143e12c5d1SDavid du Colombier Running, 6153e12c5d1SDavid du Colombier Queueing, 6167dd7cddfSDavid du Colombier QueueingR, 6177dd7cddfSDavid du Colombier QueueingW, 6183e12c5d1SDavid du Colombier Wakeme, 6193e12c5d1SDavid du Colombier Broken, 6203e12c5d1SDavid du Colombier Stopped, 6213e12c5d1SDavid du Colombier Rendezvous, 622e288d156SDavid du Colombier Waitrelease, 6233e12c5d1SDavid du Colombier 6243e12c5d1SDavid du Colombier Proc_stopme = 1, /* devproc requests */ 6253e12c5d1SDavid du Colombier Proc_exitme, 6263e12c5d1SDavid du Colombier Proc_traceme, 6277dd7cddfSDavid du Colombier Proc_exitbig, 628e288d156SDavid du Colombier Proc_tracesyscall, 6293e12c5d1SDavid du Colombier 6303e12c5d1SDavid du Colombier TUser = 0, /* Proc.time */ 6313e12c5d1SDavid du Colombier TSys, 6323e12c5d1SDavid du Colombier TReal, 6333e12c5d1SDavid du Colombier TCUser, 6343e12c5d1SDavid du Colombier TCSys, 6353e12c5d1SDavid du Colombier TCReal, 636219b2ee8SDavid du Colombier 637dc5a79c1SDavid du Colombier NERR = 64, 6387dd7cddfSDavid du Colombier NNOTE = 5, 6397dd7cddfSDavid du Colombier 640e288d156SDavid du Colombier Npriq = 20, /* number of scheduler priority levels */ 641e288d156SDavid du Colombier Nrq = Npriq+2, /* number of priority levels including real time */ 642da51d93aSDavid du Colombier PriRelease = Npriq, /* released edf processes */ 643da51d93aSDavid du Colombier PriEdf = Npriq+1, /* active edf processes */ 644219b2ee8SDavid du Colombier PriNormal = 10, /* base priority for normal processes */ 645ea58ad6fSDavid du Colombier PriExtra = Npriq-1, /* edf processes at high best-effort pri */ 646219b2ee8SDavid du Colombier PriKproc = 13, /* base priority for kernel processes */ 647219b2ee8SDavid du Colombier PriRoot = 13, /* base priority for root processes */ 6483e12c5d1SDavid du Colombier }; 6493e12c5d1SDavid du Colombier 6509a747e4fSDavid du Colombier struct Schedq 6519a747e4fSDavid du Colombier { 6529a747e4fSDavid du Colombier Lock; 6539a747e4fSDavid du Colombier Proc* head; 6549a747e4fSDavid du Colombier Proc* tail; 6559a747e4fSDavid du Colombier int n; 6569a747e4fSDavid du Colombier }; 6579a747e4fSDavid du Colombier 6583e12c5d1SDavid du Colombier struct Proc 6593e12c5d1SDavid du Colombier { 6607dd7cddfSDavid du Colombier Label sched; /* known to l.s */ 6617dd7cddfSDavid du Colombier char *kstack; /* known to l.s */ 6623e12c5d1SDavid du Colombier Mach *mach; /* machine running this proc */ 6639a747e4fSDavid du Colombier char *text; 6649a747e4fSDavid du Colombier char *user; 6659a747e4fSDavid du Colombier char *args; 6669a747e4fSDavid du Colombier int nargs; /* number of bytes of args */ 6673e12c5d1SDavid du Colombier Proc *rnext; /* next process in run queue */ 6683e12c5d1SDavid du Colombier Proc *qnext; /* next process on queue for a QLock */ 6697dd7cddfSDavid du Colombier QLock *qlock; /* addr of qlock being queued for DEBUG */ 6703e12c5d1SDavid du Colombier int state; 6713e12c5d1SDavid du Colombier char *psstate; /* What /proc/#/status reports */ 6723e12c5d1SDavid du Colombier Segment *seg[NSEG]; 6737dd7cddfSDavid du Colombier QLock seglock; /* locked whenever seg[] changes */ 6743e12c5d1SDavid du Colombier ulong pid; 6753e12c5d1SDavid du Colombier ulong noteid; /* Equivalent of note group */ 6769a747e4fSDavid du Colombier Proc *pidhash; /* next proc in pid hash */ 6773e12c5d1SDavid du Colombier 6783e12c5d1SDavid du Colombier Lock exl; /* Lock count and waitq */ 6793e12c5d1SDavid du Colombier Waitq *waitq; /* Exited processes wait children */ 6803e12c5d1SDavid du Colombier int nchild; /* Number of living children */ 6813e12c5d1SDavid du Colombier int nwait; /* Number of uncollected wait records */ 682219b2ee8SDavid du Colombier QLock qwaitr; 6833e12c5d1SDavid du Colombier Rendez waitr; /* Place to hang out in wait */ 6843e12c5d1SDavid du Colombier Proc *parent; 6853e12c5d1SDavid du Colombier 6867dd7cddfSDavid du Colombier Pgrp *pgrp; /* Process group for namespace */ 6873e12c5d1SDavid du Colombier Egrp *egrp; /* Environment group */ 6883e12c5d1SDavid du Colombier Fgrp *fgrp; /* File descriptor group */ 6897dd7cddfSDavid du Colombier Rgrp *rgrp; /* Rendez group */ 6903e12c5d1SDavid du Colombier 6912cca75a1SDavid du Colombier Fgrp *closingfgrp; /* used during teardown */ 6922cca75a1SDavid du Colombier 6933e12c5d1SDavid du Colombier ulong parentpid; 6943e12c5d1SDavid du Colombier ulong time[6]; /* User, Sys, Real; child U, S, R */ 695e288d156SDavid du Colombier 696e288d156SDavid du Colombier uvlong kentry; /* Kernel entry time stamp (for profiling) */ 697e288d156SDavid du Colombier /* 698e288d156SDavid du Colombier * pcycles: cycles spent in this process (updated on procsave/restore) 699e288d156SDavid du Colombier * when this is the current proc and we're in the kernel 700e288d156SDavid du Colombier * (procrestores outnumber procsaves by one) 701e288d156SDavid du Colombier * the number of cycles spent in the proc is pcycles + cycles() 702e288d156SDavid du Colombier * when this is not the current process or we're in user mode 703e288d156SDavid du Colombier * (procrestores and procsaves balance), it is pcycles. 704e288d156SDavid du Colombier */ 705e288d156SDavid du Colombier vlong pcycles; 706e288d156SDavid du Colombier 7073ff48bf5SDavid du Colombier int insyscall; 7083e12c5d1SDavid du Colombier int fpstate; 7093e12c5d1SDavid du Colombier 7103e12c5d1SDavid du Colombier QLock debug; /* to access debugging elements of User */ 7113e12c5d1SDavid du Colombier Proc *pdbg; /* the debugging process */ 712717772fdSDavid du Colombier ulong procmode; /* proc device default file mode */ 7139a747e4fSDavid du Colombier ulong privatemem; /* proc does not let anyone read mem */ 7143e12c5d1SDavid du Colombier int hang; /* hang at next exec for debug */ 7153e12c5d1SDavid du Colombier int procctl; /* Control for /proc debugging */ 7163e12c5d1SDavid du Colombier ulong pc; /* DEBUG only */ 7173e12c5d1SDavid du Colombier 7187dd7cddfSDavid du Colombier Lock rlock; /* sync sleep/wakeup with postnote */ 7193e12c5d1SDavid du Colombier Rendez *r; /* rendezvous point slept on */ 7203e12c5d1SDavid du Colombier Rendez sleep; /* place for syssleep/debug */ 7213e12c5d1SDavid du Colombier int notepending; /* note issued but not acted on */ 7223e12c5d1SDavid du Colombier int kp; /* true if a kernel process */ 7233e12c5d1SDavid du Colombier Proc *palarm; /* Next alarm time */ 7243e12c5d1SDavid du Colombier ulong alarm; /* Time of call */ 7257dd7cddfSDavid du Colombier int newtlb; /* Pager has changed my pte's, I must flush */ 726b7b24591SDavid du Colombier int noswap; /* process is not swappable */ 7273e12c5d1SDavid du Colombier 7284de34a7eSDavid du Colombier uintptr rendtag; /* Tag for rendezvous */ 7294de34a7eSDavid du Colombier uintptr rendval; /* Value for rendezvous */ 7303e12c5d1SDavid du Colombier Proc *rendhash; /* Hash list for tag values */ 7313e12c5d1SDavid du Colombier 732e288d156SDavid du Colombier Timer; /* For tsleep and real-time */ 7333e12c5d1SDavid du Colombier Rendez *trend; 7343e12c5d1SDavid du Colombier int (*tfn)(void*); 7357dd7cddfSDavid du Colombier void (*kpfun)(void*); 7367dd7cddfSDavid du Colombier void *kparg; 7373e12c5d1SDavid du Colombier 7387dd7cddfSDavid du Colombier FPsave fpsave; /* address of this is known by db */ 7397dd7cddfSDavid du Colombier int scallnr; /* sys call number - known by db */ 7407dd7cddfSDavid du Colombier Sargs s; /* address of this is known by db */ 7417dd7cddfSDavid du Colombier int nerrlab; 7427dd7cddfSDavid du Colombier Label errlab[NERR]; 7439a747e4fSDavid du Colombier char *syserrstr; /* last error from a system call, errbuf0 or 1 */ 7449a747e4fSDavid du Colombier char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */ 7459a747e4fSDavid du Colombier char errbuf0[ERRMAX]; 7469a747e4fSDavid du Colombier char errbuf1[ERRMAX]; 7479a747e4fSDavid du Colombier char genbuf[128]; /* buffer used e.g. for last name element from namec */ 7487dd7cddfSDavid du Colombier Chan *slash; 7497dd7cddfSDavid du Colombier Chan *dot; 7507dd7cddfSDavid du Colombier 7517dd7cddfSDavid du Colombier Note note[NNOTE]; 7527dd7cddfSDavid du Colombier short nnote; 7537dd7cddfSDavid du Colombier short notified; /* sysnoted is due */ 7547dd7cddfSDavid du Colombier Note lastnote; 7557dd7cddfSDavid du Colombier int (*notify)(void*, char*); 7567dd7cddfSDavid du Colombier 7579a747e4fSDavid du Colombier Lock *lockwait; 7589a747e4fSDavid du Colombier Lock *lastlock; /* debugging */ 7593ff48bf5SDavid du Colombier Lock *lastilock; /* debugging */ 7607dd7cddfSDavid du Colombier 7617dd7cddfSDavid du Colombier Mach *wired; 762219b2ee8SDavid du Colombier Mach *mp; /* machine this process last ran on */ 763e288d156SDavid du Colombier Ref nlocks; /* number of locks held by proc */ 7649a747e4fSDavid du Colombier ulong delaysched; 765219b2ee8SDavid du Colombier ulong priority; /* priority level */ 766219b2ee8SDavid du Colombier ulong basepri; /* base priority level */ 76780ee5cbfSDavid du Colombier uchar fixedpri; /* priority level deson't change */ 76859c21d95SDavid du Colombier ulong cpu; /* cpu average */ 76959c21d95SDavid du Colombier ulong lastupdate; 770bd2ae673SDavid du Colombier uchar yield; /* non-zero if the process just did a sleep(0) */ 771a6a9e072SDavid du Colombier ulong readytime; /* time process came ready */ 772219b2ee8SDavid du Colombier ulong movetime; /* last time process switched processors */ 7737dd7cddfSDavid du Colombier int preempted; /* true if this process hasn't finished the interrupt 7747dd7cddfSDavid du Colombier * that last preempted it 7757dd7cddfSDavid du Colombier */ 776e288d156SDavid du Colombier Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */ 777e288d156SDavid du Colombier int trace; /* process being traced? */ 7789a747e4fSDavid du Colombier 7797dd7cddfSDavid du Colombier ulong qpc; /* pc calling last blocking qlock */ 7807dd7cddfSDavid du Colombier 781d9306527SDavid du Colombier int setargs; 782d9306527SDavid du Colombier 7837dd7cddfSDavid du Colombier void *ureg; /* User registers for notes */ 7847dd7cddfSDavid du Colombier void *dbgreg; /* User registers for devproc */ 785*77dd0a98SDavid du Colombier /* Notsave; /* not used since 1st ed.; now use ureg above */ 786219b2ee8SDavid du Colombier 7873e12c5d1SDavid du Colombier /* 7883e12c5d1SDavid du Colombier * machine specific MMU 7893e12c5d1SDavid du Colombier */ 7903e12c5d1SDavid du Colombier PMMU; 791d1be6b08SDavid du Colombier char *syscalltrace; /* syscall trace */ 7923e12c5d1SDavid du Colombier }; 7933e12c5d1SDavid du Colombier 7943e12c5d1SDavid du Colombier enum 7953e12c5d1SDavid du Colombier { 7963e12c5d1SDavid du Colombier PRINTSIZE = 256, 7973e12c5d1SDavid du Colombier MAXCRYPT = 127, 7983e12c5d1SDavid du Colombier NUMSIZE = 12, /* size of formatted number */ 7993e12c5d1SDavid du Colombier MB = (1024*1024), 80046136019SDavid du Colombier /* READSTR was 1000, which is way too small for usb's ctl file */ 80146136019SDavid du Colombier READSTR = 4000, /* temporary buffer size for device reads */ 8023e12c5d1SDavid du Colombier }; 8033e12c5d1SDavid du Colombier 80415bfe97dSDavid du Colombier struct Execvals { 80515bfe97dSDavid du Colombier uvlong entry; 80615bfe97dSDavid du Colombier ulong textsize; 80715bfe97dSDavid du Colombier ulong datasize; 80815bfe97dSDavid du Colombier }; 80915bfe97dSDavid du Colombier 8103e12c5d1SDavid du Colombier extern Conf conf; 8113e12c5d1SDavid du Colombier extern char* conffile; 8123e12c5d1SDavid du Colombier extern int cpuserver; 8137dd7cddfSDavid du Colombier extern Dev* devtab[]; 8149a747e4fSDavid du Colombier extern char* eve; 815219b2ee8SDavid du Colombier extern char hostdomain[]; 8163e12c5d1SDavid du Colombier extern uchar initcode[]; 8174de34a7eSDavid du Colombier extern int kbdbuttons; 8187dd7cddfSDavid du Colombier extern Queue* kbdq; 8199a747e4fSDavid du Colombier extern Queue* kprintoq; 8203e12c5d1SDavid du Colombier extern Ref noteidalloc; 8214de34a7eSDavid du Colombier extern int nsyscall; 8227dd7cddfSDavid du Colombier extern Palloc palloc; 82315bfe97dSDavid du Colombier int (*parseboothdr)(Chan *, ulong, Execvals *); 8249a747e4fSDavid du Colombier extern Queue* serialoq; 8253e12c5d1SDavid du Colombier extern char* statename[]; 8263e12c5d1SDavid du Colombier extern Image swapimage; 8279a747e4fSDavid du Colombier extern char* sysname; 8289a747e4fSDavid du Colombier extern uint qiomaxatomic; 829d1be6b08SDavid du Colombier extern char* sysctab[]; 8307dd7cddfSDavid du Colombier 831a650be7dSDavid du Colombier Watchdog*watchdog; 832a650be7dSDavid du Colombier int watchdogon; 833a650be7dSDavid du Colombier 8347dd7cddfSDavid du Colombier enum 8357dd7cddfSDavid du Colombier { 8367dd7cddfSDavid du Colombier LRESPROF = 3, 8373e12c5d1SDavid du Colombier }; 838bd389b36SDavid du Colombier 839bd389b36SDavid du Colombier /* 8407dd7cddfSDavid du Colombier * action log 841bd389b36SDavid du Colombier */ 8427dd7cddfSDavid du Colombier struct Log { 8437dd7cddfSDavid du Colombier Lock; 8447dd7cddfSDavid du Colombier int opens; 8457dd7cddfSDavid du Colombier char* buf; 8467dd7cddfSDavid du Colombier char *end; 8477dd7cddfSDavid du Colombier char *rptr; 8487dd7cddfSDavid du Colombier int len; 84980ee5cbfSDavid du Colombier int nlog; 85080ee5cbfSDavid du Colombier int minread; 8517dd7cddfSDavid du Colombier 8527dd7cddfSDavid du Colombier int logmask; /* mask of things to debug */ 8537dd7cddfSDavid du Colombier 8547dd7cddfSDavid du Colombier QLock readq; 8557dd7cddfSDavid du Colombier Rendez readr; 856bd389b36SDavid du Colombier }; 8577dd7cddfSDavid du Colombier 8587dd7cddfSDavid du Colombier struct Logflag { 8597dd7cddfSDavid du Colombier char* name; 8607dd7cddfSDavid du Colombier int mask; 8617dd7cddfSDavid du Colombier }; 8627dd7cddfSDavid du Colombier 8639a747e4fSDavid du Colombier enum 8649a747e4fSDavid du Colombier { 8659a747e4fSDavid du Colombier NCMDFIELD = 128 8669a747e4fSDavid du Colombier }; 8679a747e4fSDavid du Colombier 8687dd7cddfSDavid du Colombier struct Cmdbuf 8697dd7cddfSDavid du Colombier { 8709a747e4fSDavid du Colombier char *buf; 8719a747e4fSDavid du Colombier char **f; 8727dd7cddfSDavid du Colombier int nf; 8737dd7cddfSDavid du Colombier }; 8747dd7cddfSDavid du Colombier 8759a747e4fSDavid du Colombier struct Cmdtab 8769a747e4fSDavid du Colombier { 8779a747e4fSDavid du Colombier int index; /* used by client to switch on result */ 8789a747e4fSDavid du Colombier char *cmd; /* command name */ 8799a747e4fSDavid du Colombier int narg; /* expected #args; 0 ==> variadic */ 8809a747e4fSDavid du Colombier }; 8819a747e4fSDavid du Colombier 8829a747e4fSDavid du Colombier /* 8839a747e4fSDavid du Colombier * routines to access UART hardware 8849a747e4fSDavid du Colombier */ 8859a747e4fSDavid du Colombier struct PhysUart 8869a747e4fSDavid du Colombier { 8879a747e4fSDavid du Colombier char* name; 8889a747e4fSDavid du Colombier Uart* (*pnp)(void); 8899a747e4fSDavid du Colombier void (*enable)(Uart*, int); 8909a747e4fSDavid du Colombier void (*disable)(Uart*); 8919a747e4fSDavid du Colombier void (*kick)(Uart*); 8929a747e4fSDavid du Colombier void (*dobreak)(Uart*, int); 8939a747e4fSDavid du Colombier int (*baud)(Uart*, int); 8949a747e4fSDavid du Colombier int (*bits)(Uart*, int); 8959a747e4fSDavid du Colombier int (*stop)(Uart*, int); 8969a747e4fSDavid du Colombier int (*parity)(Uart*, int); 8979a747e4fSDavid du Colombier void (*modemctl)(Uart*, int); 8989a747e4fSDavid du Colombier void (*rts)(Uart*, int); 8999a747e4fSDavid du Colombier void (*dtr)(Uart*, int); 9009a747e4fSDavid du Colombier long (*status)(Uart*, void*, long, long); 9019a747e4fSDavid du Colombier void (*fifo)(Uart*, int); 9029a747e4fSDavid du Colombier void (*power)(Uart*, int); 9039a747e4fSDavid du Colombier int (*getc)(Uart*); /* polling versions, for iprint, rdb */ 9049a747e4fSDavid du Colombier void (*putc)(Uart*, int); 9059a747e4fSDavid du Colombier }; 9069a747e4fSDavid du Colombier 9079a747e4fSDavid du Colombier enum { 908cc162d66SDavid du Colombier Stagesize= STAGESIZE 9099a747e4fSDavid du Colombier }; 9109a747e4fSDavid du Colombier 9119a747e4fSDavid du Colombier /* 9129a747e4fSDavid du Colombier * software UART 9139a747e4fSDavid du Colombier */ 9149a747e4fSDavid du Colombier struct Uart 9159a747e4fSDavid du Colombier { 9169a747e4fSDavid du Colombier void* regs; /* hardware stuff */ 9179a747e4fSDavid du Colombier void* saveregs; /* place to put registers on power down */ 9189a747e4fSDavid du Colombier char* name; /* internal name */ 9199a747e4fSDavid du Colombier ulong freq; /* clock frequency */ 9209a747e4fSDavid du Colombier int bits; /* bits per character */ 9219a747e4fSDavid du Colombier int stop; /* stop bits */ 9229a747e4fSDavid du Colombier int parity; /* even, odd or no parity */ 9239a747e4fSDavid du Colombier int baud; /* baud rate */ 9249a747e4fSDavid du Colombier PhysUart*phys; 9259a747e4fSDavid du Colombier int console; /* used as a serial console */ 9269a747e4fSDavid du Colombier int special; /* internal kernel device */ 9279a747e4fSDavid du Colombier Uart* next; /* list of allocated uarts */ 9289a747e4fSDavid du Colombier 9299a747e4fSDavid du Colombier QLock; 9309a747e4fSDavid du Colombier int type; /* ?? */ 9319a747e4fSDavid du Colombier int dev; 9329a747e4fSDavid du Colombier int opens; 9339a747e4fSDavid du Colombier 9349a747e4fSDavid du Colombier int enabled; 9359a747e4fSDavid du Colombier Uart *elist; /* next enabled interface */ 9369a747e4fSDavid du Colombier 9379a747e4fSDavid du Colombier int perr; /* parity errors */ 9389a747e4fSDavid du Colombier int ferr; /* framing errors */ 9399a747e4fSDavid du Colombier int oerr; /* rcvr overruns */ 9405243b8d1SDavid du Colombier int berr; /* no input buffers */ 9415243b8d1SDavid du Colombier int serr; /* input queue overflow */ 9429a747e4fSDavid du Colombier 9439a747e4fSDavid du Colombier /* buffers */ 9449a747e4fSDavid du Colombier int (*putc)(Queue*, int); 9459a747e4fSDavid du Colombier Queue *iq; 9469a747e4fSDavid du Colombier Queue *oq; 9479a747e4fSDavid du Colombier 9485243b8d1SDavid du Colombier Lock rlock; 9499a747e4fSDavid du Colombier uchar istage[Stagesize]; 9509a747e4fSDavid du Colombier uchar *iw; 9519a747e4fSDavid du Colombier uchar *ir; 9529a747e4fSDavid du Colombier uchar *ie; 9539a747e4fSDavid du Colombier 9549a747e4fSDavid du Colombier Lock tlock; /* transmit */ 9559a747e4fSDavid du Colombier uchar ostage[Stagesize]; 9569a747e4fSDavid du Colombier uchar *op; 9579a747e4fSDavid du Colombier uchar *oe; 958e288d156SDavid du Colombier int drain; 9599a747e4fSDavid du Colombier 9609a747e4fSDavid du Colombier int modem; /* hardware flow control on */ 9619a747e4fSDavid du Colombier int xonoff; /* software flow control on */ 9629a747e4fSDavid du Colombier int blocked; 963a9604be0SDavid du Colombier int cts, dsr, dcd; /* keep track of modem status */ 9649a747e4fSDavid du Colombier int ctsbackoff; 9659a747e4fSDavid du Colombier int hup_dsr, hup_dcd; /* send hangup upstream? */ 9669a747e4fSDavid du Colombier int dohup; 9679a747e4fSDavid du Colombier 9689a747e4fSDavid du Colombier Rendez r; 9699a747e4fSDavid du Colombier }; 9709a747e4fSDavid du Colombier 9719a747e4fSDavid du Colombier extern Uart* consuart; 9729a747e4fSDavid du Colombier 973696c1e60SDavid du Colombier void (*lprint)(char *, int); 974696c1e60SDavid du Colombier 9753ff48bf5SDavid du Colombier /* 9763ff48bf5SDavid du Colombier * performance timers, all units in perfticks 9773ff48bf5SDavid du Colombier */ 9783ff48bf5SDavid du Colombier struct Perf 9793ff48bf5SDavid du Colombier { 9803ff48bf5SDavid du Colombier ulong intrts; /* time of last interrupt */ 9813ff48bf5SDavid du Colombier ulong inintr; /* time since last clock tick in interrupt handlers */ 9823ff48bf5SDavid du Colombier ulong avg_inintr; /* avg time per clock tick in interrupt handlers */ 9833ff48bf5SDavid du Colombier ulong inidle; /* time since last clock tick in idle loop */ 9843ff48bf5SDavid du Colombier ulong avg_inidle; /* avg time per clock tick in idle loop */ 9853ff48bf5SDavid du Colombier ulong last; /* value of perfticks() at last clock tick */ 9863ff48bf5SDavid du Colombier ulong period; /* perfticks() per clock tick */ 9873ff48bf5SDavid du Colombier }; 9883ff48bf5SDavid du Colombier 989079fe160SDavid du Colombier struct Watchdog 990079fe160SDavid du Colombier { 991079fe160SDavid du Colombier void (*enable)(void); /* watchdog enable */ 992079fe160SDavid du Colombier void (*disable)(void); /* watchdog disable */ 993079fe160SDavid du Colombier void (*restart)(void); /* watchdog restart */ 994079fe160SDavid du Colombier void (*stat)(char*, char*); /* watchdog statistics */ 995079fe160SDavid du Colombier }; 996079fe160SDavid du Colombier 997217e9e83SDavid du Colombier struct Watermark 998217e9e83SDavid du Colombier { 999217e9e83SDavid du Colombier int highwater; 1000217e9e83SDavid du Colombier int curr; 1001217e9e83SDavid du Colombier int max; 1002217e9e83SDavid du Colombier int hitmax; /* count: how many times hit max? */ 1003217e9e83SDavid du Colombier char *name; 1004217e9e83SDavid du Colombier }; 1005217e9e83SDavid du Colombier 1006079fe160SDavid du Colombier 10073ff48bf5SDavid du Colombier /* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */ 10083ff48bf5SDavid du Colombier enum 10093ff48bf5SDavid du Colombier { 10103ff48bf5SDavid du Colombier /* Queue.state */ 10113ff48bf5SDavid du Colombier Qstarve = (1<<0), /* consumer starved */ 10123ff48bf5SDavid du Colombier Qmsg = (1<<1), /* message stream */ 10133ff48bf5SDavid du Colombier Qclosed = (1<<2), /* queue has been closed/hungup */ 10143ff48bf5SDavid du Colombier Qflow = (1<<3), /* producer flow controlled */ 1015cdf32439SDavid du Colombier Qcoalesce = (1<<4), /* coalesce packets on read */ 10163ff48bf5SDavid du Colombier Qkick = (1<<5), /* always call the kick routine after qwrite */ 10173ff48bf5SDavid du Colombier }; 10183ff48bf5SDavid du Colombier 10197dd7cddfSDavid du Colombier #define DEVDOTDOT -1 10207dd7cddfSDavid du Colombier 10217dd7cddfSDavid du Colombier #pragma varargck type "I" uchar* 10227dd7cddfSDavid du Colombier #pragma varargck type "V" uchar* 10237dd7cddfSDavid du Colombier #pragma varargck type "E" uchar* 10247dd7cddfSDavid du Colombier #pragma varargck type "M" uchar* 1025