1023 lines
22 KiB
C
1023 lines
22 KiB
C
typedef struct Alarms Alarms;
|
|
typedef struct Block Block;
|
|
typedef struct Chan Chan;
|
|
typedef struct Cmdbuf Cmdbuf;
|
|
typedef struct Cmdtab Cmdtab;
|
|
typedef struct Confmem Confmem;
|
|
typedef struct Dev Dev;
|
|
typedef struct Dirtab Dirtab;
|
|
typedef struct Edf Edf;
|
|
typedef struct Egrp Egrp;
|
|
typedef struct Evalue Evalue;
|
|
typedef struct Fgrp Fgrp;
|
|
typedef struct DevConf DevConf;
|
|
typedef struct Image Image;
|
|
typedef struct Log Log;
|
|
typedef struct Logflag Logflag;
|
|
typedef struct Mntcache Mntcache;
|
|
typedef struct Mount Mount;
|
|
typedef struct Mntrah Mntrah;
|
|
typedef struct Mntrpc Mntrpc;
|
|
typedef struct Mntproc Mntproc;
|
|
typedef struct Mnt Mnt;
|
|
typedef struct Mhead Mhead;
|
|
typedef struct Note Note;
|
|
typedef struct Page Page;
|
|
typedef struct Path Path;
|
|
typedef struct Palloc Palloc;
|
|
typedef struct Perf Perf;
|
|
typedef struct PhysUart PhysUart;
|
|
typedef struct Pgrp Pgrp;
|
|
typedef struct Physseg Physseg;
|
|
typedef struct Proc Proc;
|
|
typedef struct Pte Pte;
|
|
typedef struct PMach PMach;
|
|
typedef struct QLock QLock;
|
|
typedef struct Queue Queue;
|
|
typedef struct Ref Ref;
|
|
typedef struct Rendez Rendez;
|
|
typedef struct Rendezq Rendezq;
|
|
typedef struct Rgrp Rgrp;
|
|
typedef struct RWlock RWlock;
|
|
typedef struct Sargs Sargs;
|
|
typedef struct Schedq Schedq;
|
|
typedef struct Segment Segment;
|
|
typedef struct Segio Segio;
|
|
typedef struct Sema Sema;
|
|
typedef struct Timer Timer;
|
|
typedef struct Timers Timers;
|
|
typedef struct Uart Uart;
|
|
typedef struct Waitq Waitq;
|
|
typedef struct Walkqid Walkqid;
|
|
typedef struct Watchpt Watchpt;
|
|
typedef struct Watchdog Watchdog;
|
|
typedef int Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
|
|
|
|
#pragma incomplete DevConf
|
|
#pragma incomplete Edf
|
|
#pragma incomplete Mntcache
|
|
#pragma incomplete Mntrpc
|
|
#pragma incomplete Queue
|
|
#pragma incomplete Timers
|
|
|
|
#include <fcall.h>
|
|
|
|
struct Ref
|
|
{
|
|
long ref;
|
|
};
|
|
|
|
struct Rendez
|
|
{
|
|
Lock;
|
|
Proc *p;
|
|
};
|
|
|
|
struct QLock
|
|
{
|
|
Lock use; /* to access Qlock structure */
|
|
Proc *head; /* next process waiting for object */
|
|
Proc *tail; /* last process waiting for object */
|
|
int locked; /* flag */
|
|
};
|
|
|
|
struct Rendezq
|
|
{
|
|
QLock;
|
|
Rendez;
|
|
};
|
|
|
|
struct RWlock
|
|
{
|
|
Lock use;
|
|
Proc *head; /* list of waiting processes */
|
|
Proc *tail;
|
|
uintptr wpc; /* pc of writer */
|
|
Proc *wproc; /* writing proc */
|
|
int readers; /* number of readers */
|
|
int writer; /* number of writers */
|
|
};
|
|
|
|
struct Alarms
|
|
{
|
|
QLock;
|
|
Proc *head;
|
|
};
|
|
|
|
struct Sargs
|
|
{
|
|
uchar args[MAXSYSARG*BY2WD];
|
|
};
|
|
|
|
/*
|
|
* Access types in namec & channel flags
|
|
*/
|
|
enum
|
|
{
|
|
Aaccess, /* as in stat, wstat */
|
|
Abind, /* for left-hand-side of bind */
|
|
Atodir, /* as in chdir */
|
|
Aopen, /* for i/o */
|
|
Amount, /* to be mounted or mounted upon */
|
|
Acreate, /* is to be created */
|
|
Aremove, /* will be removed by caller */
|
|
|
|
COPEN = 0x0001, /* for i/o */
|
|
CMSG = 0x0002, /* the message channel for a mount */
|
|
/*rsc CCREATE = 0x0004, /* permits creation if c->mnt */
|
|
CCEXEC = 0x0008, /* close on exec (per file descriptor) */
|
|
CFREE = 0x0010, /* not in use */
|
|
CRCLOSE = 0x0020, /* remove on close */
|
|
CCACHE = 0x0080, /* client cache */
|
|
};
|
|
|
|
/* flag values */
|
|
enum
|
|
{
|
|
BINTR = (1<<0),
|
|
BFREE = (1<<1),
|
|
Bipck = (1<<2), /* ip checksum */
|
|
Budpck = (1<<3), /* udp checksum */
|
|
Btcpck = (1<<4), /* tcp checksum */
|
|
Bpktck = (1<<5), /* packet checksum */
|
|
};
|
|
|
|
struct Block
|
|
{
|
|
Block* next;
|
|
Block* list;
|
|
uchar* rp; /* first unconsumed byte */
|
|
uchar* wp; /* first empty byte */
|
|
uchar* lim; /* 1 past the end of the buffer */
|
|
uchar* base; /* start of the buffer */
|
|
void (*free)(Block*);
|
|
ushort flag;
|
|
ushort checksum; /* IP checksum of complete packet (minus media header) */
|
|
};
|
|
|
|
#define BLEN(s) ((s)->wp - (s)->rp)
|
|
#define BALLOC(s) ((s)->lim - (s)->base)
|
|
|
|
struct Chan
|
|
{
|
|
Ref;
|
|
Lock;
|
|
Chan* next; /* allocation */
|
|
Chan* link;
|
|
vlong offset; /* in fd */
|
|
vlong devoffset; /* in underlying device; see read */
|
|
ushort type;
|
|
ulong dev;
|
|
ushort mode; /* read/write */
|
|
ushort flag;
|
|
Qid qid;
|
|
int fid; /* for devmnt */
|
|
ulong iounit; /* chunk size for i/o; 0==default */
|
|
Mhead* umh; /* mount point that derived Chan; used in unionread */
|
|
Chan* umc; /* channel in union; held for union read */
|
|
QLock umqlock; /* serialize unionreads */
|
|
int uri; /* union read index */
|
|
int dri; /* devdirread index */
|
|
uchar* dirrock; /* directory entry rock for translations */
|
|
int nrock;
|
|
int mrock;
|
|
QLock rockqlock;
|
|
int ismtpt;
|
|
Mntcache*mcp; /* Mount cache pointer */
|
|
Mnt* mux; /* Mnt for clients using me for messages */
|
|
union {
|
|
void* aux;
|
|
ulong mid; /* for ns in devproc */
|
|
};
|
|
Chan* mchan; /* channel to mounted server */
|
|
Qid mqid; /* qid of root of mount point */
|
|
Path* path;
|
|
};
|
|
|
|
struct Path
|
|
{
|
|
Ref;
|
|
char *s;
|
|
Chan **mtpt; /* mtpt history */
|
|
int len; /* strlen(s) */
|
|
int alen; /* allocated length of s */
|
|
int mlen; /* number of path elements */
|
|
int malen; /* allocated length of mtpt */
|
|
};
|
|
|
|
struct Dev
|
|
{
|
|
int dc;
|
|
char* name;
|
|
|
|
void (*reset)(void);
|
|
void (*init)(void);
|
|
void (*shutdown)(void);
|
|
Chan* (*attach)(char*);
|
|
Walkqid*(*walk)(Chan*, Chan*, char**, int);
|
|
int (*stat)(Chan*, uchar*, int);
|
|
Chan* (*open)(Chan*, int);
|
|
Chan* (*create)(Chan*, char*, int, ulong);
|
|
void (*close)(Chan*);
|
|
long (*read)(Chan*, void*, long, vlong);
|
|
Block* (*bread)(Chan*, long, ulong);
|
|
long (*write)(Chan*, void*, long, vlong);
|
|
long (*bwrite)(Chan*, Block*, ulong);
|
|
void (*remove)(Chan*);
|
|
int (*wstat)(Chan*, uchar*, int);
|
|
void (*power)(int); /* power mgt: power(1) => on, power (0) => off */
|
|
int (*config)(int, char*, DevConf*); /* returns nil on error */
|
|
};
|
|
|
|
struct Dirtab
|
|
{
|
|
char name[KNAMELEN];
|
|
Qid qid;
|
|
vlong length;
|
|
long perm;
|
|
};
|
|
|
|
struct Walkqid
|
|
{
|
|
Chan *clone;
|
|
int nqid;
|
|
Qid qid[1];
|
|
};
|
|
|
|
struct Mount
|
|
{
|
|
ulong mountid;
|
|
int mflag;
|
|
Mount* next;
|
|
Mount* order;
|
|
Chan* to; /* channel replacing channel */
|
|
char* spec;
|
|
};
|
|
|
|
struct Mhead
|
|
{
|
|
Ref;
|
|
RWlock lock;
|
|
Chan* from; /* channel mounted upon */
|
|
Mount* mount; /* what's mounted upon it */
|
|
Mhead* hash; /* Hash chain */
|
|
};
|
|
|
|
struct Mntrah
|
|
{
|
|
Rendez;
|
|
|
|
ulong vers;
|
|
|
|
vlong off;
|
|
vlong seq;
|
|
|
|
uint i;
|
|
Mntrpc *r[8];
|
|
};
|
|
|
|
struct Mntproc
|
|
{
|
|
Rendez;
|
|
|
|
Mnt *m;
|
|
Mntrpc *r;
|
|
void *a;
|
|
void (*f)(Mntrpc*, void*);
|
|
};
|
|
|
|
struct Mnt
|
|
{
|
|
Lock;
|
|
/* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
|
|
Chan *c; /* Channel to file service */
|
|
Proc *rip; /* Reader in progress */
|
|
Mntrpc *queue; /* Queue of pending requests on this channel */
|
|
Mntproc defered[8]; /* Worker processes for defered RPCs (read ahead) */
|
|
ulong id; /* Multiplexer id for channel check */
|
|
Mnt *list; /* Free list */
|
|
int flags; /* cache */
|
|
int msize; /* data + IOHDRSZ */
|
|
char *version; /* 9P version */
|
|
Queue *q; /* input queue */
|
|
};
|
|
|
|
enum
|
|
{
|
|
NUser, /* note provided externally */
|
|
NExit, /* deliver note quietly */
|
|
NDebug, /* print debug message */
|
|
};
|
|
|
|
struct Note
|
|
{
|
|
char msg[ERRMAX];
|
|
int flag; /* whether system posted it */
|
|
};
|
|
|
|
enum
|
|
{
|
|
PG_MOD = 0x01, /* software modified bit */
|
|
PG_REF = 0x02, /* software referenced bit */
|
|
};
|
|
|
|
struct Page
|
|
{
|
|
Ref;
|
|
Page *next; /* Free list or Hash chains */
|
|
uintptr pa; /* Physical address in memory */
|
|
uintptr va; /* Virtual address for user */
|
|
uintptr daddr; /* Disc address on swap */
|
|
Image *image; /* Associated text or swap image */
|
|
ulong txtflush; /* Flush icache for putmmu */
|
|
ushort refage; /* Swap reference age */
|
|
char modref; /* Simulated modify/reference bits */
|
|
char color; /* Cache coloring */
|
|
};
|
|
|
|
struct Swapalloc
|
|
{
|
|
Lock; /* Free map lock */
|
|
int free; /* currently free swap pages */
|
|
uchar* swmap; /* Base of swap map in memory */
|
|
uchar* alloc; /* Round robin allocator */
|
|
uchar* last; /* Speed swap allocation */
|
|
uchar* top; /* Top of swap map */
|
|
Rendez r; /* Pager kproc idle sleep */
|
|
ulong highwater; /* Pager start threshold */
|
|
ulong headroom; /* Space pager frees under highwater */
|
|
ulong xref; /* Ref count for all map refs >= 255 */
|
|
}swapalloc;
|
|
|
|
struct Pte
|
|
{
|
|
Page *pages[PTEPERTAB]; /* Page map for this chunk of pte */
|
|
Page **first; /* First used entry */
|
|
Page **last; /* Last used entry */
|
|
};
|
|
|
|
/* Segment types */
|
|
enum
|
|
{
|
|
SG_TYPE = 07, /* Mask type of segment */
|
|
SG_TEXT = 00,
|
|
SG_DATA = 01,
|
|
SG_BSS = 02,
|
|
SG_STACK = 03,
|
|
SG_SHARED = 04,
|
|
SG_PHYSICAL = 05,
|
|
SG_FIXED = 06,
|
|
SG_STICKY = 07,
|
|
|
|
SG_RONLY = 0040, /* Segment is read only */
|
|
SG_CEXEC = 0100, /* Detach at exec */
|
|
SG_FAULT = 0200, /* Fault on access */
|
|
SG_CACHED = 0400, /* Normal cached memory */
|
|
SG_DEVICE = 01000, /* Memory mapped device */
|
|
SG_NOEXEC = 02000, /* No execute */
|
|
};
|
|
|
|
#define PG_ONSWAP 1
|
|
#define onswap(s) (((uintptr)s)&PG_ONSWAP)
|
|
#define pagedout(s) (((uintptr)s)==0 || onswap(s))
|
|
#define swapaddr(s) (((uintptr)s)&~PG_ONSWAP)
|
|
|
|
#define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM)
|
|
|
|
struct Physseg
|
|
{
|
|
int attr; /* Segment attributes */
|
|
char *name; /* Attach name */
|
|
uintptr pa; /* Physical address */
|
|
uintptr size; /* Maximum segment size in bytes */
|
|
};
|
|
|
|
struct Sema
|
|
{
|
|
Rendez;
|
|
long *addr;
|
|
int waiting;
|
|
Sema *next;
|
|
Sema *prev;
|
|
};
|
|
|
|
struct Segment
|
|
{
|
|
Ref;
|
|
QLock;
|
|
int type; /* segment type */
|
|
uintptr base; /* virtual base */
|
|
uintptr top; /* virtual top */
|
|
ulong size; /* size in pages */
|
|
uintptr fstart; /* start address in file for demand load */
|
|
uintptr flen; /* length of segment in file */
|
|
int flushme; /* maintain icache for this segment */
|
|
Image *image; /* text in file attached to this segment */
|
|
Physseg *pseg;
|
|
ulong* profile; /* Tick profile area */
|
|
Pte **map;
|
|
int mapsize;
|
|
Pte *ssegmap[SSEGMAPSIZE];
|
|
Sema sema;
|
|
ulong mark; /* portcountrefs */
|
|
};
|
|
|
|
struct Segio
|
|
{
|
|
QLock;
|
|
Rendez cmdwait;
|
|
Rendez replywait;
|
|
|
|
Proc *p; /* segmentio kproc */
|
|
Segment *s;
|
|
|
|
char *data;
|
|
char *addr;
|
|
int dlen;
|
|
int cmd;
|
|
char *err;
|
|
};
|
|
|
|
enum
|
|
{
|
|
RENDLOG = 5,
|
|
RENDHASH = 1<<RENDLOG, /* Hash to lookup rendezvous tags */
|
|
MNTLOG = 5,
|
|
MNTHASH = 1<<MNTLOG, /* Hash to walk mount table */
|
|
NFD = 100, /* per process file descriptors */
|
|
PGHLOG = 9,
|
|
PGHSIZE = 1<<PGHLOG, /* Page hash for image lookup */
|
|
};
|
|
#define REND(p,s) ((p)->rendhash[(s)&((1<<RENDLOG)-1)])
|
|
#define MOUNTH(p,qid) ((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
|
|
#define PGHASH(i,daddr) ((i)->pghash[((daddr)>>PGSHIFT)&(PGHSIZE-1)])
|
|
|
|
struct Image
|
|
{
|
|
Ref;
|
|
Lock;
|
|
Chan *c; /* channel to text file, nil when not used */
|
|
Qid qid; /* Qid for page cache coherence */
|
|
ulong dev; /* Device id of owning channel */
|
|
ushort type; /* Device type of owning channel */
|
|
char notext; /* no file associated */
|
|
Segment *s; /* TEXT segment for image if running */
|
|
Image *hash; /* Qid hash chains */
|
|
Image *next; /* Free list */
|
|
long pgref; /* number of cached pages (pgref <= ref) */
|
|
Page *pghash[PGHSIZE]; /* page cache */
|
|
};
|
|
|
|
|
|
struct Pgrp
|
|
{
|
|
Ref;
|
|
RWlock ns; /* Namespace n read/one write lock */
|
|
int noattach;
|
|
Mhead *mnthash[MNTHASH];
|
|
};
|
|
|
|
struct Rgrp
|
|
{
|
|
Ref;
|
|
Lock;
|
|
Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */
|
|
};
|
|
|
|
struct Egrp
|
|
{
|
|
Ref;
|
|
RWlock;
|
|
Evalue *ent;
|
|
int nent;
|
|
int ment;
|
|
ulong path; /* qid.path of next Evalue to be allocated */
|
|
ulong vers; /* of Egrp */
|
|
};
|
|
|
|
struct Evalue
|
|
{
|
|
char *name;
|
|
char *value;
|
|
int len;
|
|
Qid qid;
|
|
};
|
|
|
|
struct Fgrp
|
|
{
|
|
Ref;
|
|
Lock;
|
|
Chan **fd;
|
|
uchar *flag; /* per file-descriptor flags (CCEXEC) */
|
|
int nfd; /* number allocated */
|
|
int maxfd; /* highest fd in use */
|
|
int exceed; /* debugging */
|
|
};
|
|
|
|
enum
|
|
{
|
|
DELTAFD = 20 /* incremental increase in Fgrp.fd's */
|
|
};
|
|
|
|
struct Palloc
|
|
{
|
|
Lock;
|
|
Page *head; /* freelist head */
|
|
ulong freecount; /* how many pages on free list now */
|
|
Page *pages; /* array of all pages */
|
|
ulong user; /* how many user pages */
|
|
Rendezq pwait[2]; /* Queues of procs waiting for memory */
|
|
};
|
|
|
|
struct Waitq
|
|
{
|
|
Waitmsg w;
|
|
Waitq *next;
|
|
};
|
|
|
|
/*
|
|
* fasttick timer interrupts
|
|
*/
|
|
enum {
|
|
/* Mode */
|
|
Trelative, /* timer programmed in ns from now */
|
|
Tperiodic, /* periodic timer, period in ns */
|
|
};
|
|
|
|
struct Timer
|
|
{
|
|
/* Public interface */
|
|
int tmode; /* See above */
|
|
vlong tns; /* meaning defined by mode */
|
|
void (*tf)(Ureg*, Timer*);
|
|
void *ta;
|
|
/* Internal */
|
|
Lock;
|
|
Mach *tactive; /* The cpu that tf is active on */
|
|
Timers *tt; /* Timers queue this timer runs on */
|
|
Tval tticks; /* tns converted to ticks */
|
|
Tval twhen; /* ns represented in fastticks */
|
|
Timer *tnext;
|
|
};
|
|
|
|
enum
|
|
{
|
|
RFNAMEG = (1<<0),
|
|
RFENVG = (1<<1),
|
|
RFFDG = (1<<2),
|
|
RFNOTEG = (1<<3),
|
|
RFPROC = (1<<4),
|
|
RFMEM = (1<<5),
|
|
RFNOWAIT = (1<<6),
|
|
RFCNAMEG = (1<<10),
|
|
RFCENVG = (1<<11),
|
|
RFCFDG = (1<<12),
|
|
RFREND = (1<<13),
|
|
RFNOMNT = (1<<14),
|
|
};
|
|
|
|
/*
|
|
* process memory segments - NSEG always last !
|
|
*/
|
|
enum
|
|
{
|
|
SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG
|
|
};
|
|
|
|
enum
|
|
{
|
|
Dead = 0, /* Process states */
|
|
Moribund,
|
|
Ready,
|
|
Scheding,
|
|
Running,
|
|
Queueing,
|
|
QueueingR,
|
|
QueueingW,
|
|
Wakeme,
|
|
Broken,
|
|
Stopped,
|
|
Rendezvous,
|
|
Waitrelease,
|
|
|
|
Proc_stopme = 1, /* devproc requests */
|
|
Proc_exitme,
|
|
Proc_traceme,
|
|
Proc_exitbig,
|
|
Proc_tracesyscall,
|
|
|
|
TUser = 0, /* Proc.time */
|
|
TSys,
|
|
TReal,
|
|
TCUser,
|
|
TCSys,
|
|
TCReal,
|
|
|
|
NERR = 64,
|
|
NNOTE = 5,
|
|
|
|
Npriq = 20, /* number of scheduler priority levels */
|
|
Nrq = Npriq+2, /* number of priority levels including real time */
|
|
PriRelease = Npriq, /* released edf processes */
|
|
PriEdf = Npriq+1, /* active edf processes */
|
|
PriNormal = 10, /* base priority for normal processes */
|
|
PriExtra = Npriq-1, /* edf processes at high best-effort pri */
|
|
PriKproc = 13, /* base priority for kernel processes */
|
|
PriRoot = 13, /* base priority for root processes */
|
|
};
|
|
|
|
struct Schedq
|
|
{
|
|
Lock;
|
|
Proc* head;
|
|
Proc* tail;
|
|
int n;
|
|
};
|
|
|
|
struct Proc
|
|
{
|
|
Label sched; /* known to l.s */
|
|
char *kstack; /* known to l.s */
|
|
Mach *mach; /* machine running this proc */
|
|
char *text;
|
|
char *user;
|
|
|
|
char *args;
|
|
int nargs; /* number of bytes of args */
|
|
int setargs; /* process changed its args */
|
|
|
|
Proc *rnext; /* next process in run queue */
|
|
Proc *qnext; /* next process on queue for a QLock */
|
|
|
|
char *psstate; /* What /proc/#/status reports */
|
|
int state;
|
|
|
|
ulong pid;
|
|
ulong noteid; /* Equivalent of note group */
|
|
ulong parentpid;
|
|
|
|
Proc *parent; /* Process to send wait record on exit */
|
|
Lock exl; /* Lock count and waitq */
|
|
Waitq *waitq; /* Exited processes wait children */
|
|
int nchild; /* Number of living children */
|
|
int nwait; /* Number of uncollected wait records */
|
|
QLock qwaitr;
|
|
Rendez waitr; /* Place to hang out in wait */
|
|
|
|
QLock seglock; /* locked whenever seg[] changes */
|
|
Segment *seg[NSEG];
|
|
|
|
Pgrp *pgrp; /* Process group for namespace */
|
|
Egrp *egrp; /* Environment group */
|
|
Fgrp *fgrp; /* File descriptor group */
|
|
Rgrp *rgrp; /* Rendez group */
|
|
|
|
Fgrp *closingfgrp; /* used during teardown */
|
|
|
|
int insyscall;
|
|
ulong time[6]; /* User, Sys, Real; child U, S, R */
|
|
|
|
uvlong kentry; /* Kernel entry time stamp (for profiling) */
|
|
/*
|
|
* pcycles: cycles spent in this process (updated on procswitch)
|
|
* when this is the current proc and we're in the kernel
|
|
* (procrestores outnumber procsaves by one)
|
|
* the number of cycles spent in the proc is pcycles + cycles()
|
|
* when this is not the current process or we're in user mode
|
|
* (procrestores and procsaves balance), it is pcycles.
|
|
*/
|
|
vlong pcycles;
|
|
|
|
QLock debug; /* to access debugging elements of User */
|
|
Proc *pdbg; /* the debugging process */
|
|
ulong procmode; /* proc device default file mode */
|
|
int privatemem; /* proc does not let anyone read mem */
|
|
int noswap; /* process is not swappable */
|
|
int hang; /* hang at next exec for debug */
|
|
int procctl; /* Control for /proc debugging */
|
|
uintptr pc; /* DEBUG only */
|
|
|
|
Lock rlock; /* sync sleep/wakeup with postnote */
|
|
Rendez *r; /* rendezvous point slept on */
|
|
Rendez sleep; /* place for syssleep/debug */
|
|
int notepending; /* note issued but not acted on */
|
|
int kp; /* true if a kernel process */
|
|
Proc *palarm; /* Next alarm time */
|
|
ulong alarm; /* Time of call */
|
|
int newtlb; /* Pager has changed my pte's, I must flush */
|
|
|
|
uintptr rendtag; /* Tag for rendezvous */
|
|
uintptr rendval; /* Value for rendezvous */
|
|
Proc *rendhash; /* Hash list for tag values */
|
|
|
|
Timer; /* For tsleep and real-time */
|
|
Rendez *trend;
|
|
int (*tfn)(void*);
|
|
void (*kpfun)(void*);
|
|
void *kparg;
|
|
|
|
Sargs s; /* syscall arguments */
|
|
int scallnr; /* sys call number */
|
|
int nerrlab;
|
|
Label errlab[NERR];
|
|
char *syserrstr; /* last error from a system call, errbuf0 or 1 */
|
|
char *errstr; /* reason we're unwinding the error stack, errbuf1 or 0 */
|
|
char errbuf0[ERRMAX];
|
|
char errbuf1[ERRMAX];
|
|
char genbuf[128]; /* buffer used e.g. for last name element from namec */
|
|
Chan *slash;
|
|
Chan *dot;
|
|
|
|
Note note[NNOTE];
|
|
short nnote;
|
|
short notified; /* sysnoted is due */
|
|
Note lastnote;
|
|
int (*notify)(void*, char*);
|
|
|
|
Lock *lockwait;
|
|
Lock *lastlock; /* debugging */
|
|
Lock *lastilock; /* debugging */
|
|
|
|
Mach *wired;
|
|
Mach *mp; /* machine this process last ran on */
|
|
int nlocks; /* number of locks held by proc */
|
|
ulong delaysched;
|
|
ulong priority; /* priority level */
|
|
ulong basepri; /* base priority level */
|
|
uchar fixedpri; /* priority level deson't change */
|
|
ulong cpu; /* cpu average */
|
|
ulong lastupdate;
|
|
uchar yield; /* non-zero if the process just did a sleep(0) */
|
|
ulong readytime; /* time process came ready */
|
|
int preempted; /* true if this process hasn't finished the interrupt
|
|
* that last preempted it
|
|
*/
|
|
Edf *edf; /* if non-null, real-time proc, edf contains scheduling params */
|
|
int trace; /* process being traced? */
|
|
|
|
uintptr qpc; /* pc calling last blocking qlock */
|
|
QLock *eql; /* interruptable eqlock */
|
|
|
|
void *ureg; /* User registers for notes */
|
|
void *dbgreg; /* User registers for devproc */
|
|
|
|
PFPU; /* machine specific fpu state */
|
|
PMMU; /* machine specific mmu state */
|
|
|
|
char *syscalltrace; /* syscall trace */
|
|
|
|
Watchpt *watchpt; /* watchpoints */
|
|
int nwatchpt;
|
|
};
|
|
|
|
enum
|
|
{
|
|
PRINTSIZE = 256,
|
|
NUMSIZE = 12, /* size of formatted number */
|
|
MB = (1024*1024),
|
|
/* READSTR was 1000, which is way too small for usb's ctl file */
|
|
READSTR = 8000, /* temporary buffer size for device reads */
|
|
};
|
|
|
|
extern Conf conf;
|
|
extern char* conffile;
|
|
extern int cpuserver;
|
|
extern Dev* devtab[];
|
|
extern char* eve;
|
|
extern char hostdomain[];
|
|
extern uchar initcode[];
|
|
extern Queue* kprintoq;
|
|
extern int nsyscall;
|
|
extern Palloc palloc;
|
|
extern Queue* serialoq;
|
|
extern char* statename[];
|
|
extern Image swapimage;
|
|
extern Image fscache;
|
|
extern char* sysname;
|
|
extern uint qiomaxatomic;
|
|
extern char* sysctab[];
|
|
|
|
enum
|
|
{
|
|
LRESPROF = 3,
|
|
};
|
|
|
|
/*
|
|
* action log
|
|
*/
|
|
struct Log {
|
|
Lock;
|
|
int opens;
|
|
char* buf;
|
|
char *end;
|
|
char *rptr;
|
|
int len;
|
|
int nlog;
|
|
int minread;
|
|
|
|
int logmask; /* mask of things to debug */
|
|
|
|
QLock readq;
|
|
Rendez readr;
|
|
};
|
|
|
|
struct Logflag {
|
|
char* name;
|
|
int mask;
|
|
};
|
|
|
|
enum
|
|
{
|
|
NCMDFIELD = 128
|
|
};
|
|
|
|
struct Cmdbuf
|
|
{
|
|
char *buf;
|
|
char **f;
|
|
int nf;
|
|
};
|
|
|
|
struct Cmdtab
|
|
{
|
|
int index; /* used by client to switch on result */
|
|
char *cmd; /* command name */
|
|
int narg; /* expected #args; 0 ==> variadic */
|
|
};
|
|
|
|
/*
|
|
* routines to access UART hardware
|
|
*/
|
|
struct PhysUart
|
|
{
|
|
char* name;
|
|
Uart* (*pnp)(void);
|
|
void (*enable)(Uart*, int);
|
|
void (*disable)(Uart*);
|
|
void (*kick)(Uart*);
|
|
void (*dobreak)(Uart*, int);
|
|
int (*baud)(Uart*, int);
|
|
int (*bits)(Uart*, int);
|
|
int (*stop)(Uart*, int);
|
|
int (*parity)(Uart*, int);
|
|
void (*modemctl)(Uart*, int);
|
|
void (*rts)(Uart*, int);
|
|
void (*dtr)(Uart*, int);
|
|
long (*status)(Uart*, void*, long, long);
|
|
void (*fifo)(Uart*, int);
|
|
void (*power)(Uart*, int);
|
|
int (*getc)(Uart*); /* polling versions, for iprint, rdb */
|
|
void (*putc)(Uart*, int);
|
|
};
|
|
|
|
enum {
|
|
Stagesize= 2048
|
|
};
|
|
|
|
/*
|
|
* software UART
|
|
*/
|
|
struct Uart
|
|
{
|
|
void* regs; /* hardware stuff */
|
|
void* saveregs; /* place to put registers on power down */
|
|
char* name; /* internal name */
|
|
ulong freq; /* clock frequency */
|
|
int bits; /* bits per character */
|
|
int stop; /* stop bits */
|
|
int parity; /* even, odd or no parity */
|
|
int baud; /* baud rate */
|
|
PhysUart*phys;
|
|
int console; /* used as a serial console */
|
|
int special; /* internal kernel device */
|
|
Uart* next; /* list of allocated uarts */
|
|
|
|
QLock;
|
|
int type; /* ?? */
|
|
int dev;
|
|
int opens;
|
|
|
|
int enabled;
|
|
Uart *elist; /* next enabled interface */
|
|
|
|
int perr; /* parity errors */
|
|
int ferr; /* framing errors */
|
|
int oerr; /* rcvr overruns */
|
|
int berr; /* no input buffers */
|
|
int serr; /* input queue overflow */
|
|
|
|
/* buffers */
|
|
int (*putc)(Queue*, int);
|
|
Queue *iq;
|
|
Queue *oq;
|
|
|
|
Lock rlock;
|
|
uchar istage[Stagesize];
|
|
uchar *iw;
|
|
uchar *ir;
|
|
uchar *ie;
|
|
|
|
Lock tlock; /* transmit */
|
|
uchar ostage[Stagesize];
|
|
uchar *op;
|
|
uchar *oe;
|
|
int drain;
|
|
|
|
int modem; /* hardware flow control on */
|
|
int xonoff; /* software flow control on */
|
|
int blocked;
|
|
int cts, dsr, dcd; /* keep track of modem status */
|
|
int ctsbackoff;
|
|
int hup_dsr, hup_dcd; /* send hangup upstream? */
|
|
int dohup;
|
|
|
|
Rendez r;
|
|
};
|
|
|
|
extern Uart* consuart;
|
|
|
|
/*
|
|
* performance timers, all units in perfticks
|
|
*/
|
|
struct Perf
|
|
{
|
|
ulong intrts; /* time of last interrupt */
|
|
ulong inintr; /* time since last clock tick in interrupt handlers */
|
|
ulong avg_inintr; /* avg time per clock tick in interrupt handlers */
|
|
ulong inidle; /* time since last clock tick in idle loop */
|
|
ulong avg_inidle; /* avg time per clock tick in idle loop */
|
|
ulong last; /* value of perfticks() at last clock tick */
|
|
ulong period; /* perfticks() per clock tick */
|
|
};
|
|
|
|
struct Watchdog
|
|
{
|
|
void (*enable)(void); /* watchdog enable */
|
|
void (*disable)(void); /* watchdog disable */
|
|
void (*restart)(void); /* watchdog restart */
|
|
void (*stat)(char*, char*); /* watchdog statistics */
|
|
};
|
|
|
|
struct Watchpt
|
|
{
|
|
enum {
|
|
WATCHRD = 1,
|
|
WATCHWR = 2,
|
|
WATCHEX = 4,
|
|
} type;
|
|
uintptr addr, len;
|
|
};
|
|
|
|
struct PMach
|
|
{
|
|
Proc* readied; /* for runproc */
|
|
Label sched; /* scheduler wakeup */
|
|
ulong ticks; /* of the clock since boot time */
|
|
ulong schedticks; /* next forced context switch */
|
|
|
|
int pfault;
|
|
int cs;
|
|
int syscall;
|
|
int load;
|
|
int intr;
|
|
int ilockdepth;
|
|
|
|
int flushmmu; /* make current proc flush it's mmu state */
|
|
|
|
int tlbfault;
|
|
int tlbpurge;
|
|
|
|
Perf perf; /* performance counters */
|
|
|
|
uvlong cyclefreq; /* Frequency of user readable cycle counter */
|
|
};
|
|
|
|
/* queue state bits, Qmsg, Qcoalesce, and Qkick can be set in qopen */
|
|
enum
|
|
{
|
|
/* Queue.state */
|
|
Qstarve = (1<<0), /* consumer starved */
|
|
Qmsg = (1<<1), /* message stream */
|
|
Qclosed = (1<<2), /* queue has been closed/hungup */
|
|
Qflow = (1<<3), /* producer flow controlled */
|
|
Qcoalesce = (1<<4), /* coallesce packets on read */
|
|
Qkick = (1<<5), /* always call the kick routine after qwrite */
|
|
};
|
|
|
|
#define DEVDOTDOT -1
|
|
|
|
#pragma varargck type "I" uchar*
|
|
#pragma varargck type "V" uchar*
|
|
#pragma varargck type "E" uchar*
|
|
#pragma varargck type "M" uchar*
|
|
|
|
/*
|
|
* Log console output so it can be retrieved via /dev/kmesg.
|
|
* This is good for catching boot-time messages after the fact.
|
|
*/
|
|
struct {
|
|
Lock lk;
|
|
uint n;
|
|
char buf[16384];
|
|
} kmesg;
|