M ss/dat.h => ss/dat.h +1 -0
@@ 193,6 193,7 @@ extern register Mach *m; /* R6 */
extern register User *u; /* R5 */
extern uchar *intrreg;
+extern FPsave *initfpp;
struct
{
M ss/l.s => ss/l.s +5 -12
@@ 468,15 468,10 @@ TEXT putsegm(SB), $0
MOVW R8, (R7, 3)
RETURN
-/*
- * in savefpregs and restfpregs, incoming R7 points to doubleword
- * below where F0 will go; doubleword align in and backfill FSR
- */
TEXT savefpregs(SB), $0
- ADD $8, R7
- ANDN $7, R7 /* now MOVD-aligned */
- MOVW FSR, -4(R7)
+ MOVW FSR, 0(R7)
+ ADD $4, R7
MOVD F0, (0*4)(R7)
MOVD F2, (2*4)(R7)
@@ 520,11 515,9 @@ TEXT restfpregs(SB), $0
OR $PSREF, R8
MOVW R8, PSR
- ADD $8, R7
- ANDN $7, R7 /* now MOVD-aligned */
- OR R0, R0
-
- MOVW -4(R7), FSR
+ NOOP /* wait for PSR to quiesce */
+ MOVW 0(R7), FSR
+ ADD $4, R7
MOVD (0*4)(R7), F0
MOVD (2*4)(R7), F2
M ss/main.c => ss/main.c +11 -3
@@ 35,6 35,7 @@ main(void)
initseg();
chandevreset();
streaminit();
+ swapinit();
userinit();
clockinit();
schedinit();
@@ 112,7 113,8 @@ init0(void)
touser(USTKTOP-(1+MAXSYSARG)*BY2WD);
}
-FPsave initfp;
+FPsave *initfpp;
+uchar initfpa[sizeof(FPsave)+7];
void
userinit(void)
@@ 121,6 123,7 @@ userinit(void)
Segment *s;
User *up;
KMap *k;
+ ulong l;
p = newproc();
p->pgrp = newpgrp();
@@ 132,8 135,13 @@ userinit(void)
strcpy(p->text, "*init*");
strcpy(p->user, eve);
- savefpregs(&initfp);
-/* initfp.fsr |= 0x1E << 23; /* trap on all but INEXACT */
+ /* must align initfpp to an ODD word boundary */
+ l = (ulong)initfpa;
+ l += 3;
+ l &= ~7;
+ l += 4;
+ initfpp = (FPsave*)l;
+ savefpregs(initfpp);
p->fpstate = FPinit;
/*
M ss/trap.c => ss/trap.c +28 -2
@@ 95,6 95,29 @@ excname(ulong tbr)
return excbuf;
}
+/*
+ * This routine is frightening. See comment in fptrap.c
+ */
+void
+fpquiet(void)
+{
+ int i;
+ ulong fsr;
+
+ i = 0;
+ fsr = getfsr();
+ while(fsr & (1<<13)){
+ if(fsr & 0x1F){
+ print("trap in fpquiet\n");
+ break;
+ }
+ if(++i > 1000){
+ print("fp not quiescent\n");
+ break;
+ }
+ }
+}
+
void
trap(Ureg *ur)
{
@@ 111,7 134,8 @@ trap(Ureg *ur)
tbr = (ur->tbr&0xFFF)>>4;
if(tbr > 16){ /* interrupt */
if(u && u->p->state==Running){
- if(u->p->fpstate == FPactive) {
+ if(u->p->fpstate == FPactive){
+ fpquiet();
savefpregs(&u->fpsave);
u->p->fpstate = FPinactive;
ur->psr &= ~PSREF;
@@ 138,6 162,7 @@ trap(Ureg *ur)
case 1: /* instr. access */
case 9: /* data access */
if(u && u->p->fpstate==FPactive) {
+ fpquiet();
savefpregs(&u->fpsave);
u->p->fpstate = FPinactive;
ur->psr &= ~PSREF;
@@ 161,7 186,7 @@ trap(Ureg *ur)
case 4: /* floating point disabled */
if(u && u->p){
if(u->p->fpstate == FPinit)
- restfpregs(&initfp);
+ restfpregs(initfpp);
else if(u->p->fpstate == FPinactive)
restfpregs(&u->fpsave);
else
@@ 514,6 539,7 @@ syscall(Ureg *aur)
* guarantee anything about registers,
*/
if(u->p->fpstate == FPactive) {
+ fpquiet();
u->p->fpstate = FPinit;
ur->psr &= ~PSREF;
}