xref: /plan9/sys/src/9/port/portdat.h (revision 217e9e83c7f9cc6fb27d97dda90c8339b6f98728)
1 typedef struct Alarms	Alarms;
2 typedef struct Block	Block;
3 typedef struct Chan	Chan;
4 typedef struct Cmdbuf	Cmdbuf;
5 typedef struct Cmdtab	Cmdtab;
6 typedef struct Confmem	Confmem;
7 typedef struct Dev	Dev;
8 typedef struct Dirtab	Dirtab;
9 typedef struct Edf	Edf;
10 typedef struct Egrp	Egrp;
11 typedef struct Evalue	Evalue;
12 typedef struct Execvals	Execvals;
13 typedef struct Fgrp	Fgrp;
14 typedef struct DevConf	DevConf;
15 typedef struct Image	Image;
16 typedef struct Log	Log;
17 typedef struct Logflag	Logflag;
18 typedef struct Mntcache Mntcache;
19 typedef struct Mount	Mount;
20 typedef struct Mntrpc	Mntrpc;
21 typedef struct Mntwalk	Mntwalk;
22 typedef struct Mnt	Mnt;
23 typedef struct Mhead	Mhead;
24 typedef struct Note	Note;
25 typedef struct Page	Page;
26 typedef struct Path	Path;
27 typedef struct Palloc	Palloc;
28 typedef struct Pallocmem	Pallocmem;
29 typedef struct Perf	Perf;
30 typedef struct PhysUart	PhysUart;
31 typedef struct Pgrp	Pgrp;
32 typedef struct Physseg	Physseg;
33 typedef struct Proc	Proc;
34 typedef struct Pte	Pte;
35 typedef struct QLock	QLock;
36 typedef struct Queue	Queue;
37 typedef struct Ref	Ref;
38 typedef struct Rendez	Rendez;
39 typedef struct Rgrp	Rgrp;
40 typedef struct RWlock	RWlock;
41 typedef struct Sargs	Sargs;
42 typedef struct Schedq	Schedq;
43 typedef struct Segment	Segment;
44 typedef struct Sema	Sema;
45 typedef struct Timer	Timer;
46 typedef struct Timers	Timers;
47 typedef struct Uart	Uart;
48 typedef struct Waitq	Waitq;
49 typedef struct Walkqid	Walkqid;
50 typedef struct Watchdog	Watchdog;
51 typedef struct Watermark	Watermark;
52 typedef int    Devgen(Chan*, char*, Dirtab*, int, int, Dir*);
53 
54 #pragma incomplete DevConf
55 #pragma incomplete Edf
56 #pragma incomplete Mntcache
57 #pragma incomplete Mntrpc
58 #pragma incomplete Queue
59 #pragma incomplete Timers
60 
61 #include <fcall.h>
62 
63 #define HOWMANY(x, y)	(((x)+((y)-1))/(y))
64 #define ROUNDUP(x, y)	(HOWMANY((x), (y))*(y))	/* ceiling */
65 #define ROUNDDN(x, y)	(((x)/(y))*(y))		/* floor */
66 #define	ROUND(s, sz)	(((s)+(sz-1))&~(sz-1))
67 #define	PGROUND(s)	ROUNDUP(s, BY2PG)
68 #define MIN(a, b)	((a) < (b)? (a): (b))
69 #define MAX(a, b)	((a) > (b)? (a): (b))
70 
71 /*
72  * For multi-bit fields use FIELD(v, o, w) where 'v' is the value
73  * of the bit-field of width 'w' with LSb at bit offset 'o'.
74  */
75 #define FIELD(v, o, w)	(((v) & ((1<<(w))-1))<<(o))
76 
77 #define FCLR(d, o, w)	((d) & ~(((1<<(w))-1)<<(o)))
78 #define FEXT(d, o, w)	(((d)>>(o)) & ((1<<(w))-1))
79 #define FINS(d, o, w, v) (FCLR((d), (o), (w))|FIELD((v), (o), (w)))
80 #define FSET(d, o, w)	((d)|(((1<<(w))-1)<<(o)))
81 
82 #define FMASK(o, w)	(((1<<(w))-1)<<(o))
83 
84 /* let each port override any of these */
85 #ifndef KMESGSIZE
86 #define KMESGSIZE (16*1024)
87 #endif
88 #ifndef PCICONSSIZE
89 #define PCICONSSIZE (16*1024)
90 #endif
91 #ifndef STAGESIZE
92 #define STAGESIZE 64
93 #endif
94 #ifndef MAXBY2PG
95 #define MAXBY2PG BY2PG		/* rounding for UTZERO in executables */
96 #endif
97 
98 struct Ref
99 {
100 	Lock;
101 	long	ref;
102 };
103 
104 struct Rendez
105 {
106 	Lock;
107 	Proc	*p;
108 };
109 
110 struct QLock
111 {
112 	Lock	use;		/* to access Qlock structure */
113 	Proc	*head;		/* next process waiting for object */
114 	Proc	*tail;		/* last process waiting for object */
115 	int	locked;		/* flag */
116 	uintptr	qpc;		/* pc of the holder */
117 };
118 
119 struct RWlock
120 {
121 	Lock	use;
122 	Proc	*head;		/* list of waiting processes */
123 	Proc	*tail;
124 	ulong	wpc;		/* pc of writer */
125 	Proc	*wproc;		/* writing proc */
126 	int	readers;	/* number of readers */
127 	int	writer;		/* number of writers */
128 };
129 
130 struct Alarms
131 {
132 	QLock;
133 	Proc	*head;
134 };
135 
136 struct Sargs
137 {
138 	ulong	args[MAXSYSARG];
139 };
140 
141 /*
142  * Access types in namec & channel flags
143  */
144 enum
145 {
146 	Aaccess,			/* as in stat, wstat */
147 	Abind,				/* for left-hand-side of bind */
148 	Atodir,				/* as in chdir */
149 	Aopen,				/* for i/o */
150 	Amount,				/* to be mounted or mounted upon */
151 	Acreate,			/* is to be created */
152 	Aremove,			/* will be removed by caller */
153 
154 	COPEN	= 0x0001,		/* for i/o */
155 	CMSG	= 0x0002,		/* the message channel for a mount */
156 /*rsc	CCREATE	= 0x0004,		/* permits creation if c->mnt */
157 	CCEXEC	= 0x0008,		/* close on exec */
158 	CFREE	= 0x0010,		/* not in use */
159 	CRCLOSE	= 0x0020,		/* remove on close */
160 	CCACHE	= 0x0080,		/* client cache */
161 };
162 
163 /* flag values */
164 enum
165 {
166 	BINTR	=	(1<<0),
167 	BFREE	=	(1<<1),
168 	Bipck	=	(1<<2),		/* ip checksum */
169 	Budpck	=	(1<<3),		/* udp checksum */
170 	Btcpck	=	(1<<4),		/* tcp checksum */
171 	Bpktck	=	(1<<5),		/* packet checksum */
172 };
173 
174 struct Block
175 {
176 	long	ref;
177 	Block*	next;
178 	Block*	list;
179 	uchar*	rp;			/* first unconsumed byte */
180 	uchar*	wp;			/* first empty byte */
181 	uchar*	lim;			/* 1 past the end of the buffer */
182 	uchar*	base;			/* start of the buffer */
183 	void	(*free)(Block*);
184 	ushort	flag;
185 	ushort	checksum;		/* IP checksum of complete packet (minus media header) */
186 	ulong	magic;
187 };
188 
189 #define BLEN(s)	((s)->wp - (s)->rp)
190 #define BALLOC(s) ((s)->lim - (s)->base)
191 
192 struct Chan
193 {
194 	Ref;				/* the Lock in this Ref is also Chan's lock */
195 	Chan*	next;			/* allocation */
196 	Chan*	link;
197 	vlong	offset;			/* in fd */
198 	vlong	devoffset;		/* in underlying device; see read */
199 	ushort	type;
200 	ulong	dev;
201 	ushort	mode;			/* read/write */
202 	ushort	flag;
203 	Qid	qid;
204 	int	fid;			/* for devmnt */
205 	ulong	iounit;			/* chunk size for i/o; 0==default */
206 	Mhead*	umh;			/* mount point that derived Chan; used in unionread */
207 	Chan*	umc;			/* channel in union; held for union read */
208 	QLock	umqlock;		/* serialize unionreads */
209 	int	uri;			/* union read index */
210 	int	dri;			/* devdirread index */
211 	uchar*	dirrock;		/* directory entry rock for translations */
212 	int	nrock;
213 	int	mrock;
214 	QLock	rockqlock;
215 	int	ismtpt;
216 	Mntcache*mcp;			/* Mount cache pointer */
217 	Mnt*	mux;			/* Mnt for clients using me for messages */
218 	union {
219 		void*	aux;
220 		Qid	pgrpid;		/* for #p/notepg */
221 		ulong	mid;		/* for ns in devproc */
222 	};
223 	Chan*	mchan;			/* channel to mounted server */
224 	Qid	mqid;			/* qid of root of mount point */
225 	Path*	path;
226 };
227 
228 struct Path
229 {
230 	Ref;
231 	char	*s;
232 	Chan	**mtpt;			/* mtpt history */
233 	int	len;			/* strlen(s) */
234 	int	alen;			/* allocated length of s */
235 	int	mlen;			/* number of path elements */
236 	int	malen;			/* allocated length of mtpt */
237 };
238 
239 struct Dev
240 {
241 	int	dc;
242 	char*	name;
243 
244 	void	(*reset)(void);
245 	void	(*init)(void);
246 	void	(*shutdown)(void);
247 	Chan*	(*attach)(char*);
248 	Walkqid*(*walk)(Chan*, Chan*, char**, int);
249 	int	(*stat)(Chan*, uchar*, int);
250 	Chan*	(*open)(Chan*, int);
251 	void	(*create)(Chan*, char*, int, ulong);
252 	void	(*close)(Chan*);
253 	long	(*read)(Chan*, void*, long, vlong);
254 	Block*	(*bread)(Chan*, long, ulong);
255 	long	(*write)(Chan*, void*, long, vlong);
256 	long	(*bwrite)(Chan*, Block*, ulong);
257 	void	(*remove)(Chan*);
258 	int	(*wstat)(Chan*, uchar*, int);
259 	void	(*power)(int);	/* power mgt: power(1) => on, power (0) => off */
260 	int	(*config)(int, char*, DevConf*);	/* returns nil on error */
261 
262 	/* not initialised */
263 	int	attached;				/* debugging */
264 };
265 
266 struct Dirtab
267 {
268 	char	name[KNAMELEN];
269 	Qid	qid;
270 	vlong	length;
271 	long	perm;
272 };
273 
274 struct Walkqid
275 {
276 	Chan	*clone;
277 	int	nqid;
278 	Qid	qid[1];
279 };
280 
281 enum
282 {
283 	NSMAX	=	1000,
284 	NSLOG	=	7,
285 	NSCACHE	=	(1<<NSLOG),
286 };
287 
288 struct Mntwalk				/* state for /proc/#/ns */
289 {
290 	int	cddone;
291 	Mhead*	mh;
292 	Mount*	cm;
293 };
294 
295 struct Mount
296 {
297 	ulong	mountid;
298 	Mount*	next;
299 	Mhead*	head;
300 	Mount*	copy;
301 	Mount*	order;
302 	Chan*	to;			/* channel replacing channel */
303 	int	mflag;
304 	char	*spec;
305 };
306 
307 struct Mhead
308 {
309 	Ref;
310 	RWlock	lock;
311 	Chan*	from;			/* channel mounted upon */
312 	Mount*	mount;			/* what's mounted upon it */
313 	Mhead*	hash;			/* Hash chain */
314 };
315 
316 struct Mnt
317 {
318 	Lock;
319 	/* references are counted using c->ref; channels on this mount point incref(c->mchan) == Mnt.c */
320 	Chan	*c;		/* Channel to file service */
321 	Proc	*rip;		/* Reader in progress */
322 	Mntrpc	*queue;		/* Queue of pending requests on this channel */
323 	ulong	id;		/* Multiplexer id for channel check */
324 	Mnt	*list;		/* Free list */
325 	int	flags;		/* cache */
326 	int	msize;		/* data + IOHDRSZ */
327 	char	*version;	/* 9P version */
328 	Queue	*q;		/* input queue */
329 };
330 
331 enum
332 {
333 	NUser,				/* note provided externally */
334 	NExit,				/* deliver note quietly */
335 	NDebug,				/* print debug message */
336 };
337 
338 struct Note
339 {
340 	char	msg[ERRMAX];
341 	int	flag;			/* whether system posted it */
342 };
343 
344 enum
345 {
346 	PG_NOFLUSH	= 0,
347 	PG_TXTFLUSH	= 1,		/* flush dcache and invalidate icache */
348 	PG_DATFLUSH	= 2,		/* flush both i & d caches (UNUSED) */
349 	PG_NEWCOL	= 3,		/* page has been recolored */
350 
351 	PG_MOD		= 0x01,		/* software modified bit */
352 	PG_REF		= 0x02,		/* software referenced bit */
353 };
354 
355 struct Page
356 {
357 	Lock;
358 	ulong	pa;			/* Physical address in memory */
359 	ulong	va;			/* Virtual address for user */
360 	ulong	daddr;			/* Disc address on swap */
361 	ulong	gen;			/* Generation counter for swap */
362 	ushort	ref;			/* Reference count */
363 	char	modref;			/* Simulated modify/reference bits */
364 	char	color;			/* Cache coloring */
365 	char	cachectl[MAXMACH];	/* Cache flushing control for putmmu */
366 	Image	*image;			/* Associated text or swap image */
367 	Page	*next;			/* Lru free list */
368 	Page	*prev;
369 	Page	*hash;			/* Image hash chains */
370 };
371 
372 struct Swapalloc
373 {
374 	Lock;				/* Free map lock */
375 	int	free;			/* currently free swap pages */
376 	uchar*	swmap;			/* Base of swap map in memory */
377 	uchar*	alloc;			/* Round robin allocator */
378 	uchar*	last;			/* Speed swap allocation */
379 	uchar*	top;			/* Top of swap map */
380 	Rendez	r;			/* Pager kproc idle sleep */
381 	ulong	highwater;		/* Pager start threshold */
382 	ulong	headroom;		/* Space pager frees under highwater */
383 }swapalloc;
384 
385 struct Image
386 {
387 	Ref;
388 	Chan	*c;			/* channel to text file */
389 	Qid 	qid;			/* Qid for page cache coherence */
390 	Qid	mqid;
391 	Chan	*mchan;
392 	ushort	type;			/* Device type of owning channel */
393 	Segment *s;			/* TEXT segment for image if running */
394 	Image	*hash;			/* Qid hash chains */
395 	Image	*next;			/* Free list */
396 	int	notext;			/* no file associated */
397 };
398 
399 struct Pte
400 {
401 	Page	*pages[PTEPERTAB];	/* Page map for this chunk of pte */
402 	Page	**first;		/* First used entry */
403 	Page	**last;			/* Last used entry */
404 };
405 
406 /* Segment types */
407 enum
408 {
409 	SG_TYPE		= 07,		/* Mask type of segment */
410 	SG_TEXT		= 00,
411 	SG_DATA		= 01,
412 	SG_BSS		= 02,
413 	SG_STACK	= 03,
414 	SG_SHARED	= 04,
415 	SG_PHYSICAL	= 05,
416 
417 	SG_RONLY	= 0040,		/* Segment is read only */
418 	SG_CEXEC	= 0100,		/* Detach at exec */
419 };
420 
421 #define PG_ONSWAP	1
422 #define onswap(s)	(((ulong)s)&PG_ONSWAP)
423 #define pagedout(s)	(((ulong)s)==0 || onswap(s))
424 #define swapaddr(s)	(((ulong)s)&~PG_ONSWAP)
425 
426 #define SEGMAXSIZE	(SEGMAPSIZE*PTEMAPMEM)
427 
428 struct Physseg
429 {
430 	ulong	attr;			/* Segment attributes */
431 	char	*name;			/* Attach name */
432 	ulong	pa;			/* Physical address */
433 	ulong	size;			/* Maximum segment size in pages */
434 	Page	*(*pgalloc)(Segment*, ulong);	/* Allocation if we need it */
435 	void	(*pgfree)(Page*);
436 };
437 
438 struct Sema
439 {
440 	Rendez;
441 	long	*addr;
442 	int	waiting;
443 	Sema	*next;
444 	Sema	*prev;
445 };
446 
447 struct Segment
448 {
449 	Ref;
450 	QLock	lk;
451 	ushort	steal;		/* Page stealer lock */
452 	ushort	type;		/* segment type */
453 	ulong	base;		/* virtual base */
454 	ulong	top;		/* virtual top */
455 	ulong	size;		/* size in pages */
456 	ulong	fstart;		/* start address in file for demand load */
457 	ulong	flen;		/* length of segment in file */
458 	int	flushme;	/* maintain icache for this segment */
459 	Image	*image;		/* text in file attached to this segment */
460 	Physseg *pseg;
461 	ulong*	profile;	/* Tick profile area */
462 	Pte	**map;
463 	int	mapsize;
464 	Pte	*ssegmap[SSEGMAPSIZE];
465 	Lock	semalock;
466 	Sema	sema;
467 	ulong	mark;		/* portcountrefs */
468 };
469 
470 enum
471 {
472 	RENDLOG	=	5,
473 	RENDHASH =	1<<RENDLOG,	/* Hash to lookup rendezvous tags */
474 	MNTLOG	=	5,
475 	MNTHASH =	1<<MNTLOG,	/* Hash to walk mount table */
476 	NFD =		100,		/* per process file descriptors */
477 	PGHLOG  =	9,
478 	PGHSIZE	=	1<<PGHLOG,	/* Page hash for image lookup */
479 };
480 #define REND(p,s)	((p)->rendhash[(s)&((1<<RENDLOG)-1)])
481 #define MOUNTH(p,qid)	((p)->mnthash[(qid).path&((1<<MNTLOG)-1)])
482 
483 struct Pgrp
484 {
485 	Ref;				/* also used as a lock when mounting */
486 	int	noattach;
487 	ulong	pgrpid;
488 	QLock	debug;			/* single access via devproc.c */
489 	RWlock	ns;			/* Namespace n read/one write lock */
490 	Mhead	*mnthash[MNTHASH];
491 };
492 
493 struct Rgrp
494 {
495 	Ref;				/* the Ref's lock is also the Rgrp's lock */
496 	Proc	*rendhash[RENDHASH];	/* Rendezvous tag hash */
497 };
498 
499 struct Egrp
500 {
501 	Ref;
502 	RWlock;
503 	Evalue	**ent;
504 	int	nent;
505 	int	ment;
506 	ulong	path;	/* qid.path of next Evalue to be allocated */
507 	ulong	vers;	/* of Egrp */
508 };
509 
510 struct Evalue
511 {
512 	char	*name;
513 	char	*value;
514 	int	len;
515 	Evalue	*link;
516 	Qid	qid;
517 };
518 
519 struct Fgrp
520 {
521 	Ref;
522 	Chan	**fd;
523 	int	nfd;			/* number allocated */
524 	int	maxfd;			/* highest fd in use */
525 	int	exceed;			/* debugging */
526 };
527 
528 enum
529 {
530 	DELTAFD	= 20		/* incremental increase in Fgrp.fd's */
531 };
532 
533 struct Pallocmem
534 {
535 	ulong base;
536 	ulong npage;
537 };
538 
539 struct Palloc
540 {
541 	Lock;
542 	Pallocmem	mem[4];
543 	Page	*head;			/* most recently used */
544 	Page	*tail;			/* least recently used */
545 	ulong	freecount;		/* how many pages on free list now */
546 	Page	*pages;			/* array of all pages */
547 	ulong	user;			/* how many user pages */
548 	Page	*hash[PGHSIZE];
549 	Lock	hashlock;
550 	Rendez	r;			/* Sleep for free mem */
551 	QLock	pwait;			/* Queue of procs waiting for memory */
552 };
553 
554 struct Waitq
555 {
556 	Waitmsg	w;
557 	Waitq	*next;
558 };
559 
560 /*
561  * fasttick timer interrupts
562  */
563 enum {
564 	/* Mode */
565 	Trelative,	/* timer programmed in ns from now */
566 	Tperiodic,	/* periodic timer, period in ns */
567 };
568 
569 struct Timer
570 {
571 	/* Public interface */
572 	int	tmode;		/* See above */
573 	vlong	tns;		/* meaning defined by mode */
574 	void	(*tf)(Ureg*, Timer*);
575 	void	*ta;
576 	/* Internal */
577 	Lock;
578 	Timers	*tt;		/* Timers queue this timer runs on */
579 	Tval	tticks;		/* tns converted to ticks */
580 	Tval	twhen;		/* ns represented in fastticks */
581 	Timer	*tnext;
582 };
583 
584 enum
585 {
586 	RFNAMEG		= (1<<0),
587 	RFENVG		= (1<<1),
588 	RFFDG		= (1<<2),
589 	RFNOTEG		= (1<<3),
590 	RFPROC		= (1<<4),
591 	RFMEM		= (1<<5),
592 	RFNOWAIT	= (1<<6),
593 	RFCNAMEG	= (1<<10),
594 	RFCENVG		= (1<<11),
595 	RFCFDG		= (1<<12),
596 	RFREND		= (1<<13),
597 	RFNOMNT		= (1<<14),
598 };
599 
600 /*
601  *  process memory segments - NSEG always last !
602  */
603 enum
604 {
605 	SSEG, TSEG, DSEG, BSEG, ESEG, LSEG, SEG1, SEG2, SEG3, SEG4, NSEG
606 };
607 
608 enum
609 {
610 	Dead = 0,		/* Process states */
611 	Moribund,
612 	Ready,
613 	Scheding,
614 	Running,
615 	Queueing,
616 	QueueingR,
617 	QueueingW,
618 	Wakeme,
619 	Broken,
620 	Stopped,
621 	Rendezvous,
622 	Waitrelease,
623 
624 	Proc_stopme = 1, 	/* devproc requests */
625 	Proc_exitme,
626 	Proc_traceme,
627 	Proc_exitbig,
628 	Proc_tracesyscall,
629 
630 	TUser = 0, 		/* Proc.time */
631 	TSys,
632 	TReal,
633 	TCUser,
634 	TCSys,
635 	TCReal,
636 
637 	NERR = 64,
638 	NNOTE = 5,
639 
640 	Npriq		= 20,		/* number of scheduler priority levels */
641 	Nrq		= Npriq+2,	/* number of priority levels including real time */
642 	PriRelease	= Npriq,	/* released edf processes */
643 	PriEdf		= Npriq+1,	/* active edf processes */
644 	PriNormal	= 10,		/* base priority for normal processes */
645 	PriExtra	= Npriq-1,	/* edf processes at high best-effort pri */
646 	PriKproc	= 13,		/* base priority for kernel processes */
647 	PriRoot		= 13,		/* base priority for root processes */
648 };
649 
650 struct Schedq
651 {
652 	Lock;
653 	Proc*	head;
654 	Proc*	tail;
655 	int	n;
656 };
657 
658 struct Proc
659 {
660 	Label	sched;		/* known to l.s */
661 	char	*kstack;	/* known to l.s */
662 	Mach	*mach;		/* machine running this proc */
663 	char	*text;
664 	char	*user;
665 	char	*args;
666 	int	nargs;		/* number of bytes of args */
667 	Proc	*rnext;		/* next process in run queue */
668 	Proc	*qnext;		/* next process on queue for a QLock */
669 	QLock	*qlock;		/* addr of qlock being queued for DEBUG */
670 	int	state;
671 	char	*psstate;	/* What /proc/#/status reports */
672 	Segment	*seg[NSEG];
673 	QLock	seglock;	/* locked whenever seg[] changes */
674 	ulong	pid;
675 	ulong	noteid;		/* Equivalent of note group */
676 	Proc	*pidhash;	/* next proc in pid hash */
677 
678 	Lock	exl;		/* Lock count and waitq */
679 	Waitq	*waitq;		/* Exited processes wait children */
680 	int	nchild;		/* Number of living children */
681 	int	nwait;		/* Number of uncollected wait records */
682 	QLock	qwaitr;
683 	Rendez	waitr;		/* Place to hang out in wait */
684 	Proc	*parent;
685 
686 	Pgrp	*pgrp;		/* Process group for namespace */
687 	Egrp 	*egrp;		/* Environment group */
688 	Fgrp	*fgrp;		/* File descriptor group */
689 	Rgrp	*rgrp;		/* Rendez group */
690 
691 	Fgrp	*closingfgrp;	/* used during teardown */
692 
693 	ulong	parentpid;
694 	ulong	time[6];	/* User, Sys, Real; child U, S, R */
695 
696 	uvlong	kentry;		/* Kernel entry time stamp (for profiling) */
697 	/*
698 	 * pcycles: cycles spent in this process (updated on procsave/restore)
699 	 * when this is the current proc and we're in the kernel
700 	 * (procrestores outnumber procsaves by one)
701 	 * the number of cycles spent in the proc is pcycles + cycles()
702 	 * when this is not the current process or we're in user mode
703 	 * (procrestores and procsaves balance), it is pcycles.
704 	 */
705 	vlong	pcycles;
706 
707 	int	insyscall;
708 	int	fpstate;
709 
710 	QLock	debug;		/* to access debugging elements of User */
711 	Proc	*pdbg;		/* the debugging process */
712 	ulong	procmode;	/* proc device default file mode */
713 	ulong	privatemem;	/* proc does not let anyone read mem */
714 	int	hang;		/* hang at next exec for debug */
715 	int	procctl;	/* Control for /proc debugging */
716 	ulong	pc;		/* DEBUG only */
717 
718 	Lock	rlock;		/* sync sleep/wakeup with postnote */
719 	Rendez	*r;		/* rendezvous point slept on */
720 	Rendez	sleep;		/* place for syssleep/debug */
721 	int	notepending;	/* note issued but not acted on */
722 	int	kp;		/* true if a kernel process */
723 	Proc	*palarm;	/* Next alarm time */
724 	ulong	alarm;		/* Time of call */
725 	int	newtlb;		/* Pager has changed my pte's, I must flush */
726 	int	noswap;		/* process is not swappable */
727 
728 	uintptr	rendtag;	/* Tag for rendezvous */
729 	uintptr	rendval;	/* Value for rendezvous */
730 	Proc	*rendhash;	/* Hash list for tag values */
731 
732 	Timer;			/* For tsleep and real-time */
733 	Rendez	*trend;
734 	int	(*tfn)(void*);
735 	void	(*kpfun)(void*);
736 	void	*kparg;
737 
738 	FPsave	fpsave;		/* address of this is known by db */
739 	int	scallnr;	/* sys call number - known by db */
740 	Sargs	s;		/* address of this is known by db */
741 	int	nerrlab;
742 	Label	errlab[NERR];
743 	char	*syserrstr;	/* last error from a system call, errbuf0 or 1 */
744 	char	*errstr;	/* reason we're unwinding the error stack, errbuf1 or 0 */
745 	char	errbuf0[ERRMAX];
746 	char	errbuf1[ERRMAX];
747 	char	genbuf[128];	/* buffer used e.g. for last name element from namec */
748 	Chan	*slash;
749 	Chan	*dot;
750 
751 	Note	note[NNOTE];
752 	short	nnote;
753 	short	notified;	/* sysnoted is due */
754 	Note	lastnote;
755 	int	(*notify)(void*, char*);
756 
757 	Lock	*lockwait;
758 	Lock	*lastlock;	/* debugging */
759 	Lock	*lastilock;	/* debugging */
760 
761 	Mach	*wired;
762 	Mach	*mp;		/* machine this process last ran on */
763 	Ref	nlocks;		/* number of locks held by proc */
764 	ulong	delaysched;
765 	ulong	priority;	/* priority level */
766 	ulong	basepri;	/* base priority level */
767 	uchar	fixedpri;	/* priority level deson't change */
768 	ulong	cpu;		/* cpu average */
769 	ulong	lastupdate;
770 	uchar	yield;		/* non-zero if the process just did a sleep(0) */
771 	ulong	readytime;	/* time process came ready */
772 	ulong	movetime;	/* last time process switched processors */
773 	int	preempted;	/* true if this process hasn't finished the interrupt
774 				 *  that last preempted it
775 				 */
776 	Edf	*edf;		/* if non-null, real-time proc, edf contains scheduling params */
777 	int	trace;		/* process being traced? */
778 
779 	ulong	qpc;		/* pc calling last blocking qlock */
780 
781 	int	setargs;
782 
783 	void	*ureg;		/* User registers for notes */
784 	void	*dbgreg;	/* User registers for devproc */
785 	Notsave;
786 
787 	/*
788 	 *  machine specific MMU
789 	 */
790 	PMMU;
791 	char	*syscalltrace;	/* syscall trace */
792 };
793 
794 enum
795 {
796 	PRINTSIZE =	256,
797 	MAXCRYPT = 	127,
798 	NUMSIZE	=	12,		/* size of formatted number */
799 	MB =		(1024*1024),
800 	/* READSTR was 1000, which is way too small for usb's ctl file */
801 	READSTR =	4000,		/* temporary buffer size for device reads */
802 };
803 
804 struct Execvals {
805 	uvlong	entry;
806 	ulong	textsize;
807 	ulong	datasize;
808 };
809 
810 extern	Conf	conf;
811 extern	char*	conffile;
812 extern	int	cpuserver;
813 extern	Dev*	devtab[];
814 extern	char*	eve;
815 extern	char	hostdomain[];
816 extern	uchar	initcode[];
817 extern	int	kbdbuttons;
818 extern	Queue*	kbdq;
819 extern	Queue*	kprintoq;
820 extern 	Ref	noteidalloc;
821 extern	int	nsyscall;
822 extern	Palloc	palloc;
823 	int	(*parseboothdr)(Chan *, ulong, Execvals *);
824 extern	Queue*	serialoq;
825 extern	char*	statename[];
826 extern	Image	swapimage;
827 extern	char*	sysname;
828 extern	uint	qiomaxatomic;
829 extern	char*	sysctab[];
830 
831 	Watchdog*watchdog;
832 	int	watchdogon;
833 
834 enum
835 {
836 	LRESPROF	= 3,
837 };
838 
839 /*
840  *  action log
841  */
842 struct Log {
843 	Lock;
844 	int	opens;
845 	char*	buf;
846 	char	*end;
847 	char	*rptr;
848 	int	len;
849 	int	nlog;
850 	int	minread;
851 
852 	int	logmask;	/* mask of things to debug */
853 
854 	QLock	readq;
855 	Rendez	readr;
856 };
857 
858 struct Logflag {
859 	char*	name;
860 	int	mask;
861 };
862 
863 enum
864 {
865 	NCMDFIELD = 128
866 };
867 
868 struct Cmdbuf
869 {
870 	char	*buf;
871 	char	**f;
872 	int	nf;
873 };
874 
875 struct Cmdtab
876 {
877 	int	index;	/* used by client to switch on result */
878 	char	*cmd;	/* command name */
879 	int	narg;	/* expected #args; 0 ==> variadic */
880 };
881 
882 /*
883  *  routines to access UART hardware
884  */
885 struct PhysUart
886 {
887 	char*	name;
888 	Uart*	(*pnp)(void);
889 	void	(*enable)(Uart*, int);
890 	void	(*disable)(Uart*);
891 	void	(*kick)(Uart*);
892 	void	(*dobreak)(Uart*, int);
893 	int	(*baud)(Uart*, int);
894 	int	(*bits)(Uart*, int);
895 	int	(*stop)(Uart*, int);
896 	int	(*parity)(Uart*, int);
897 	void	(*modemctl)(Uart*, int);
898 	void	(*rts)(Uart*, int);
899 	void	(*dtr)(Uart*, int);
900 	long	(*status)(Uart*, void*, long, long);
901 	void	(*fifo)(Uart*, int);
902 	void	(*power)(Uart*, int);
903 	int	(*getc)(Uart*);	/* polling versions, for iprint, rdb */
904 	void	(*putc)(Uart*, int);
905 };
906 
907 enum {
908 	Stagesize=	STAGESIZE
909 };
910 
911 /*
912  *  software UART
913  */
914 struct Uart
915 {
916 	void*	regs;			/* hardware stuff */
917 	void*	saveregs;		/* place to put registers on power down */
918 	char*	name;			/* internal name */
919 	ulong	freq;			/* clock frequency */
920 	int	bits;			/* bits per character */
921 	int	stop;			/* stop bits */
922 	int	parity;			/* even, odd or no parity */
923 	int	baud;			/* baud rate */
924 	PhysUart*phys;
925 	int	console;		/* used as a serial console */
926 	int	special;		/* internal kernel device */
927 	Uart*	next;			/* list of allocated uarts */
928 
929 	QLock;
930 	int	type;			/* ?? */
931 	int	dev;
932 	int	opens;
933 
934 	int	enabled;
935 	Uart	*elist;			/* next enabled interface */
936 
937 	int	perr;			/* parity errors */
938 	int	ferr;			/* framing errors */
939 	int	oerr;			/* rcvr overruns */
940 	int	berr;			/* no input buffers */
941 	int	serr;			/* input queue overflow */
942 
943 	/* buffers */
944 	int	(*putc)(Queue*, int);
945 	Queue	*iq;
946 	Queue	*oq;
947 
948 	Lock	rlock;
949 	uchar	istage[Stagesize];
950 	uchar	*iw;
951 	uchar	*ir;
952 	uchar	*ie;
953 
954 	Lock	tlock;			/* transmit */
955 	uchar	ostage[Stagesize];
956 	uchar	*op;
957 	uchar	*oe;
958 	int	drain;
959 
960 	int	modem;			/* hardware flow control on */
961 	int	xonoff;			/* software flow control on */
962 	int	blocked;
963 	int	cts, dsr, dcd;	/* keep track of modem status */
964 	int	ctsbackoff;
965 	int	hup_dsr, hup_dcd;	/* send hangup upstream? */
966 	int	dohup;
967 
968 	Rendez	r;
969 };
970 
971 extern	Uart*	consuart;
972 
973 void (*lprint)(char *, int);
974 
975 /*
976  *  performance timers, all units in perfticks
977  */
978 struct Perf
979 {
980 	ulong	intrts;		/* time of last interrupt */
981 	ulong	inintr;		/* time since last clock tick in interrupt handlers */
982 	ulong	avg_inintr;	/* avg time per clock tick in interrupt handlers */
983 	ulong	inidle;		/* time since last clock tick in idle loop */
984 	ulong	avg_inidle;	/* avg time per clock tick in idle loop */
985 	ulong	last;		/* value of perfticks() at last clock tick */
986 	ulong	period;		/* perfticks() per clock tick */
987 };
988 
989 struct Watchdog
990 {
991 	void	(*enable)(void);	/* watchdog enable */
992 	void	(*disable)(void);	/* watchdog disable */
993 	void	(*restart)(void);	/* watchdog restart */
994 	void	(*stat)(char*, char*);	/* watchdog statistics */
995 };
996 
997 struct Watermark
998 {
999 	int	highwater;
1000 	int	curr;
1001 	int	max;
1002 	int	hitmax;		/* count: how many times hit max? */
1003 	char	*name;
1004 };
1005 
1006 
1007 /* queue state bits,  Qmsg, Qcoalesce, and Qkick can be set in qopen */
1008 enum
1009 {
1010 	/* Queue.state */
1011 	Qstarve		= (1<<0),	/* consumer starved */
1012 	Qmsg		= (1<<1),	/* message stream */
1013 	Qclosed		= (1<<2),	/* queue has been closed/hungup */
1014 	Qflow		= (1<<3),	/* producer flow controlled */
1015 	Qcoalesce	= (1<<4),	/* coalesce packets on read */
1016 	Qkick		= (1<<5),	/* always call the kick routine after qwrite */
1017 };
1018 
1019 #define DEVDOTDOT -1
1020 
1021 #pragma	varargck	type	"I"	uchar*
1022 #pragma	varargck	type	"V"	uchar*
1023 #pragma	varargck	type	"E"	uchar*
1024 #pragma	varargck	type	"M"	uchar*
1025