2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2015-07-25 20:43:26 -07:00
|
|
|
typedef struct Mntrah Mntrah;
|
2011-03-30 05:46:40 -07:00
|
|
|
typedef struct Mntrpc Mntrpc;
|
2015-07-25 20:43:26 -07:00
|
|
|
typedef struct Mntproc Mntproc;
|
2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2021-04-25 08:41:34 -07:00
|
|
|
typedef struct PMach PMach;
|
2011-03-30 05:46:40 -07:00
|
|
|
typedef struct QLock QLock;
|
|
|
|
typedef struct Queue Queue;
|
|
|
|
typedef struct Ref Ref;
|
|
|
|
typedef struct Rendez Rendez;
|
2015-06-15 07:05:00 -07:00
|
|
|
typedef struct Rendezq Rendezq;
|
2011-03-30 05:46:40 -07:00
|
|
|
typedef struct Rgrp Rgrp;
|
|
|
|
typedef struct RWlock RWlock;
|
|
|
|
typedef struct Sargs Sargs;
|
|
|
|
typedef struct Schedq Schedq;
|
|
|
|
typedef struct Segment Segment;
|
2015-04-15 15:45:25 -07:00
|
|
|
typedef struct Segio Segio;
|
2011-03-30 05:46:40 -07:00
|
|
|
typedef struct Sema Sema;
|
|
|
|
typedef struct Timer Timer;
|
|
|
|
typedef struct Timers Timers;
|
|
|
|
typedef struct Uart Uart;
|
|
|
|
typedef struct Waitq Waitq;
|
|
|
|
typedef struct Walkqid Walkqid;
|
2017-06-12 12:03:07 -07:00
|
|
|
typedef struct Watchpt Watchpt;
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
2015-06-15 07:05:00 -07:00
|
|
|
struct Rendezq
|
|
|
|
{
|
|
|
|
QLock;
|
|
|
|
Rendez;
|
|
|
|
};
|
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
struct RWlock
|
|
|
|
{
|
|
|
|
Lock use;
|
|
|
|
Proc *head; /* list of waiting processes */
|
|
|
|
Proc *tail;
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr wpc; /* pc of writer */
|
2011-03-30 05:46:40 -07:00
|
|
|
Proc *wproc; /* writing proc */
|
|
|
|
int readers; /* number of readers */
|
|
|
|
int writer; /* number of writers */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Alarms
|
|
|
|
{
|
|
|
|
QLock;
|
|
|
|
Proc *head;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Sargs
|
|
|
|
{
|
2014-01-19 15:47:55 -08:00
|
|
|
uchar args[MAXSYSARG*BY2WD];
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 */
|
kernel: implement per file descriptor OCEXEC flag, reject ORCLOSE when opening /fd, /srv and /shr
The OCEXEC flag used to be maintained per channel,
making it shared between all the file desciptors.
This has a unexpected side effects with regard to
channel passing drivers such as devdup (/fd),
devsrv (/srv) and devshr (/shr).
For example, opening a /srv file with OCEXEC
makes it impossible to be remounted by exportfs
as it internally does a exec() to mount and
re-export it. There is no way to reset the flag.
This change makes the OCEXEC flag per file descriptor,
so a open with the OCEXEC flag only affects the fd
group of the calling process, and not the channel
itself.
On rfork(RFFDG), the per file descriptor flags get
copied.
On dup(), the per file descriptor flags are reset.
The second modification is that /fd, /srv and /shr
should reject the ORCLOSE flag, as the files that
are returned have already been opend.
2020-12-13 07:04:09 -08:00
|
|
|
CCEXEC = 0x0008, /* close on exec (per file descriptor) */
|
2011-03-30 05:46:40 -07:00
|
|
|
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
|
|
|
|
{
|
2014-06-22 06:12:45 -07:00
|
|
|
Ref;
|
|
|
|
Lock;
|
2011-03-30 05:46:40 -07:00
|
|
|
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);
|
2011-08-17 14:27:31 -07:00
|
|
|
Chan* (*create)(Chan*, char*, int, ulong);
|
2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2015-08-09 12:35:50 -07:00
|
|
|
int mflag;
|
2011-03-30 05:46:40 -07:00
|
|
|
Mount* next;
|
|
|
|
Mount* order;
|
|
|
|
Chan* to; /* channel replacing channel */
|
2015-08-09 12:35:50 -07:00
|
|
|
char* spec;
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Mhead
|
|
|
|
{
|
|
|
|
Ref;
|
|
|
|
RWlock lock;
|
|
|
|
Chan* from; /* channel mounted upon */
|
|
|
|
Mount* mount; /* what's mounted upon it */
|
|
|
|
Mhead* hash; /* Hash chain */
|
|
|
|
};
|
|
|
|
|
2015-07-25 20:43:26 -07:00
|
|
|
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*);
|
|
|
|
};
|
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
2015-07-25 20:43:26 -07:00
|
|
|
Mntproc defered[8]; /* Worker processes for defered RPCs (read ahead) */
|
2011-03-30 05:46:40 -07:00
|
|
|
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
|
|
|
|
{
|
2014-06-22 06:12:45 -07:00
|
|
|
Ref;
|
|
|
|
Page *next; /* Free list or Hash chains */
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr pa; /* Physical address in memory */
|
|
|
|
uintptr va; /* Virtual address for user */
|
|
|
|
uintptr daddr; /* Disc address on swap */
|
2014-06-22 06:12:45 -07:00
|
|
|
Image *image; /* Associated text or swap image */
|
2015-02-06 17:52:23 -08:00
|
|
|
ulong txtflush; /* Flush icache for putmmu */
|
2014-06-22 06:12:45 -07:00
|
|
|
ushort refage; /* Swap reference age */
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
2012-10-15 05:04:30 -07:00
|
|
|
ulong xref; /* Ref count for all map refs >= 255 */
|
2011-03-30 05:46:40 -07:00
|
|
|
}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,
|
2015-04-12 13:30:30 -07:00
|
|
|
SG_FIXED = 06,
|
2017-06-20 12:53:45 -07:00
|
|
|
SG_STICKY = 07,
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
SG_RONLY = 0040, /* Segment is read only */
|
|
|
|
SG_CEXEC = 0100, /* Detach at exec */
|
2016-03-27 11:57:01 -07:00
|
|
|
SG_FAULT = 0200, /* Fault on access */
|
2019-08-26 13:34:38 -07:00
|
|
|
SG_CACHED = 0400, /* Normal cached memory */
|
|
|
|
SG_DEVICE = 01000, /* Memory mapped device */
|
|
|
|
SG_NOEXEC = 02000, /* No execute */
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
#define PG_ONSWAP 1
|
2014-01-19 15:47:55 -08:00
|
|
|
#define onswap(s) (((uintptr)s)&PG_ONSWAP)
|
|
|
|
#define pagedout(s) (((uintptr)s)==0 || onswap(s))
|
|
|
|
#define swapaddr(s) (((uintptr)s)&~PG_ONSWAP)
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
#define SEGMAXSIZE (SEGMAPSIZE*PTEMAPMEM)
|
|
|
|
|
|
|
|
struct Physseg
|
|
|
|
{
|
2016-03-30 13:49:13 -07:00
|
|
|
int attr; /* Segment attributes */
|
2011-03-30 05:46:40 -07:00
|
|
|
char *name; /* Attach name */
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr pa; /* Physical address */
|
2014-03-04 13:37:15 -08:00
|
|
|
uintptr size; /* Maximum segment size in bytes */
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
struct Sema
|
|
|
|
{
|
|
|
|
Rendez;
|
|
|
|
long *addr;
|
|
|
|
int waiting;
|
|
|
|
Sema *next;
|
|
|
|
Sema *prev;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Segment
|
|
|
|
{
|
|
|
|
Ref;
|
2014-06-22 06:12:45 -07:00
|
|
|
QLock;
|
2014-07-13 21:02:21 -07:00
|
|
|
int type; /* segment type */
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr base; /* virtual base */
|
|
|
|
uintptr top; /* virtual top */
|
2011-03-30 05:46:40 -07:00
|
|
|
ulong size; /* size in pages */
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr fstart; /* start address in file for demand load */
|
|
|
|
uintptr flen; /* length of segment in file */
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
2015-04-15 15:45:25 -07:00
|
|
|
struct Segio
|
|
|
|
{
|
|
|
|
QLock;
|
|
|
|
Rendez cmdwait;
|
|
|
|
Rendez replywait;
|
|
|
|
|
|
|
|
Proc *p; /* segmentio kproc */
|
|
|
|
Segment *s;
|
|
|
|
|
|
|
|
char *data;
|
|
|
|
char *addr;
|
|
|
|
int dlen;
|
|
|
|
int cmd;
|
2015-04-15 16:20:30 -07:00
|
|
|
char *err;
|
2015-04-15 15:45:25 -07:00
|
|
|
};
|
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
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)])
|
2014-06-22 06:12:45 -07:00
|
|
|
#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 */
|
|
|
|
};
|
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
struct Pgrp
|
|
|
|
{
|
2014-06-22 06:12:45 -07:00
|
|
|
Ref;
|
2015-08-09 09:19:47 -07:00
|
|
|
RWlock ns; /* Namespace n read/one write lock */
|
2011-03-30 05:46:40 -07:00
|
|
|
int noattach;
|
|
|
|
Mhead *mnthash[MNTHASH];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Rgrp
|
|
|
|
{
|
2014-06-22 06:12:45 -07:00
|
|
|
Ref;
|
|
|
|
Lock;
|
2011-03-30 05:46:40 -07:00
|
|
|
Proc *rendhash[RENDHASH]; /* Rendezvous tag hash */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Egrp
|
|
|
|
{
|
|
|
|
Ref;
|
|
|
|
RWlock;
|
2015-08-02 12:39:33 -07:00
|
|
|
Evalue *ent;
|
2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2014-06-22 06:12:45 -07:00
|
|
|
Lock;
|
2011-03-30 05:46:40 -07:00
|
|
|
Chan **fd;
|
kernel: implement per file descriptor OCEXEC flag, reject ORCLOSE when opening /fd, /srv and /shr
The OCEXEC flag used to be maintained per channel,
making it shared between all the file desciptors.
This has a unexpected side effects with regard to
channel passing drivers such as devdup (/fd),
devsrv (/srv) and devshr (/shr).
For example, opening a /srv file with OCEXEC
makes it impossible to be remounted by exportfs
as it internally does a exec() to mount and
re-export it. There is no way to reset the flag.
This change makes the OCEXEC flag per file descriptor,
so a open with the OCEXEC flag only affects the fd
group of the calling process, and not the channel
itself.
On rfork(RFFDG), the per file descriptor flags get
copied.
On dup(), the per file descriptor flags are reset.
The second modification is that /fd, /srv and /shr
should reject the ORCLOSE flag, as the files that
are returned have already been opend.
2020-12-13 07:04:09 -08:00
|
|
|
uchar *flag; /* per file-descriptor flags (CCEXEC) */
|
2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2014-06-22 06:12:45 -07:00
|
|
|
Page *head; /* freelist head */
|
2011-03-30 05:46:40 -07:00
|
|
|
ulong freecount; /* how many pages on free list now */
|
|
|
|
Page *pages; /* array of all pages */
|
|
|
|
ulong user; /* how many user pages */
|
2015-06-15 07:05:00 -07:00
|
|
|
Rendezq pwait[2]; /* Queues of procs waiting for memory */
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2017-03-28 15:30:53 -07:00
|
|
|
Mach *tactive; /* The cpu that tf is active on */
|
2011-03-30 05:46:40 -07:00
|
|
|
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;
|
2020-02-23 09:00:21 -08:00
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
char *args;
|
|
|
|
int nargs; /* number of bytes of args */
|
2015-08-09 12:48:58 -07:00
|
|
|
int setargs; /* process changed its args */
|
2020-02-23 09:00:21 -08:00
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
Proc *rnext; /* next process in run queue */
|
|
|
|
Proc *qnext; /* next process on queue for a QLock */
|
2020-02-23 09:00:21 -08:00
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
char *psstate; /* What /proc/#/status reports */
|
2020-02-23 09:00:21 -08:00
|
|
|
int state;
|
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
ulong pid;
|
|
|
|
ulong noteid; /* Equivalent of note group */
|
2020-01-26 10:01:36 -08:00
|
|
|
ulong parentpid;
|
2011-03-30 05:46:40 -07:00
|
|
|
|
2020-02-23 09:00:21 -08:00
|
|
|
Proc *parent; /* Process to send wait record on exit */
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
2020-02-23 09:00:21 -08:00
|
|
|
|
|
|
|
QLock seglock; /* locked whenever seg[] changes */
|
|
|
|
Segment *seg[NSEG];
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
Pgrp *pgrp; /* Process group for namespace */
|
|
|
|
Egrp *egrp; /* Environment group */
|
|
|
|
Fgrp *fgrp; /* File descriptor group */
|
|
|
|
Rgrp *rgrp; /* Rendez group */
|
|
|
|
|
|
|
|
Fgrp *closingfgrp; /* used during teardown */
|
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 12:08:22 -07:00
|
|
|
int insyscall;
|
2011-03-30 05:46:40 -07:00
|
|
|
ulong time[6]; /* User, Sys, Real; child U, S, R */
|
|
|
|
|
|
|
|
uvlong kentry; /* Kernel entry time stamp (for profiling) */
|
|
|
|
/*
|
2020-12-20 13:34:41 -08:00
|
|
|
* pcycles: cycles spent in this process (updated on procswitch)
|
2011-03-30 05:46:40 -07:00
|
|
|
* 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 */
|
2014-08-16 15:50:20 -07:00
|
|
|
int privatemem; /* proc does not let anyone read mem */
|
2020-01-26 10:01:36 -08:00
|
|
|
int noswap; /* process is not swappable */
|
2011-03-30 05:46:40 -07:00
|
|
|
int hang; /* hang at next exec for debug */
|
|
|
|
int procctl; /* Control for /proc debugging */
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr pc; /* DEBUG only */
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 12:08:22 -07:00
|
|
|
Sargs s; /* syscall arguments */
|
2020-01-26 10:01:36 -08:00
|
|
|
int scallnr; /* sys call number */
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
2014-06-05 12:54:32 -07:00
|
|
|
int nlocks; /* number of locks held by proc */
|
2011-03-30 05:46:40 -07:00
|
|
|
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? */
|
|
|
|
|
2014-01-19 15:47:55 -08:00
|
|
|
uintptr qpc; /* pc calling last blocking qlock */
|
2011-08-11 14:02:48 -07:00
|
|
|
QLock *eql; /* interruptable eqlock */
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
void *ureg; /* User registers for notes */
|
|
|
|
void *dbgreg; /* User registers for devproc */
|
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 12:08:22 -07:00
|
|
|
PFPU; /* machine specific fpu state */
|
|
|
|
PMMU; /* machine specific mmu state */
|
2015-07-18 18:31:17 -07:00
|
|
|
|
2011-03-30 05:46:40 -07:00
|
|
|
char *syscalltrace; /* syscall trace */
|
2017-06-12 12:03:07 -07:00
|
|
|
|
kernel: introduce per process FPU struct (PFPU) for more flexible machine specific fpu handling
introducing the PFPU structue which allows the machine specific
code some flexibility on how to handle the FPU process state.
for example, in the pc and pc64 kernel, the FPsave structure is
arround 512 bytes. with avx512, it could grow up to 2K. instead
of embedding that into the Proc strucutre, it is more effective
to allocate it on first use of the fpu, as most processes do not
use simd or floating point in the first place. also, the FPsave
structure has special 16 byte alignment constraint, which further
favours dynamic allocation.
this gets rid of the memmoves in pc/pc64 kernels for the aligment.
there is also devproc, which is now checking if the fpsave area
is actually valid before reading it, avoiding debuggers to see
garbage data.
the Notsave structure is gone now, as it was not used on any
machine.
2017-11-04 12:08:22 -07:00
|
|
|
Watchpt *watchpt; /* watchpoints */
|
|
|
|
int nwatchpt;
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
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 */
|
2017-08-10 16:32:24 -07:00
|
|
|
READSTR = 8000, /* temporary buffer size for device reads */
|
2011-03-30 05:46:40 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2014-06-22 06:12:45 -07:00
|
|
|
extern Image fscache;
|
2011-03-30 05:46:40 -07:00
|
|
|
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 */
|
|
|
|
};
|
|
|
|
|
2017-06-12 12:03:07 -07:00
|
|
|
struct Watchpt
|
|
|
|
{
|
|
|
|
enum {
|
|
|
|
WATCHRD = 1,
|
|
|
|
WATCHWR = 2,
|
|
|
|
WATCHEX = 4,
|
|
|
|
} type;
|
|
|
|
uintptr addr, len;
|
|
|
|
};
|
|
|
|
|
2021-04-25 08:41:34 -07:00
|
|
|
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 */
|
|
|
|
};
|
2011-03-30 05:46:40 -07:00
|
|
|
|
|
|
|
/* 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*
|
2017-11-25 19:49:30 -08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* 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;
|