~kris/9p

9hist

199caac4a5a50eec65c2ed0244db029bf359a26b — David du Colombier 35 years ago f6a37fb
Plan 9 from Bell Labs 1991-08-08
M pc/clock.c => pc/clock.c +46 -6
@@ 21,6 21,7 @@ enum
					 *  period is the counter period
					 */
	Freq=		1193182,	/* Real clock frequency */
	FHZ=		1000,		/* hertz for fast clock */
};

/*


@@ 60,14 61,12 @@ clock(Ureg *ur)

	m->ticks++;

	uartintr0(ur);

	if(m->ticks % 50)
		return;

	checkalarms();
	mouseclock();

	/*
	 *  process time accounting
	 */
	p = m->proc;
	if(p){
		p->pc = ur->pc;


@@ 76,15 75,56 @@ clock(Ureg *ur)
	}

	if(u && p && p->state==Running){
		/*
		 *  preemption
		 */
		if(anyready()){
			if(p->hasspin)
				p->hasspin = 0;
			else
				sched();
		}
		if((ur->cs&0xffff) == UESEL){ /* if was in user mode */
		/*
		 *  notes for processes that might be spinning
		 *  in user mode.
		 */
		if((ur->cs&0xffff) == UESEL){
			if(u->nnote)
				notify(ur);
		}
	}
}

/*
 *  a faster (1 MS) clock tick for a non-interrupting serial port or
 *  kernel profiling.  m->ticks still increments as usual.
 */
void
fclock(Ureg *ur)
{
	static ulong ticks;

	uartintr0(ur);		/* poll the serial port */
	if((ticks++ % (FHZ/HZ)) == 0)
		clock(ur);
}

void
fclockinit(void)
{
	int x;

	/*
	 *  set vector for clock interrupts
	 */
	setvec(Clockvec, fclock);

	/*
	 *  make clock output a square wave with a 1/FHZ period
	 */
	x = splhi();
	outb(Tmode, Load0square);
	outb(T0cntr, (Freq/FHZ));	/* low byte */
	outb(T0cntr, (Freq/FHZ)>>8);	/* high byte */
	splx(x);
}

M pc/devuart.c => pc/devuart.c +53 -52
@@ 1,4 1,4 @@
#include	"u.h"

#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"


@@ 18,9 18,8 @@ enum
	 */
	Data=	0,		/* xmit/rcv buffer */
	Iena=	1,		/* interrupt enable */
	 Ircv=	(1<<0),		/*  interrupt on receive */
	 Ixmt=	(1<<1),		/*  interrupt on xmit */
	Istat=	2,		/* interrupt flag */
	Istat=	2,		/* interrupt flag (read) */
	Tctl=	2,		/* test control (write) */
	Format=	3,		/* byte format */
	 Bits8=	(3<<0),		/*  8 bits/byte */
	 Stop2=	(1<<2),		/*  2 stop bits */


@@ 42,6 41,9 @@ enum
	Scratch=7,		/* scratchpad */
	Dlsb=	0,		/* divisor lsb */
	Dmsb=	1,		/* divisor msb */

	Serial=	0,
	Modem=	1,
};

typedef struct Uart	Uart;


@@ 62,7 64,6 @@ struct Uart
	Queue	*wq;		/* write queue */
	Rendez	r;		/* kproc waiting for input */
	Alarm	*a;		/* alarm for waking the kernel process */
	int	delay;		/* between character input and waking kproc */
 	int	kstarted;	/* kproc started */
	uchar	delim[256/8];	/* characters that act as delimiters */
};


@@ 248,7 249,8 @@ uartintr0(Ureg *ur)
void
uartintr1(Ureg *ur)
{
	uartintr(&uart[1]);
	if(uart[1].enabled)
		uartintr(&uart[1]);
}

/*


@@ 262,36 264,42 @@ uartenable(Uart *up)
	/*
	 *  turn on power to the port
	 */
	if(up == &uart[0]){
	if(up == &uart[Serial]){
		if(serial(0) < 0)
			print("can't turn on serial port power\n");
	}

	/*
	 *  speed up the clock to poll the uart
	 */
	fclockinit();

	/*
	 *  set up i/o routines
	 */
	if(up->oq){
		up->oq->puts = uartputs;
		up->oq->ptr = up;
		up->sticky[Iena] |= Ixmt;
	}
	if(up->iq){
		up->iq->ptr = up;
		up->sticky[Iena] |= Ircv;
	}
	up->enabled = 1;
	up->sticky[Iena] |= (1<<2) | (1<<3);
	up->sticky[Iena] = 0xf;

	/*
 	 *  turn on interrupts
	 */
	uartwrreg(up, Iena, 0);
	uartwrreg(up, Tctl, 0x0);

	/*
	 *  turn on DTR and RTS
	 */
	uartdtr(up, 1);
	uartrts(up, 1);

print("uart enabled: Iena=%lux\n", uartrdreg(up, Iena));
}

/*


@@ 316,10 324,15 @@ uartdisable(Uart *up)
	/*
	 *  turn off power
	 */
	if(up == &uart[0]){
	if(up == &uart[Serial]){
		if(serial(1) < 0)
			print("can't turn off serial power\n");
	}

	/*
	 *  slow the clock down again
	 */
	clockinit();
}

/*


@@ 374,25 387,6 @@ uarttimer(Alarm *a)
	wakeup(&up->iq->r);
}

static int
uartputc(IOQ *cq, int ch)
{
	Uart *up = cq->ptr; int r;

	r = putc(cq, ch);

	/*
	 *  pass upstream within up->delay milliseconds
	 */
	if(up->a==0){
		if(up->delay == 0)
			wakeup(&cq->r);
		else
			up->a = alarm(up->delay, uarttimer, up);
	}
	return r;
}

static void
uartstopen(Queue *q, Stream *s)
{


@@ 403,18 397,17 @@ print("uartstopen: q=0x%ux, inuse=%d, type=%d, dev=%d, id=%d\n",
		q, s->inuse, s->type, s->dev, s->id);

	up = &uart[s->id];
	up->iq->putc = 0;
	uartenable(up);

	qlock(up);
	up->wq = WR(q);
	WR(q)->ptr = up;
	RD(q)->ptr = up;
	up->delay = 64;
	up->iq->putc = uartputc;
	qunlock(up);

	/* start with all characters as delimiters */
	memset(up->delim, 1, sizeof(up->delim));
	memset(up->delim, 0xff, sizeof(up->delim));
	
	if(up->kstarted == 0){
		up->kstarted = 1;


@@ 468,6 461,18 @@ uartoput(Queue *q, Block *bp)
		case 'd':
			uartdtr(up, n);
			break;
		case 'e':
		case 'E':
			/*
			 *  the characters in the block are the message
			 *  delimiters to use upstream
			 */
			memset(up->delim, 0, sizeof(up->delim));
			while(++(bp->rptr) < bp->wptr){
				m = *bp->rptr;
				up->delim[m/8] |= 1<<(m&7);
			}
			break;
		case 'K':
		case 'k':
			uartbreak(up, n);


@@ 476,15 481,9 @@ uartoput(Queue *q, Block *bp)
		case 'r':
			uartrts(up, n);
			break;
		case 'W':
		case 'w':
			if(n>=0 && n<1000)
				up->delay = n;
			break;
		}
	}else while((m = BLEN(bp)) > 0){
		while ((n = canputc(cq)) == 0){
print("uartoput: sleeping\n");
			sleep(&cq->r, canputc, cq);
		}
		if(n > m)


@@ 507,21 506,23 @@ uartkproc(void *a)
	Block *bp;
	int n;

loop:
	while ((n = cangetc(cq)) == 0){
	if(waserror())
		print("uartkproc got an error\n");

	for(;;){
		sleep(&cq->r, cangetc, cq);
		qlock(up);
		if(up->wq == 0){
			cq->out = cq->in;
		}else{
			n = cangetc(cq);
			bp = allocb(n);
			bp->flags |= S_DELIM;
			bp->wptr += gets(cq, bp->wptr, n);
			PUTNEXT(RD(up->wq), bp);
		}
		qunlock(up);
	}
	qlock(up);
	if(up->wq == 0){
		cq->out = cq->in;
	}else{
		bp = allocb(n);
		bp->flags |= S_DELIM;
		bp->wptr += gets(cq, bp->wptr, n);
		PUTNEXT(RD(up->wq), bp);
	}
	qunlock(up);
	goto loop;
}

enum{

M pc/fault386.c => pc/fault386.c +1 -1
@@ 35,7 35,7 @@ fault386(Ureg *ur)
		}
		u->p->state = MMUing;
		dumpregs(ur);
		panic("fault: 0x%lux 0x%lux", addr);
		panic("fault: 0x%lux", addr);
	}
	faulting = 0;
	u->p->insyscall = insyscall;

M pc/fns.h => pc/fns.h +6 -0
@@ 4,12 4,15 @@ void	a20enable(void);
#define	clearmmucache()		/* 386 doesn't have one */
void	clock(Ureg*);
void	clockinit(void);
void	config(int);
void	delay(int);
void	dmaend(int);
long	dmasetup(int, void*, long, int);
#define	evenaddr(x)		/* 386 doesn't care */
void	fault386(Ureg*);
void	faultinit(void);
void	fclock(Ureg*);
void	fclockinit(void);
#define	flushvirt();
void	fpsave(FPsave*);
void	fprestore(FPsave*);


@@ 20,8 23,10 @@ int	inss(int, void*, int);
int	outss(int, void*, int);
void	kbdinit(void);
void	kbdintr(Ureg*);
int	mail(int);
void	mmuinit(void);
void	outb(int, int);
int	owl(int);
void	prhex(ulong);
void	procrestore(Proc*, uchar*);
void	procsave(uchar*, int);


@@ 39,5 44,6 @@ void	systrap(void);
void	touser(void);
void	trapinit(void);
int	tas(Lock*);
void	uartintr0(Ureg*);
void	vgainit(void);
#define	waserror()	(u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))

M pc/main.c => pc/main.c +0 -8
@@ 373,14 373,6 @@ pmuwrbit(int index, int bit, int pos)
int
serial(int onoff)
{
	int x;

	/*
	 *  set config (enable everything)
	 */
	x = splhi();
	config(0x00);
	splx(x);
	return pmuwrbit(1, onoff, 6);
}


M pc/mem.h => pc/mem.h +1 -1
@@ 18,7 18,7 @@
/*
 * Time
 */
#define	HZ		(1000)			/* clock frequency */
#define	HZ		(20)			/* clock frequency */
#define	MS2HZ		(1000/HZ)		/* millisec per clock tick */
#define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */
#define	TK2MS(t)	((((ulong)(t))*1000)/HZ)	/* ticks to milliseconds */

M pc/trap.c => pc/trap.c +7 -3
@@ 34,8 34,8 @@ enum
	EOI=		0x20,		/* non-specific end of interrupt */
};

int	int0mask = 0xff;	/* interrupts enabled for first 8259 */
int	int1mask = 0xff;	/* interrupts enabled for second 8259 */
int	int0mask = 0x00;	/* interrupts enabled for first 8259 */
int	int1mask = 0x00;	/* interrupts enabled for second 8259 */

/*
 *  trap/interrupt gates


@@ 231,7 231,7 @@ dumpregs(Ureg *ur)
	else
		print("registers for kernel\n");
	print("FLAGS=%lux ECODE=%lux CS=%lux PC=%lux SS=%lux USP=%lux\n", ur->flags,
		ur->ecode, ur->cs, ur->pc, ur->ss, ur->usp);
		ur->ecode, ur->cs&0xff, ur->pc, 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);


@@ 286,7 286,11 @@ syscall(Ureg *ur)
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
			validaddr(sp, (1+MAXSYSARG)*BY2WD, 0);
		if(ax == EXITS)
			print("%d exiting\n", u->p->pid);
		ret = (*systab[ax])((ulong*)(sp+BY2WD));
		if(ax == EXITS)
			print("%d returned from sysexits!\n", u->p->pid);
		poperror();
	}
	if(u->nerrlab){

M port/devcons.c => port/devcons.c +9 -0
@@ 44,7 44,14 @@ putstrn(char *str, int n)
{
	int s, c, m;
	char *t;
static Lock fuck;

loop:
s = splhi();
if(!canlock(&fuck)){
	splx(s);
	goto loop;
}
	while(n > 0){
		if(printq.puts && *str=='\n')
			(*printq.puts)(&printq, "\r", 1);


@@ 59,6 66,8 @@ putstrn(char *str, int n)
		n -= m;
		str += m;
	}
unlock(&fuck);
splx(s);
}

/*

M port/devmnt.c => port/devmnt.c +15 -4
@@ 124,7 124,10 @@ loop:
	lock(&mnthdralloc);
	if(mh = mnthdralloc.free){		/* assign = */
		mnthdralloc.free = mh->next;
		mh->flushing = 0;
if(mh->active) print("mh->active\n");
if(mh->flushing) print("mh->flushing\n");
if(mh->mbr) print("mh->mbr\n");
		mh->mbr = 0;
		unlock(&mnthdralloc);
		return mh;
	}


@@ 619,8 622,10 @@ mntflush(Mnt *m, Mnthdr *omh)	/* queue is unlocked */
{
	Mnthdr *mh;

	if(omh->thdr.type == Tflush)
	if(omh->thdr.type == Tflush){
		omh->flushing = 0;
		return;
	}

	mh = mhalloc();
	if(waserror()){


@@ 680,8 685,10 @@ mntxmit(Mnt *m, Mnthdr *mh)
	mh->mbr = 0;
	mbw = mballoc();
	if(waserror()){			/* 1 */
		if(mh->mbr)
		if(mh->mbr){
			mbfree(mh->mbr);
			mh->mbr = 0;
		}
		mbfree(mbw);
		nexterror();
	}


@@ 780,6 787,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		qunlock(q);
		qlocked = 0;
		if(waserror()){		/* 3 */
print("%d interrupted read %lux %lux\n", u->p->pid, mh, mh->mbr);
			mnterrdequeue(m, mh);
			nexterror();
		}


@@ 789,7 797,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
		}while(n == 0);
		poperror();		/* 3 */
		if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]);
print("%d POO bad len %d %ux %lux %lux\n", u->p->pid, n, mh->mbr->buf[0], mh, mh->mbr);
			mnterrdequeue(m, mh);
			error(Ebadmsg);
		}


@@ 845,7 853,9 @@ print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]);
		qunlock(q);
		qlocked = 0;
		if(waserror()){		/* interrupted sleep */
print("%d interrupted queued sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing);
			mnterrdequeue(m, mh);
print("%d after flush sleep %lux %lux %d %d\n", u->p->pid, mh, mh->mbr, mh->active, mh->flushing);
			nexterror();
		}
		sleep(&mh->r, mntreadreply, mh);


@@ 885,6 895,7 @@ print("POO bad len %d %ux!\n", n, mh->mbr->buf[0]);
		memmove(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
	}
	mbfree(mh->mbr);
	mh->mbr = 0;
	mbfree(mbw);
	USED(qlocked);
	poperror();		/* 1 */

M port/queue.c => port/queue.c +37 -46
@@ 18,15 18,16 @@ initq(IOQ *q)
int
putc(IOQ *q, int c)
{
	uchar *nextin;
	if(q->in >= &q->buf[sizeof(q->buf)-1])
		nextin = q->buf;
	uchar *next;

	if(q->in ==  &q->buf[NQ-1])
		next = q->buf;
	else
		nextin = q->in+1;
	if(nextin == q->out)
		next = q->in+1;
	if(next == q->out)
		return -1;
	*q->in = c;
	q->in = nextin;
	q->in = next;
	return 0;
}



@@ 38,7 39,7 @@ getc(IOQ *q)
	if(q->in == q->out)
		return -1;
	c = *q->out;
	if(q->out == q->buf+sizeof(q->buf)-1)
	if(q->out == &q->buf[NQ-1])
		q->out = q->buf;
	else
		q->out++;


@@ 48,60 49,44 @@ getc(IOQ *q)
void
puts(IOQ *q, void *buf, int n)
{
	int m; uchar *nextin;
	uchar *s = buf;
	uchar *next;
	uchar *p = buf;

	while(n){
		m = q->out - q->in - 1;
		if(m < 0)
			m = &q->buf[NQ] - q->in;
		if(m == 0)
			break;
		if(m > n)
			m = n;
		memmove(q->in, s, m);
		n -= m;
		s += m;
		nextin = q->in + m;
		if(nextin >= &q->buf[NQ])
			q->in = q->buf;
	for(; n; n--){
		if(q->in == &q->buf[NQ-1])
			next = q->buf;
		else
			q->in = nextin;
			next = q->in + 1;
		if(next == q->out)
			break;
		*q->in = *p++;
		q->in = next;
	}
}

int
gets(IOQ *q, void *buf, int n)
{
	int m, k = 0; uchar *nextout;
	uchar *s = buf;
	uchar *p = buf;

	while(n){
		m = q->in - q->out;
		if(m < 0)
			m = &q->buf[NQ] - q->out;
		if(m == 0)
			return k;
		if(m > n)
			m = n;
		memmove(s, q->out, m);
		s += m;
		k += m;
		n -= m;
		nextout = q->out + m;
		if(nextout >= &q->buf[NQ])
	for(; n && q->out != q->in; n--){
		*p++ = *q->out;
		if(q->out == &q->buf[NQ-1])
			q->out = q->buf;
		else
			q->out = nextout;
			q->out++;
	}
	return k;
	return p - (uchar*)buf;
}

int
cangetc(void *arg)
{
	IOQ *q = (IOQ *)arg;
	int n = q->in - q->out;
	IOQ *q;
	int n;

	q = (IOQ *)arg;
	n = q->in - q->out;
	if (n < 0)
		n += sizeof(q->buf);
	return n;


@@ 110,6 95,12 @@ cangetc(void *arg)
int
canputc(void *arg)
{
	IOQ *q = (IOQ *)arg;
	return sizeof(q->buf)-cangetc(q)-1;
	IOQ *q;
	int n;

	q = (IOQ *)arg;
	n = q->out - q->in - 1;
	if (n < 0)
		n += sizeof(q->buf);
	return n;
}

M port/sysproc.c => port/sysproc.c +14 -12
@@ 21,7 21,7 @@ sysr1(ulong *arg)
long
sysfork(ulong *arg)
{
	return rfork(Forkfd|Forkeg|Forkpg);
	return rfork(Forkfd);
}

/* This call will obsolete fork */


@@ 76,28 76,28 @@ rfork(ulong flag)

	if(flag & Forkfd)
		p->fgrp = dupfgrp(u->p->fgrp);
	else {
	else{
		p->fgrp = u->p->fgrp;
		incref(p->fgrp);
	}

	if(flag & Forkpg) {
		p->pgrp = u->p->pgrp;			/* Process groups */
		incref(p->pgrp);
	}
	else {
		p->pgrp = newpgrp();
		pgrpcpy(p->pgrp, u->p->pgrp);
	}
	else {
		p->pgrp = u->p->pgrp;			/* Process groups */
		incref(p->pgrp);
	}

	if(flag & Forkeg) {
		p->egrp = u->p->egrp;			/* Environment group */
		incref(p->egrp);
	}
	else {
		p->egrp = newegrp();
		envcpy(p->egrp, u->p->egrp);
	}
	else {
		p->egrp = u->p->egrp;			/* Environment group */
		incref(p->egrp);
	}

	/*
	 * Sched


@@ 406,14 406,16 @@ long
sysexits(ulong *arg)
{
	char *status;
	char *inval = "invalid exit string";

	status = (char*)arg[0];
	if(status){
		if(waserror())
			status = "invalid exit string";
			status = inval;
		else{
			validaddr((ulong)status, 1, 0);
			vmemchr(status, 0, ERRLEN);
			if(vmemchr(status, 0, ERRLEN) == 0)
				status = inval;
		}
		poperror();


M power/devhotrod.c => power/devhotrod.c +1 -5
@@ 21,12 21,11 @@ ulong	testbuf[NTESTBUF];
/*
 * If defined, ENABBUSTEST causes bus error diagnostic to be run at device open
 */
#define	ENABBUSTEST

/*
 * If 1, ENABCKSUM causes data transfers to have checksums
 */
#define	ENABCKSUM	1
#define	ENABCKSUM	0

typedef struct Hotrod	Hotrod;



@@ 72,14 71,11 @@ hotsend(Hotrod *h, Hotmsg *m)

	lock(h);
	mp = (Hotmsg**)&h->addr->reqstq[h->wi];
print("send 1 %lux\n", MP2VME(m)); delay(500);
	*mp = (Hotmsg*)MP2VME(m);
print("send 2\n"); delay(500);
	h->wi++;
	if(h->wi >= NRQ)
		h->wi = 0;
	unlock(h);
print("send 3\n"); delay(500);
	return mp;
}