M gnot/chan.c => gnot/chan.c +37 -11
@@ 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;
}
M gnot/dat.h => gnot/dat.h +7 -3
@@ 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,
};
/*
M gnot/devdk.c => gnot/devdk.c +10 -5
@@ 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
M gnot/fns.h => gnot/fns.h +5 -0
@@ 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*);
M gnot/l.s => gnot/l.s +34 -0
@@ 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
M gnot/main.c => gnot/main.c +4 -2
@@ 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<<m->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
M gnot/proc.c => gnot/proc.c +18 -0
@@ 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;
}
M gnot/sysproc.c => gnot/sysproc.c +6 -0
@@ 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;
}
M gnot/trap.c => gnot/trap.c +10 -6
@@ 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;
M port/chan.c => port/chan.c +37 -11
@@ 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;
}