M gnot/devcons.c => gnot/devcons.c +6 -0
@@ 188,6 188,8 @@ echo(int c)
return;
if(c == 0x15)
putstrn("^U\n", 3);
+ if(c == 0x16)
+ dumpqueues();
else{
ch = c;
putstrn(&ch, 1);
@@ 399,6 401,10 @@ consread(Chan *c, void *buf, long n)
case Qrcons:
case Qcons:
qlock(&kbdq);
+ if(waserror()){
+ qunlock(&kbdq);
+ nexterror();
+ }
while(!cangetc(&lineq)){
sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
do{
M gnot/devdk.c => gnot/devdk.c +10 -2
@@ 66,7 66,7 @@ struct Dkmsg {
#define D_OK 1 /* not used */
#define D_OPEN 2 /* (dkmux to host) connection established */
#define D_FAIL 3 /* (dkmux to host) connection failed */
-#define T_CHG 3 /* linege the status of a connection */
+#define T_CHG 3 /* change the status of a connection */
#define D_CLOSE 1 /* close the connection */
#define D_ISCLOSED 2 /* (dkmux to host) confirm a close */
#define D_CLOSEALL 3 /* (dkmux to host) close all connections */
@@ 1003,7 1003,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
}
/*
- * linege state if serving
+ * change state if serving
*/
if(type == D_SERV){
lp->state = Llistening;
@@ 1075,7 1075,9 @@ dklisten(Chan *c)
n = streamread(dc, dialstr, sizeof(dialstr)-1);
DPRINT("returns %d\n", n);
if(n <= 0)
+{print("bad n\n");
error(0, Eio);
+}
dialstr[n] = 0;
DPRINT("dialstr = %s\n", dialstr);
@@ 1085,6 1087,7 @@ dklisten(Chan *c)
n = getfields(dialstr, line, 12, '\n');
if (n < 2) {
DPRINT("bad dialstr from dk (1 line)\n");
+print("bad dialstr %d '%s'\n", n, dialstr);
error(0, Eio);
}
@@ 1291,6 1294,11 @@ dkcsckproc(void *a)
dp = (Dk *)a;
/*
+ * tell datakit we've rebooted. It should close all channels.
+ */
+ dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);
+
+ /*
* loop forever listening
*/
for(;;){
M gnot/devmnt.c => gnot/devmnt.c +12 -14
@@ 65,6 65,7 @@ struct
struct
{
Lock;
+ QLock;
MntQ *arena;
MntQ *free;
}mntqalloc;
@@ 141,22 142,21 @@ mhfree(Mnthdr *mh)
}
MntQ*
-mqalloc(void)
+mqalloc(Chan *msg) /* mntqalloc is qlocked */
{
MntQ *q;
- lock(&mntqalloc);
if(q = mntqalloc.free){ /* assign = */
mntqalloc.free = q->next;
- unlock(&mntqalloc);
lock(q);
q->ref = 1;
+ q->msg = msg;
+ unlock(q);
+ incref(msg);
q->writer = 0;
q->reader = 0;
- unlock(q);
return q;
}
- unlock(&mntqalloc);
panic("no mntqs\n"); /* there MUST be enough */
}
@@ 167,7 167,7 @@ mqfree(MntQ *mq)
lock(mq);
if(--mq->ref == 0){
-print("mqfree\n");
+print("mqfree %lux %lux\n", mq->reader, mq->writer);
msg = mq->msg;
mq->msg = 0;
lock(&mntqalloc);
@@ 272,6 272,7 @@ mntattach(char *spec)
* Look for queue to same msg channel
*/
q = mntqalloc.arena;
+ qlock(&mntqalloc);
for(i=0; i<conf.nmntdev; i++,q++)
if(q->msg==cm){
lock(q);
@@ 283,11 284,10 @@ mntattach(char *spec)
}
unlock(q);
}
- m->q = mqalloc();
- m->q->msg = cm;
- incref(cm);
+ m->q = mqalloc(cm);
out:
+ qunlock(&mntqalloc);
mh = mhalloc();
if(waserror()){
mhfree(mh);
@@ 645,7 645,6 @@ mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */
qlock(q);
/* take self from queue if necessary */
if(q->reader == u->p){ /* advance a writer to reader */
-print("err: reader\n");
w = q->writer;
if(w){
q->reader = w->p;
@@ 656,7 655,6 @@ print("err: reader\n");
q->writer = 0;
}
}else{
-print("err: writer\n");
w = q->writer;
if(w == mh)
q->writer = w->next;
@@ 774,7 772,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
qlocked = 0;
n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE);
if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
- print("format error in mntxmit\n");
+ print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text);
mnterrdequeue(q, mh);
error(0, Ebadmsg);
}
@@ 798,7 796,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
/*
* Hand response to correct recipient
*/
-if(q->writer == 0) print("response with empty queue\n");
+if(q->writer == 0) print("response with empty queue %d %d %d: %d %d\n", mh->rhdr.type, mh->rhdr.err, mh->rhdr.fid, mh->thdr.type, mh->thdr.fid);
for(ow=0,w=q->writer; w; ow=w,w=w->next)
if(mh->rhdr.fid == w->thdr.fid
&& mh->rhdr.type == w->thdr.type+1){
@@ 825,7 823,7 @@ if(q->writer == 0) print("response with empty queue\n");
qunlock(q);
qlocked = 0;
if(waserror()){ /* interrupted sleep */
- print("interrupted i/o\n");
+ print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid);
mnterrdequeue(q, mh);
nexterror();
}
M gnot/devpipe.c => gnot/devpipe.c +1 -4
@@ 92,22 92,19 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
- print("pipecreate\n");
error(0, Egreg);
}
void
piperemove(Chan *c)
{
- print("piperemove\n");
error(0, Egreg);
}
void
pipewstat(Chan *c, char *db)
{
- print("pipewstat\n");
- error(0, Egreg);
+ error(0, Eperm);
}
void
M gnot/devproc.c => gnot/devproc.c +1 -1
@@ 263,7 263,7 @@ procread(Chan *c, void *va, long n)
}
/* u area */
- if(c->offset>=USERADDR && c->offset<=USERADDR+BY2PG){
+ if(c->offset>=USERADDR && c->offset<USERADDR+BY2PG){
if(c->offset+n > USERADDR+BY2PG)
n = USERADDR+BY2PG - c->offset;
pg = p->upage;
M gnot/fault.c => gnot/fault.c +13 -6
@@ 280,19 280,26 @@ fault(Ureg *ur, FFrame *f)
void
validaddr(ulong addr, ulong len, int write)
{
- Seg *s;
+ Seg *s, *ns;
- if((long)len < 0)
- goto Err;
- s = seg(u->p, addr);
- if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){
+ if((long)len < 0){
Err:
pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
postnote(u->p, 1, "bad address", NDebug);
error(0, Ebadarg);
}
+ Again:
+ s = seg(u->p, addr);
+ if(s==0)
+ goto Err;
+ if(write && (s->o->flag&OWRPERM)==0)
+ goto Err;
+ if(addr+len > s->maxva){
+ len -= s->maxva - addr;
+ addr = s->maxva;
+ goto Again;
+ }
}
-
/*
* &s[0] is known to be a valid address.
*/
M gnot/lock.c => gnot/lock.c +4 -6
@@ 4,7 4,7 @@
#include "dat.h"
#include "fns.h"
-#define PCOFF -2
+#define PCOFF -1
/*
* N.B. Ken's compiler generates a TAS instruction for the sequence:
@@ 25,13 25,13 @@ lock(Lock *l)
*/
if(l->key >= 0){
l->key |= 0x80;
- l->pc = ((ulong*)&i)[PCOFF];
+ l->pc = ((ulong*)&l)[PCOFF];
return;
}
for(i=0; i<10000000; i++)
if(l->key >= 0){
l->key |= 0x80;
- l->pc = ((ulong*)&i)[PCOFF];
+ l->pc = ((ulong*)&l)[PCOFF];
return;
}
l->key = 0;
@@ 41,11 41,9 @@ lock(Lock *l)
int
canlock(Lock *l)
{
- int i;
-
if(l->key >= 0){
l->key |= 0x80;
- l->pc = ((ulong*)&i)[PCOFF];
+ l->pc = ((ulong*)&l)[PCOFF];
return 1;
}
return 0;
M gnot/main.c => gnot/main.c +1 -1
@@ 289,7 289,7 @@ confinit(void)
conf.base1 = 16*1024*1024;
conf.npage = conf.npage0+conf.npage1;
mul = 1 + (conf.npage1>0);
- conf.nproc = 32*mul;
+ conf.nproc = 40*mul;
conf.npgrp = 15*mul;
conf.npte = 700*mul;
conf.nmod = 400*mul;
M port/chan.c => port/chan.c +0 -1
@@ 127,7 127,6 @@ mountsplit(Mount *omnt)
{
Mount *nmnt;
- print("mount copy on write\n");
nmnt = newmount();
lock(nmnt);
nmnt->term = omnt->term;
M port/devcons.c => port/devcons.c +5 -1
@@ 425,6 425,10 @@ consread(Chan *c, void *buf, long n)
case Qcons:
qlock(&kbdq);
+ if(waserror()){
+ qunlock(&kbdq);
+ nexterror();
+ }
while(!cangetc(&lineq)){
sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
do{
@@ 486,7 490,7 @@ consread(Chan *c, void *buf, long n)
return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);
case Qtime:
- return readnum(c->offset, buf, n, boottime+TK2MS(MACHP(0)->ticks), 12);
+ return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
case Quser:
return readstr(c->offset, buf, n, u->p->pgrp->user);
M port/devdk.c => port/devdk.c +11 -2
@@ 66,7 66,7 @@ struct Dkmsg {
#define D_OK 1 /* not used */
#define D_OPEN 2 /* (dkmux to host) connection established */
#define D_FAIL 3 /* (dkmux to host) connection failed */
-#define T_CHG 3 /* linege the status of a connection */
+#define T_CHG 3 /* change the status of a connection */
#define D_CLOSE 1 /* close the connection */
#define D_ISCLOSED 2 /* (dkmux to host) confirm a close */
#define D_CLOSEALL 3 /* (dkmux to host) close all connections */
@@ 1003,7 1003,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine)
}
/*
- * linege state if serving
+ * change state if serving
*/
if(type == D_SERV){
lp->state = Llistening;
@@ 1075,7 1075,9 @@ dklisten(Chan *c)
n = streamread(dc, dialstr, sizeof(dialstr)-1);
DPRINT("returns %d\n", n);
if(n <= 0)
+{print("bad n\n");
error(0, Eio);
+}
dialstr[n] = 0;
DPRINT("dialstr = %s\n", dialstr);
@@ 1085,6 1087,7 @@ dklisten(Chan *c)
n = getfields(dialstr, line, 12, '\n');
if (n < 2) {
DPRINT("bad dialstr from dk (1 line)\n");
+print("bad dialstr %d '%s'\n", n, dialstr);
error(0, Eio);
}
@@ 1291,6 1294,12 @@ dkcsckproc(void *a)
dp = (Dk *)a;
/*
+ * tell datakit we've rebooted. It should close all channels.
+ */
+ dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); /* do this on mips but not 68020 */
+ dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);
+
+ /*
* loop forever listening
*/
for(;;){
M port/devmnt.c => port/devmnt.c +11 -11
@@ 141,22 141,21 @@ mhfree(Mnthdr *mh)
}
MntQ*
-mqalloc(void)
+mqalloc(Chan *msg) /* mntqalloc is locked */
{
MntQ *q;
- lock(&mntqalloc);
if(q = mntqalloc.free){ /* assign = */
mntqalloc.free = q->next;
- unlock(&mntqalloc);
lock(q);
q->ref = 1;
+ q->msg = msg;
+ unlock(q);
+ incref(msg);
q->writer = 0;
q->reader = 0;
- unlock(q);
return q;
}
- unlock(&mntqalloc);
panic("no mntqs\n"); /* there MUST be enough */
}
@@ 167,6 166,7 @@ mqfree(MntQ *mq)
lock(mq);
if(--mq->ref == 0){
+print("mqfree %lux %lux\n", mq->reader, mq->writer);
msg = mq->msg;
mq->msg = 0;
lock(&mntqalloc);
@@ 271,6 271,7 @@ mntattach(char *spec)
* Look for queue to same msg channel
*/
q = mntqalloc.arena;
+ lock(&mntqalloc);
for(i=0; i<conf.nmntdev; i++,q++)
if(q->msg==cm){
lock(q);
@@ 282,11 283,10 @@ mntattach(char *spec)
}
unlock(q);
}
- m->q = mqalloc();
- m->q->msg = cm;
- incref(cm);
+ m->q = mqalloc(cm);
out:
+ unlock(&mntqalloc);
mh = mhalloc();
if(waserror()){
mhfree(mh);
@@ 771,7 771,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
qlocked = 0;
n = (*devtab[q->msg->type].read)(q->msg, mbr->buf, BUFSIZE);
if(convM2S(mbr->buf, &mh->rhdr, n) == 0){
- print("format error in mntxmit\n");
+ print("%lux %lux %lux %d format error in mntxmit %s\n", u->p, q->reader, q->writer, n, u->p->text);
mnterrdequeue(q, mh);
error(0, Ebadmsg);
}
@@ 795,7 795,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
/*
* Hand response to correct recipient
*/
-if(q->writer == 0) print("response with empty queue\n");
+if(q->writer == 0) print("response with empty queue %d %d %d: %d %d\n", mh->rhdr.type, mh->rhdr.err, mh->rhdr.fid, mh->thdr.type, mh->thdr.fid);
for(ow=0,w=q->writer; w; ow=w,w=w->next)
if(mh->rhdr.fid == w->thdr.fid
&& mh->rhdr.type == w->thdr.type+1){
@@ 822,7 822,7 @@ if(q->writer == 0) print("response with empty queue\n");
qunlock(q);
qlocked = 0;
if(waserror()){ /* interrupted sleep */
- print("interrupted i/o\n");
+ print("%lux interrupted i/o %d %d\n", u->p, mh->thdr.type, mh->thdr.fid);
mnterrdequeue(q, mh);
nexterror();
}
M port/devpipe.c => port/devpipe.c +1 -4
@@ 92,22 92,19 @@ pipeopen(Chan *c, int omode)
void
pipecreate(Chan *c, char *name, int omode, ulong perm)
{
- print("pipecreate\n");
error(0, Egreg);
}
void
piperemove(Chan *c)
{
- print("piperemove\n");
error(0, Egreg);
}
void
pipewstat(Chan *c, char *db)
{
- print("pipewstat\n");
- error(0, Egreg);
+ error(0, Eperm);
}
void
M port/fault.c => port/fault.c +13 -5
@@ 208,17 208,25 @@ o->nmod++;
void
validaddr(ulong addr, ulong len, int write)
{
- Seg *s;
+ Seg *s, *ns;
- if((long)len < 0)
- goto Err;
- s = seg(u->p, addr);
- if(s==0 || addr+len>s->maxva || (write && (s->o->flag&OWRPERM)==0)){
+ if((long)len < 0){
Err:
pprint("invalid address in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
postnote(u->p, 1, "bad address", NDebug);
error(0, Ebadarg);
}
+ Again:
+ s = seg(u->p, addr);
+ if(s==0)
+ goto Err;
+ if(write && (s->o->flag&OWRPERM)==0)
+ goto Err;
+ if(addr+len > s->maxva){
+ len -= s->maxva - addr;
+ addr = s->maxva;
+ goto Again;
+ }
}
void
M port/page.c => port/page.c +7 -3
@@ 10,7 10,7 @@ struct
Lock;
ulong addr;
int active;
- Page *page; /* base of Page structures, indexed by phys addr */
+ Page *page; /* base of Page structures, indexed by phys page number */
ulong minppn; /* index of first usable page */
Page *head; /* most recently used */
Page *tail; /* least recently used */
@@ 161,6 161,7 @@ newpage(int noclear, Orig *o, ulong va)
{
Page *p;
Orig *o1;
+ KMap *k;
if(palloc.active == 0)
print("newpage inactive\n");
@@ 206,8 207,11 @@ loop:
p->ref = 1;
usepage(p, 0);
unlock(&palloc);
- if(!noclear)
- memset((void*)(p->pa|KZERO), 0, BY2PG);
+ if(!noclear){
+ k = kmap(p);
+ memset((void*)VA(k), 0, BY2PG);
+ kunmap(k);
+ }
p->o = o;
p->va = va;
M port/proc.c => port/proc.c +22 -12
@@ 303,18 303,23 @@ int
postnote(Proc *p, int dolock, char *n, int flag)
{
User *up;
+ KMap *k;
int s;
Rendez *r;
if(dolock)
lock(&p->debug);
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)VA(k);
if(flag!=NUser && (up->notify==0 || up->notified))
up->nnote = 0; /* force user's hand */
- else if(up->nnote == NNOTE-1)
+ else if(up->nnote == NNOTE-1){
+ kunmap(k);
return 0;
+ }
strcpy(up->note[up->nnote].msg, n);
up->note[up->nnote++].flag = flag;
+ kunmap(k);
if(dolock)
unlock(&p->debug);
if(r = p->r){ /* assign = */
@@ 398,7 403,7 @@ pexit(char *s, int freemem)
/*
* Pass info through back door, to avoid huge Proc's
*/
- p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
+ p->waitmsg = (((ulong)&w)&(BY2PG-1));
c->state = Exiting;
if(p->state == Inwait)
ready(p);
@@ 499,6 504,7 @@ ulong
pwait(Waitmsg *w)
{
Proc *c, *p;
+ KMap *k;
ulong cpid;
p = u->p;
@@ 515,16 521,17 @@ again:
lock(&p->wait.queue); /* wait until child is finished */
c = p->child;
if(c == 0){
- print("pwait %d\n", p->pid);
p->state = Inwait;
unlock(&p->wait.queue);
sched();
goto again;
}
p->child = 0;
+ k = kmap(c->upage);
if(w)
- *w = *p->waitmsg;
- cpid = p->waitmsg->pid;
+ *w = *(Waitmsg*)(p->waitmsg|VA(k));
+ cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid;
+ kunmap(k);
p->time[TCUser] += c->time[TUser] + c->time[TCUser];
p->time[TCSys] += c->time[TSys] + c->time[TCSys];
p->time[TCReal] += c->time[TReal];
@@ 566,25 573,27 @@ kproc(char *name, void (*func)(void *), void *arg)
Proc *p;
int n;
ulong upa;
- User *up;
int lastvar; /* used to compute stack address */
+ User *up;
+ KMap *k;
/*
* Kernel stack
*/
p = newproc();
p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
- upa = p->upage->pa|KZERO;
- up = (User *)upa;
+ k = kmap(p->upage);
+ upa = VA(k);
+ up = (User*)upa;
+ up->p = p;
/*
* Save time: only copy u-> data and useful stack
*/
- memcpy((void*)upa, u, sizeof(User));
+ memcpy(up, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
- memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
- ((User *)upa)->p = p;
+ memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
/*
* Refs
@@ 593,6 602,7 @@ kproc(char *name, void (*func)(void *), void *arg)
for(n=0; n<=up->maxfd; n++)
up->fd[n] = 0;
up->maxfd = 0;
+ kunmap(k);
/*
* Sched
M port/sysfile.c => port/sysfile.c +0 -1
@@ 283,7 283,6 @@ sysstat(ulong *arg)
validaddr(arg[0], 1, 0);
c = namec((char*)arg[0], Aaccess, 0, 0);
if(waserror()){
-print("stat error\n");
close(c);
nexterror();
}
M power/dat.h => power/dat.h +1 -1
@@ 310,7 310,7 @@ struct Proc
Proc *sib; /* non-ascendant relatives (circular list) */
int nchild;
QLock wait; /* exiting children to be waited for */
- Waitmsg *waitmsg;
+ ulong waitmsg;
Proc *child;
Proc *parent;
Pgrp *pgrp;
M power/main.c => power/main.c +7 -2
@@ 199,6 199,7 @@ userinit(void)
Proc *p;
Seg *s;
User *up;
+ KMap *k;
int i;
char **av;
@@ 219,8 220,10 @@ userinit(void)
/*
* User
*/
- up = (User*)(p->upage->pa|KZERO);
+ k = kmap(p->upage);
+ up = (User*)VA(k);
up->p = p;
+ kunmap(k);
/*
* User Stack, pass input arguments to boot process
@@ 244,7 247,9 @@ userinit(void)
s->proc = p;
s->o = neworig(UTZERO, 1, 0, 0);
s->o->pte[0].page = newpage(0, 0, UTZERO);
- memcpy((ulong*)(s->o->pte[0].page->pa|KZERO), initcode, sizeof initcode);
+ k = kmap(s->o->pte[0].page);
+ memcpy((ulong*)VA(k), initcode, sizeof initcode);
+ kunmap(k);
s->minva = 0x1000;
s->maxva = 0x2000;