Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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*