From 71ae88f188b239c5e66523a8ad019d5689cf3565 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 20 Aug 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-08-20 --- gnot/chan.c | 48 +++++++++++++++++++++++++++++++++++++----------- gnot/dat.h | 10 +++++++--- gnot/devdk.c | 15 ++++++++++----- gnot/fns.h | 5 +++++ gnot/l.s | 34 ++++++++++++++++++++++++++++++++++ gnot/main.c | 6 ++++-- gnot/proc.c | 18 ++++++++++++++++++ gnot/sysproc.c | 6 ++++++ gnot/trap.c | 16 ++++++++++------ port/chan.c | 48 +++++++++++++++++++++++++++++++++++++----------- 10 files changed, 168 insertions(+), 38 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 4f416670441500bb0f9f2ee2a68b347369278c15..496605e2199592f27e84dfe1e6a19c15fd14a070 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -340,7 +340,7 @@ walk(Chan *ac, char *name, int domnt) goto Notfound; } if(c->mountid != mnt->mountid){ - pprint("walk: changed underfoot?\n"); + pprint("walk: changed underfoot? '%s'\n", name); unlock(pg); goto Notfound; } @@ -431,12 +431,13 @@ namec(char *name, int amode, int omode, ulong perm) { Chan *c, *nc; int t; - int mntok; + int mntok, isdot; char *elem = u->elem; if(name[0] == 0) error(0, Enonexist); mntok = 1; + isdot = 0; if(name[0] == '/'){ c = clone(u->slash, 0); /* @@ -459,8 +460,12 @@ namec(char *name, int amode, int omode, ulong perm) }else name = nextelem(name, elem); c = (*devtab[t].attach)(elem); - }else + }else{ c = clone(u->dot, 0); + name = skipslash(name); /* eat leading ./ */ + if(*name == 0) + isdot = 1; + } if(waserror()){ close(c); @@ -468,8 +473,9 @@ namec(char *name, int amode, int omode, ulong perm) } name = nextelem(name, elem); - if(mntok) - if(!(amode==Amount && elem[0]==0)) /* don't domount on dot or slash */ + + if(mntok && !isdot) + if(!(amode==Amount && elem[0]==0)) /* don't domount on slash */ c = domount(c); /* see case Atodir below */ /* @@ -482,15 +488,20 @@ namec(char *name, int amode, int omode, ulong perm) c = nc; name = nextelem(name, elem); } + /* * Last element; act according to type of access. */ switch(amode){ case Aaccess: - if((nc=walk(c, elem, mntok)) == 0) - error(0, Enonexist); - c = nc; + if(isdot) + c = domount(c); + else{ + if((nc=walk(c, elem, mntok)) == 0) + error(0, Enonexist); + c = nc; + } break; case Atodir: @@ -506,9 +517,13 @@ namec(char *name, int amode, int omode, ulong perm) break; case Aopen: - if((nc=walk(c, elem, mntok)) == 0) - error(0, Enonexist); - c = nc; + if(isdot) + c = domount(c); + else{ + if((nc=walk(c, elem, mntok)) == 0) + error(0, Enonexist); + c = nc; + } Open: c = (*devtab[c->type].open)(c, omode); if(omode & OCEXEC) @@ -527,6 +542,8 @@ namec(char *name, int amode, int omode, ulong perm) break; case Acreate: + if(isdot) + error(0, Eisdir); if((nc=walk(c, elem, 1)) != 0){ c = nc; omode |= OTRUNC; @@ -552,11 +569,20 @@ namec(char *name, int amode, int omode, ulong perm) char* skipslash(char *name) { + Again: while(*name == '/'){ if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) validaddr((ulong)name+1, 1, 0); name++; } + if(*name == '.'){ + if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) + validaddr((ulong)name+1, 1, 0); + if(name[1]==0 || name[1]=='/'){ + name++; + goto Again; + } + } return name; } diff --git a/gnot/dat.h b/gnot/dat.h index 487b595d57999ee653e69d08b66a7c825442c841..c5c17d5376c9ea04030c029bae28c009fcc6ace8 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -106,8 +106,11 @@ struct Chan struct FPsave { - long fpreg[32]; - long fpstatus; + char type; + char size; + short reserved; + char junk[180]; + char reg[3*4+8*12]; }; struct Conf @@ -202,6 +205,7 @@ struct Mach Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ + int fpstate; /* state of fp registers on machine */ int stack[1]; }; @@ -513,7 +517,7 @@ enum { FPinit, FPactive, - FPinactive, + FPdirty, }; /* diff --git a/gnot/devdk.c b/gnot/devdk.c index 9e98863a7d1b3e6458f8902d826b3b8219ab4b70..dcc56fa917e1a046b139bf43657dfc204ef608ed 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -125,6 +125,7 @@ struct Dk { Chan *csc; /* common signalling line */ Line line[Nline]; int restart; + int urpwindow; }; static Dk dk[Ndk]; @@ -429,12 +430,13 @@ dkoput(Queue *q, Block *bp) } /* - * configure a datakit multiplexor. this takes 4 arguments separated + * configure a datakit multiplexor. this takes 5 arguments separated * by spaces: * the line number of the common signalling channel (must be > 0) * the number of lines in the device (optional) * the word `restart' or `norestart' (optional/default==restart) - * the name of the dk (optional) + * the name of the dk (default==dk) + * the urp window size (default==WS_2K) * * we can configure only once */ @@ -442,7 +444,7 @@ static void dkmuxconfig(Dk *dp, Block *bp) { Chan *c; - char *fields[4]; + char *fields[5]; int n; char buf[64]; static int dktimeron; @@ -456,9 +458,12 @@ dkmuxconfig(Dk *dp, Block *bp) * parse */ dp->restart = 1; - n = getfields((char *)bp->rptr, fields, 4, ' '); + n = getfields((char *)bp->rptr, fields, 5, ' '); strcpy(dp->name, "dk"); + dp->urpwindow = WS_2K; switch(n){ + case 5: + dp->urpwindow = strtoul(fields[4], 0, 0); case 4: strncpy(dp->name, fields[3], sizeof(dp->name)); case 3: @@ -978,7 +983,7 @@ dkcall(int type, Chan *c, char *addr, char *nuser, char *machine) * tell the controller we want to make a call */ DPRINT("dialout\n"); - dkmesg(dp, t_val, d_val, line, W_WINDOW(WS_2K,WS_2K,2)); + dkmesg(dp, t_val, d_val, line, W_WINDOW(dp->urpwindow,dp->urpwindow,2)); /* * if redial, wait for a dial tone (otherwise we might send diff --git a/gnot/fns.h b/gnot/fns.h index bacd1ef504f53f5e011d516a953aa54b0704b622..550bc2ea9dda851806617479c2209cd60d5ae995 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -49,6 +49,11 @@ void flowctl(Queue*); void flushcpucache(void); void flushmmu(void); void forkmod(Seg*, Seg*, Proc*); +int fpcr(int); +void fpsave(FPsave*); +void fpregsave(char*); +void fprestore(FPsave*); +void fpregrestore(char*); void freeb(Block*); void freenextmod(PTE*); void freepage(Orig*); diff --git a/gnot/l.s b/gnot/l.s index 09ea1146c1f71a9648a9a149e4c553ab5f8907c1..b854f39b1689761a657e4d82d30c4aab66e7ac1b 100644 --- a/gnot/l.s +++ b/gnot/l.s @@ -104,6 +104,40 @@ TEXT tas(SB), $0 tas_1: RTS +/* + * Floating point + */ + +TEXT fpsave(SB), $0 + + FSAVE (fp+0(FP)) + RTS + +TEXT fprestore(SB), $0 + + FRESTORE (fp+0(FP)) + RTS + +TEXT fpregsave(SB), $0 + + FMOVEM $0xFF, (3*4)(fr+0(FP)) + FMOVEMC $0x7, (fr+0(FP)) + RTS + +TEXT fpregrestore(SB), $0 + + FMOVEMC (fr+0(FP)), $0x7 + FMOVEM (3*4)(fr+0(FP)), $0xFF + RTS + +TEXT fpcr(SB), $0 + + MOVL new+0(FP), R1 + MOVL FPCR, R0 + MOVL R1, FPCR + RTS + + TEXT rfnote(SB), $0 MOVL uregpp+0(FP), A0 diff --git a/gnot/main.c b/gnot/main.c index 3cdaa1970e8a43d5be091bfe55c2b93bce455e7e..b6d74a69019801a8f8e2ee6c407fa18b89981e24 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -59,11 +59,14 @@ void machinit(void) { int n; + long fpnull = 0; n = m->machno; memset(m, 0, sizeof(Mach)); m->machno = n; m->mmask = 1<machno; + m->fpstate = FPinit; + fprestore((FPsave*)&fpnull); } void @@ -125,8 +128,7 @@ userinit(void) p->pgrp = newpgrp(); strcpy(p->text, "*init*"); strcpy(p->pgrp->user, protouser); -/* savefpregs(&initfp); /**/ -/* p->fpstate = FPinit; /**/ + p->fpstate = FPinit; /* * Kernel Stack diff --git a/gnot/proc.c b/gnot/proc.c index d86d46c3cbc8c19176619eedb4cdf59faae0ad06..434071271cbbd515fb38d3597d29720538d3ac47 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -78,15 +78,33 @@ sched(void) Proc *p; ulong tlbvirt, tlbphys; void (*f)(ulong); + long fpnull = 0; if(u){ splhi(); + fpsave(&u->fpsave); + if(u->fpsave.type){ + fpregsave(u->fpsave.reg); + u->p->fpstate = FPactive; + m->fpstate = FPdirty; + } if(setlabel(&u->p->sched)){ /* woke up */ if(u->p->mach)panic("mach non zero"); p = u->p; p->state = Running; p->mach = m; m->proc = p; + if(p->fpstate != m->fpstate){ + if(p->fpstate == FPinit){ + u->p->fpstate = FPinit; + fprestore((FPsave*)&fpnull); + m->fpstate = FPinit; + }else{ + fpregrestore(u->fpsave.reg); + fprestore(&u->fpsave); + m->fpstate = FPdirty; + } + } spllo(); return; } diff --git a/gnot/sysproc.c b/gnot/sysproc.c index f346eb8ee29b73361009c2b0ea4991ca50862b94..e5c061ca509f64153d333910025fcba0a6f2f32c 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -161,6 +161,7 @@ sysexec(ulong *arg) Orig *o; char **argv, **argp; char *a, *charp, *file; + long fpnull = 0; char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; ulong ssize, spage, nargs, nbytes, n; ulong *sp; @@ -370,6 +371,11 @@ sysexec(ulong *arg) u->nnote = 0; u->notify = 0; u->notified = 0; + splhi(); + m->fpstate = FPinit; + p->fpstate = FPinit; + fprestore((FPsave*)&fpnull); + spllo(); unlock(&p->debug); return 0; } diff --git a/gnot/trap.c b/gnot/trap.c index 7aae8ca8e840f4cb632356c2a814447983f122fd..3872346ca45d459e317e39835143d997087271b8 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -243,22 +243,26 @@ syscall(Ureg *aur) ulong r0; Ureg *ur; char *msg; + long fpnull = 0; u->p->insyscall = 1; ur = aur; u->p->pc = ur->pc; if(ur->sr & SUPER) panic("recursive system call"); -#ifdef asdf /* * since the system call interface does not - * guarantee anything about registers + * guarantee anything about registers, but the fpcr is more than + * just a register... BUG */ - if(u->p->fpstate == FPactive) { - u->p->fpstate = FPinit; /* BUG */ - ur->status &= ~CU1; + splhi(); + fpsave(&u->fpsave); + if(u->p->fpstate==FPactive || u->fpsave.type){ + fprestore((FPsave*)&fpnull); + u->p->fpstate = FPinit; + m->fpstate = FPinit; } -#endif + spllo(); r0 = ur->r0; sp = ur->usp; diff --git a/port/chan.c b/port/chan.c index 4f416670441500bb0f9f2ee2a68b347369278c15..496605e2199592f27e84dfe1e6a19c15fd14a070 100644 --- a/port/chan.c +++ b/port/chan.c @@ -340,7 +340,7 @@ walk(Chan *ac, char *name, int domnt) goto Notfound; } if(c->mountid != mnt->mountid){ - pprint("walk: changed underfoot?\n"); + pprint("walk: changed underfoot? '%s'\n", name); unlock(pg); goto Notfound; } @@ -431,12 +431,13 @@ namec(char *name, int amode, int omode, ulong perm) { Chan *c, *nc; int t; - int mntok; + int mntok, isdot; char *elem = u->elem; if(name[0] == 0) error(0, Enonexist); mntok = 1; + isdot = 0; if(name[0] == '/'){ c = clone(u->slash, 0); /* @@ -459,8 +460,12 @@ namec(char *name, int amode, int omode, ulong perm) }else name = nextelem(name, elem); c = (*devtab[t].attach)(elem); - }else + }else{ c = clone(u->dot, 0); + name = skipslash(name); /* eat leading ./ */ + if(*name == 0) + isdot = 1; + } if(waserror()){ close(c); @@ -468,8 +473,9 @@ namec(char *name, int amode, int omode, ulong perm) } name = nextelem(name, elem); - if(mntok) - if(!(amode==Amount && elem[0]==0)) /* don't domount on dot or slash */ + + if(mntok && !isdot) + if(!(amode==Amount && elem[0]==0)) /* don't domount on slash */ c = domount(c); /* see case Atodir below */ /* @@ -482,15 +488,20 @@ namec(char *name, int amode, int omode, ulong perm) c = nc; name = nextelem(name, elem); } + /* * Last element; act according to type of access. */ switch(amode){ case Aaccess: - if((nc=walk(c, elem, mntok)) == 0) - error(0, Enonexist); - c = nc; + if(isdot) + c = domount(c); + else{ + if((nc=walk(c, elem, mntok)) == 0) + error(0, Enonexist); + c = nc; + } break; case Atodir: @@ -506,9 +517,13 @@ namec(char *name, int amode, int omode, ulong perm) break; case Aopen: - if((nc=walk(c, elem, mntok)) == 0) - error(0, Enonexist); - c = nc; + if(isdot) + c = domount(c); + else{ + if((nc=walk(c, elem, mntok)) == 0) + error(0, Enonexist); + c = nc; + } Open: c = (*devtab[c->type].open)(c, omode); if(omode & OCEXEC) @@ -527,6 +542,8 @@ namec(char *name, int amode, int omode, ulong perm) break; case Acreate: + if(isdot) + error(0, Eisdir); if((nc=walk(c, elem, 1)) != 0){ c = nc; omode |= OTRUNC; @@ -552,11 +569,20 @@ namec(char *name, int amode, int omode, ulong perm) char* skipslash(char *name) { + Again: while(*name == '/'){ if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) validaddr((ulong)name+1, 1, 0); name++; } + if(*name == '.'){ + if(((ulong)name&KZERO)==0 && (((ulong)name+1)&(BY2PG-1))==0) + validaddr((ulong)name+1, 1, 0); + if(name[1]==0 || name[1]=='/'){ + name++; + goto Again; + } + } return name; }