~kris/9p

9hist

4d55f1cdece7317e730b9e8fdf816e0cf9cbeb5a — David du Colombier 32 years ago 28de246
Plan 9 from Bell Labs 1993-10-13
M carrera/dat.h => carrera/dat.h +10 -0
@@ 7,6 7,7 @@ typedef struct Label	Label;
typedef struct Lock	Lock;
typedef struct Mach	Mach;
typedef struct MMU	MMU;
typedef struct Notsave	Notsave;
typedef struct PMMU	PMMU;
typedef struct Softtlb	Softtlb;
typedef struct Ureg	Ureg;


@@ 78,6 79,15 @@ struct PMMU
	int	pidonmach[MAXMACH];
};

/*
 *  things saved in the Proc structure during a notify
 */
struct Notsave
{
	ulong	svstatus;
	ulong	svr1;
};

#include "../port/portdat.h"

/* First FOUR members offsets known by l.s */

M carrera/fns.h => carrera/fns.h +1 -1
@@ 43,7 43,7 @@ void	ioinit(int);
int	iprint(char*, ...);
int	kbdinit(void);
int	kbdintr(void);
void	kfault(ulong);
void	kfault(Ureg*);
KMap*	kmap(Page*);
void	kmapinit(void);
void	kmapinval(void);

M carrera/mmu.c => carrera/mmu.c +4 -1
@@ 4,6 4,7 @@
#include	"dat.h"
#include	"fns.h"
#include	"io.h"
#include	"ureg.h"

/*
 *  tlb entry 0 is used only by mmuswitch() to set the current tlb pid.


@@ 141,11 142,13 @@ kunmap(KMap *k)
}

void
kfault(ulong addr)
kfault(Ureg *ur)
{
	KMap *k, *f;
	ulong x, index, virt;
	ulong addr;

	addr = ur->badvaddr;
	index = (addr & ~KMAPADDR) >> KMAPSHIFT;
	if(index >= KPTESIZE)
		panic("kmapfault: %lux", addr);

M carrera/trap.c => carrera/trap.c +1 -1
@@ 205,7 205,7 @@ trap(Ureg *ur)
			kernfault(ur, ecode);

		if(!user && (ur->badvaddr & KMAPMASK) == KMAPADDR) {
			kfault(ur->badvaddr);
			kfault(ur);
			break;
		}


M pc/dat.h => pc/dat.h +12 -0
@@ 5,6 5,7 @@ typedef struct Label	Label;
typedef struct Lock	Lock;
typedef struct MMU	MMU;
typedef struct Mach	Mach;
typedef struct Notsave	Notsave;
typedef struct PCArch	PCArch;
typedef struct Page	Page;
typedef struct PMMU	PMMU;


@@ 96,6 97,16 @@ struct PMMU
	Page	*mmuused;	/* used page table pages */
};

/*
 *  things saved in the Proc structure during a notify
 */
struct Notsave
{
	ulong	svflags;
	ulong	svcs;
	ulong	svss;
};

#include "../port/portdat.h"

/*


@@ 177,6 188,7 @@ struct ISAConf {

extern int	flipD[];		/* for flipping bitblt destination polarity */
extern PCArch	*arch;			/* PC architecture */
extern int	cpuflag;		/* true if this is a CPU */

extern Mach	*m;
extern Proc	*up;

M pc/main.c => pc/main.c +12 -7
@@ 95,15 95,21 @@ machinit(void)
ulong garbage;

void
ksetterm(char *f)
{
	char buf[2*NAMELEN];

	sprint(buf, f, conffile);
	ksetenv("terminal", buf);
}

void
init0(void)
{
	int i;
	char tstr[32];

	up->nerrlab = 0;
	m->proc = up->p;
	up->state = Running;
	up->mach = m;

	spllo();



@@ 136,7 142,6 @@ userinit(void)
{
	Proc *p;
	Segment *s;
	User *up;
	KMap *k;
	Page *pg;



@@ 434,12 439,12 @@ matherror(Ureg *ur)
		if((1<<i) & status){
			msg = mathmsg[i];
			sprint(note, "sys: fp: %s fppc=0x%lux", msg, up->fpsave.pc);
			postnote(up->p, 1, note, NDebug);
			postnote(up, 1, note, NDebug);
			break;
		}
	if(msg == 0){
		sprint(note, "sys: fp: unknown fppc=0x%lux", up->fpsave.pc);
		postnote(up->p, 1, note, NDebug);
		postnote(up, 1, note, NDebug);
	}
	if(ur->pc & KZERO)
		panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,


@@ 534,7 539,7 @@ procrestore(Proc *p)
void
exit(int ispanic)
{
	u = 0;
	up = 0;
	print("exiting\n");
	if(ispanic){
		if(cpuflag)

M pc/mem.h => pc/mem.h +2 -0
@@ 117,3 117,5 @@
 *  flag register bits that we care about
 */
#define IFLAG	0x200

#define getpgcolor(a)	0

M pc/mmu.c => pc/mmu.c +5 -5
@@ 165,7 165,7 @@ mmuinit(void)
	 *  set up the task segment
	 */
	memset(&tss, 0, sizeof(tss));
	taskswitch(ktoppg.pa, BY2BG + (ulong)m);
	taskswitch(ktoppg.pa, BY2PG + (ulong)m);
	puttr(TSSSEL);
}



@@ 218,9 218,9 @@ mmuswitch(Proc *p)

	/* tell processor about new page table (flushes cached entries) */
	if(p->mmutop)
		taskswitch(p->mmutop->pa, p->kstack+KSTACK);
		taskswitch(p->mmutop->pa, (ulong)(p->kstack+KSTACK));
	else
		taskswitch(ktoppg.pa, p->kstack+KSTACK);
		taskswitch(ktoppg.pa, (ulong)(p->kstack+KSTACK));
}

/*


@@ 273,7 273,7 @@ putmmu(ulong va, ulong pa, Page *pg)
		memmove((void*)pg->va, (void*)ktoppg.va, BY2PG);
		up->mmutop = pg;
	}
	top = (ulong*)up->mmutoup->va;
	top = (ulong*)up->mmutop->va;
	topoff = TOPOFF(va);

	/*


@@ 305,7 305,7 @@ putmmu(ulong va, ulong pa, Page *pg)
	pt[BTMOFF(va)] = pa | PTEUSER;

	/* flush cached mmu entries */
	taskswitch(up->mmutoup->pa, up->kstack);
	taskswitch(up->mmutop->pa, (ulong)up->kstack);
	splx(s);
}


M pc/trap.c => pc/trap.c +15 -12
@@ 103,7 103,7 @@ debugbpt(Ureg *ur)
	/* restore pc to instruction that caused the trap */
	ur->pc--;
	sprint(buf, "sys: breakpoint");
	postnote(up->p, 1, buf, NDebug);
	postnote(up, 1, buf, NDebug);
}

/*


@@ 261,7 261,7 @@ lastur = ur;
		if(v <= 16){
			if(user){
				sprint(buf, "sys: trap: %s", excname[v]);
				postnote(up->p, 1, buf, NDebug);
				postnote(up, 1, buf, NDebug);
				return;
			} else {
				dumpregs(ur);


@@ 308,10 308,7 @@ dumpregs2(Ureg *ur)
		print("registers for kernel\n");
	print("FLAGS=%lux TRAP=%lux ECODE=%lux CS=%lux PC=%lux", ur->flags, ur->trap,
		ur->ecode, ur->cs&0xff, ur->pc);
	if(ur == (Ureg*)UREGADDR)
		print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
	else
		print("\n");
	print(" SS=%lux USP=%lux\n", ur->ss&0xff, ur->usp);
	print("  AX %8.8lux  BX %8.8lux  CX %8.8lux  DX %8.8lux\n",
		ur->ax, ur->bx, ur->cx, ur->dx);
	print("  SI %8.8lux  DI %8.8lux  BP %8.8lux\n",


@@ 340,7 337,7 @@ dumpstack(void)
		return;

	i = 0;
	for(l=(ulong)&l; l<up->kstack+BY2PG; l+=4){
	for(l=(ulong)&l; l<(ulong)(up->kstack+BY2PG); l+=4){
		v = *(ulong*)l;
		if(KTZERO < v && v < (ulong)&etext){
			print("%lux ", v);


@@ 358,18 355,24 @@ long
execregs(ulong entry, ulong ssize, ulong nargs)
{
	ulong *sp;
	Ureg *ur;

	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;
	((Ureg*)UREGADDR)->usp = (ulong)sp;
	((Ureg*)UREGADDR)->pc = entry;

	ur = up->dbgreg;
	ur->usp = (ulong)sp;
	ur->pc = entry;
	return USTKTOP-BY2WD;			/* address of user-level clock */
}

ulong
userpc(void)
{
	return ((Ureg*)UREGADDR)->pc;
	Ureg *ur;

	ur = (Ureg*)up->dbgreg;
	return ur->pc;
}

/*


@@ 411,7 414,7 @@ syscall(Ureg *ur)
	if(!waserror()){
		if(up->scallnr >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", up->scallnr, ur->pc);
			postnote(up->p, 1, "sys: bad sys call", NDebug);
			postnote(up, 1, "sys: bad sys call", NDebug);
			error(Ebadarg);
		}



@@ 464,7 467,7 @@ notify(Ureg *ur)
	Note *n;

	if(up->procctl)
		procctl(up->p);
		procctl(up);
	if(up->nnote == 0)
		return 0;


M port/cache.c => port/cache.c +256 -13
@@ 6,26 6,269 @@
#include	"../port/error.h"
#include	"devtab.h"

typedef struct Fcache Fcache;
typedef struct Fcalloc Fcalloc;
struct Fcache
Image	fscache;

typedef Extent Extent;
struct Extent
{
	int	bid;
	ulong	start;
	int	len;
	Extent	*next;
};

typedef struct Mntcache Mntcache;
struct Mntcache
{
	QLock;
	Qid;
	Page*	alloc;
	Fcache*	hash;
	Fcache*	next;
	int	dev;
	int	type;
	Qlock;
	Extent	 *list;
	Mntcache *hash;
	Mntcache *prev;
	Mntcache *next;
};

struct Fcalloc
typedef struct Cache Cache;
struct Cache
{
	ulong	start;
	short	len;
	Page*	data;
	Ref;
	Mntcache	*head;
	Mntcache	*tail;
	Mntcache	*hash[NHASH];
};
Cache cache;

Mntcache*
clook(Chan *c)
{
	int h;

	h = c->qid.path%NHASH;

	lock(&cache);
	for(m = cache.hash[h]; m; m = m->hash) {
		if(m->path == c->path) {
			qlock(m);
			if(m->path == c->qid.path)
			if(m->dev  == c->dev)
			if(m->type == c->type) {
				unlock(&cache);
				return m;
			}
			qunlock(m);
		}
	}
	unlock(&cache);
	return 0;
}

Fcache*
clook(Qid *qid)
void
cnodata(Mntcache *m)
{
	Extent *e, *n;

	/*
	 * Invalidate all extent data
	 * Image lru will waste the pages
	 */
	for(e = m->list; e; e = n) {
		n = e->list;
		free(e);
	}
}

void
ctail(Mntcache *m)
{
	lock(&cache);

	/* Unlink and send to the tail */
	if(m->prev) 
		m->prev->next = m->next;
	else
		cache.head = m->next;
	if(m->next)
		m->next->prev = m->prev;
	else
		cache.tail = m->prev;

	if(cache.tail) {
		m->prev = cache.tail;
		cache.tail->next = m;
		m->next = 0;
		cache.tail = m;
	}
	else {
		cache.head = cache.tail = m;
		m->prev = m->next = 0;
	}

	unlock(&cache);
}

void
copen(Chan *c)
{
	Mntcache *m, *f, **l;

	m = clook(c);
	if(m != 0) {
		/* File was updated */
		if(m->vers != c->vers)
			cnodata(m);

		ctail(m);
		qunlock(m);
		return;
	}

	/* LRU the cache headers */
	m = cache.head;
	qlock(m);
	lock(cache);
	l = &cache.hash[m->qid.path%NHASH];
	for(f = *l; f; f = f->next) {
		if(f == m) {
			*l = f->next;
			break;
		}
		l = &f->next;
	}
	l = &cache.hash[c->qid.path%NHASH];
	m->hash = *l;
	*l = m;
	unlock(cache);
	m->qid = c->qid;
	m->dev = c->dev;
	m->type = c->type;
	cnodata(m);
	ctail(m);
	c->mcp = m;
	qunlock(m);
}

static int
cdev(Mntcache *m, Chan *c)
{
	if(m->path != c->path)
		return 0;
	if(m->vers != c->vers)
		return 0;
	if(m->dev != c->dev)
		return 0;
	if(m->type != c->type)
		return 0;
	return 1;
}

int
cread(Chan *c, uchar *buf, int len, long offset)
{
	KMap *k;
	Page *p;
	Mntcache *m;
	Extent *e, **l;
	int o, l, total;

	m = c->mcp;
	if(m == 0)
		return 0;
	qlock(m);
	if(cdev(m, c) == 0) {
		qunlock(m);
		return 0;
	}

	end = offset+len;
	l = &m->list;
	for(e = *l; e; e = e->next) {
		if(e->start >= offset && e->start+e->len < end)
			break;
		l = &e->next;
	}

	if(e == 0) {
		qunlock(m);
		return 0;
	}

	total = 0;
	while(len) {
		p = lookpage(&fscache, e->bid);
		if(p == 0) {
			*l = e->next;
			free(e);
			qunlock(m);
			return total;
		}

		k = kmap(p);
		if(waserror()) {
			kunmap(k);
			putpage(p);
			qunlock(m);
			nexterror();
		}

		o = offset - e->start;
		l = len;
		if(l > e->len-o)
			l = e->len-o;

		p = (uchar*)VA(k) + o;
		memset(buf, p, l);
		kunmap(k);
		putpage(p);

		buf += l;
		len -= l;
		offset += l;
		total += l;
		l = &e->next;
		e = e->next;
		if(e == 0 || e->start != offset)
			break;
	}
	qunlock(m)
	return total;
}

void
cwrite(Chan *c, uchar *buf, int len, long offset)
{
	Extent *e;
	Mntcache *m;

	if(offset > MAXCACHE)
		return;

	m = c->mcp;
	if(m == 0)
		return;
	qlock(m);
	if(cdev(m, c) == 0) {
		qunlock(m);
		return;
	}

	if(m->list == 0) {
		e = malloc(sizeof(Extent));
		if(e == 0)
			return;
		e->start = offset;
		l = len;
		if(l > BY2PG)
			l = BY2PG;
		p = auxpage();
		if(p == 0)
			return;
		e->bid = incref(&cache);
		p->daddr = e->bid;
		cachepage(p, fscache);
		k = kmap(p);
		
		kunmap(p);
	}
}

M port/chan.c => port/chan.c +1 -0
@@ 99,6 99,7 @@ newchan(void)
	c->aux = 0;
	c->mchan = 0;
	c->path = 0;
	c->mcp = 0;
	c->mqid = (Qid){0, 0};
	return c;
}

M port/dev.c => port/dev.c +1 -0
@@ 98,6 98,7 @@ devclone(Chan *c, Chan *nc)
	nc->aux = c->aux;
	nc->mchan = c->mchan;
	nc->mqid = c->mqid;
	nc->mcp = c->mcp;
	nc->path = c->path;
	incref(nc->path);
	return nc;

M port/devproc.c => port/devproc.c +2 -2
@@ 243,7 243,6 @@ procwstat(Chan *c, char *db)
	if(c->qid.path&CHDIR)
		error(Eperm);

	convM2D(db, &d);
	p = proctab(SLOT(c->qid));
	if(p->pid != PID(c->qid))
		error(Eprocdied);


@@ 251,13 250,14 @@ procwstat(Chan *c, char *db)
	if(strcmp(up->user, p->user) != 0 && strcmp(up->user, eve) != 0)
		error(Eperm);

	convM2D(db, &d);
	p->procmode = d.mode&0777;
}

void
procclose(Chan * c)
{
	if(QID(c->qid) == Qns)
	if(QID(c->qid) == Qns && c->aux != 0)
		free(c->aux);
}


M port/portdat.h => port/portdat.h +3 -2
@@ 11,6 11,7 @@ typedef struct Image	Image;
typedef struct IOQ	IOQ;
typedef struct KIOQ	KIOQ;
typedef struct List	List;
typedef struct Mntcache Mntcache;
typedef struct Mount	Mount;
typedef struct Mntrpc	Mntrpc;
typedef struct Mntwalk	Mntwalk;


@@ 135,6 136,7 @@ struct Chan
	Mount	*mnt;			/* mount point that derived Chan */
	Mount	*xmnt;			/* Last mount point crossed */
	ulong	mountid;
	Mntcache *mcp;			/* Mount cache pointer */
	union {
		void	*aux;
		Qid	pgrpid;		/* for #p/notepg */


@@ 597,8 599,7 @@ struct Proc

	void	*ureg;		/* User registers for notes */
	void	*dbgreg;	/* User registers for devproc */
	ulong	svstatus;
	ulong	svr1;
	Notsave;

	/*
	 *  machine specific MMU