M alphapc/dat.h => alphapc/dat.h +1 -1
@@ 43,7 43,7 @@ struct Label
};
/*
- * FPsave.fpstatus
+ * Proc.fpstate
*/
enum
{
M alphapc/main.c => alphapc/main.c +1 -2
@@ 258,14 258,13 @@ procsave(Proc *p)
*/
}
-/* still too do */
+/* still to do */
void
reboot(void*, void*, ulong)
{
exit(0);
}
-
void
exit(int)
{
M mtx/dat.h => mtx/dat.h +1 -3
@@ 42,7 42,7 @@ struct Label
};
/*
- * FPsave.fpstatus
+ * Proc.fpstate
*/
enum
{
@@ 64,8 64,6 @@ struct FPsave
ulong fpscr;
};
};
- int fpistate; /* emulated fp */
- ulong emreg[32][3]; /* emulated fp */
};
struct Conf
M mtx/fns.h => mtx/fns.h +9 -5
@@ 6,8 6,7 @@ int cistrncmp(char*, char*, int);
void clockcheck(void);
void clockinit(void);
void clockintr(Ureg*);
-void clrfptrap(void);
-#define coherence()
+#define coherence() eieio()
void cpuidentify(void);
void cpuidprint(void);
void dcflush(void*, ulong);
@@ 19,14 18,17 @@ void evenaddr(ulong);
void faultpower(Ureg*, ulong addr, int read);
void firmware(void);
void fpinit(void);
-int fpipower(Ureg*);
-void fpoff(void);
-ulong fpstatus(void);
+void fpoff(Proc*);
+void fprestore(FPsave*);
+void fpsave(FPsave*);
+void fptrap(Ureg*);
char* getconf(char*);
ulong getdar(void);
ulong getdec(void);
ulong getdepn(void);
ulong getdsisr(void);
+ulong gethid0(void);
+ulong gethid1(void);
ulong getimmr(void);
ulong getmsr(void);
ulong getpvr(void);
@@ 93,6 95,8 @@ void pcisetbme(Pcidev*);
void procsave(Proc*);
void procsetup(Proc*);
void putdec(ulong);
+void puthid0(ulong);
+void puthid1(ulong);
void putmsr(ulong);
void putsdr1(ulong);
void putsr(int, ulong);
M mtx/l.s => mtx/l.s +91 -3
@@ 286,6 286,22 @@ TEXT putsr(SB), $0
MOVW R4, SEG(R3)
RETURN
+TEXT gethid0(SB), $0
+ MOVW SPR(HID0), R3
+ RETURN
+
+TEXT gethid1(SB), $0
+ MOVW SPR(HID1), R3
+ RETURN
+
+TEXT puthid0(SB), $0
+ MOVW R3, SPR(HID0)
+ RETURN
+
+TEXT puthid1(SB), $0
+ MOVW R3, SPR(HID1)
+ RETURN
+
TEXT eieio(SB), $0
EIEIO
RETURN
@@ 349,7 365,6 @@ TEXT trapvec(SB), $-4
MOVW R0, R2
BL saveureg(SB)
BL trap(SB)
-// BL splhi(SB) /* BUG? */
BR restoreureg
ktrap:
MOVW R1, CR
@@ 358,7 373,6 @@ ktrap:
SUB $UREGSPACE, R1
BL saveureg(SB)
BL trap(SB)
-// BL splhi(SB) /* BUG? */
BR restoreureg
/*
@@ 405,7 419,7 @@ TEXT saveureg(SB), $-4
MOVW $0, R0 /* compiler/linker expect R0 to be zero */
MOVW MSR, R5
- OR $(MSR_IR|MSR_DR|MSR_RI), R5 /* enable MMU */
+ OR $(MSR_IR|MSR_DR|MSR_FP|MSR_RI), R5 /* enable MMU */
MOVW R5, SPR(SRR1)
MOVW LR, R31
OR $KZERO, R31 /* return PC in KSEG0 */
@@ 441,3 455,77 @@ restoreureg:
MOVW 44(R1), R1 /* old SP */
MOVW SPR(SAVER0), R0
RFI
+
+TEXT fpsave(SB), $0
+ FMOVD F0, (0*8)(R3)
+ FMOVD F1, (1*8)(R3)
+ FMOVD F2, (2*8)(R3)
+ FMOVD F3, (3*8)(R3)
+ FMOVD F4, (4*8)(R3)
+ FMOVD F5, (5*8)(R3)
+ FMOVD F6, (6*8)(R3)
+ FMOVD F7, (7*8)(R3)
+ FMOVD F8, (8*8)(R3)
+ FMOVD F9, (9*8)(R3)
+ FMOVD F10, (10*8)(R3)
+ FMOVD F11, (11*8)(R3)
+ FMOVD F12, (12*8)(R3)
+ FMOVD F13, (13*8)(R3)
+ FMOVD F14, (14*8)(R3)
+ FMOVD F15, (15*8)(R3)
+ FMOVD F16, (16*8)(R3)
+ FMOVD F17, (17*8)(R3)
+ FMOVD F18, (18*8)(R3)
+ FMOVD F19, (19*8)(R3)
+ FMOVD F20, (20*8)(R3)
+ FMOVD F21, (21*8)(R3)
+ FMOVD F22, (22*8)(R3)
+ FMOVD F23, (23*8)(R3)
+ FMOVD F24, (24*8)(R3)
+ FMOVD F25, (25*8)(R3)
+ FMOVD F26, (26*8)(R3)
+ FMOVD F27, (27*8)(R3)
+ FMOVD F28, (28*8)(R3)
+ FMOVD F29, (29*8)(R3)
+ FMOVD F30, (30*8)(R3)
+ FMOVD F31, (31*8)(R3)
+ MOVFL FPSCR, F0
+ FMOVD F0, (32*8)(R3)
+ RETURN
+
+TEXT fprestore(SB), $0
+ FMOVD (32*8)(R3), F0
+ MOVFL F0, FPSCR
+ FMOVD (0*8)(R3), F0
+ FMOVD (1*8)(R3), F1
+ FMOVD (2*8)(R3), F2
+ FMOVD (3*8)(R3), F3
+ FMOVD (4*8)(R3), F4
+ FMOVD (5*8)(R3), F5
+ FMOVD (6*8)(R3), F6
+ FMOVD (7*8)(R3), F7
+ FMOVD (8*8)(R3), F8
+ FMOVD (9*8)(R3), F9
+ FMOVD (10*8)(R3), F10
+ FMOVD (11*8)(R3), F11
+ FMOVD (12*8)(R3), F12
+ FMOVD (13*8)(R3), F13
+ FMOVD (14*8)(R3), F14
+ FMOVD (15*8)(R3), F15
+ FMOVD (16*8)(R3), F16
+ FMOVD (17*8)(R3), F17
+ FMOVD (18*8)(R3), F18
+ FMOVD (19*8)(R3), F19
+ FMOVD (20*8)(R3), F20
+ FMOVD (21*8)(R3), F21
+ FMOVD (22*8)(R3), F22
+ FMOVD (23*8)(R3), F23
+ FMOVD (24*8)(R3), F24
+ FMOVD (25*8)(R3), F25
+ FMOVD (26*8)(R3), F26
+ FMOVD (27*8)(R3), F27
+ FMOVD (28*8)(R3), F28
+ FMOVD (29*8)(R3), F29
+ FMOVD (30*8)(R3), F30
+ FMOVD (31*8)(R3), F31
+ RETURN
M mtx/main.c => mtx/main.c +23 -4
@@ 35,6 35,8 @@ main(void)
chandevreset();
pageinit();
swapinit();
+ fpsave(&initfp);
+ initfp.fpscr = 0;
userinit();
schedinit();
}
@@ 51,8 53,11 @@ machinit(void)
* be enough for a while. Cpuidentify will
* calculate the real value later.
*/
-// m->loopconst = 100000;
-m->loopconst = 5000; /* dog slow, the cache must be off */
+ m->loopconst = 100000;
+
+ /* turn on caches (instruction only for now) */
+ puthid0(gethid0() | BIT(16));
+//puthid0(gethid0() | BIT(16) | BIT(17)); /* and data */
active.machs = 1;
active.exiting = 0;
@@ 245,7 250,7 @@ exit(int ispanic)
void
procsetup(Proc *p)
{
- USED(p);
+ p->fpstate = FPinit;
}
/*
@@ 254,7 259,21 @@ procsetup(Proc *p)
void
procsave(Proc *p)
{
- USED(p);
+ if(p->fpstate == FPactive){
+ if(p->state != Moribund) {
+ /*
+ * Fpsave() stores without handling pending
+ * unmasked exeptions. Postnote() can't be called
+ * here as sleep() already has up->rlock, so
+ * the handling of pending exceptions is delayed
+ * until the process runs again and generates an
+ * emulation fault to activate the FPU.
+ */
+ fpsave(&up->fpsave);
+ }
+ fpoff(p);
+ p->fpstate = FPinactive;
+ }
}
void
M mtx/mem.h => mtx/mem.h +6 -1
@@ 22,7 22,7 @@
#define MHz 1000000
#define BY2PTE 8 /* bytes per pte entry */
-#define PTE2PG (BY2PG/BY2PTE) /* pte entries per page */
+#define BY2PTEG 64 /* bytes per pte group */
#define MAXMACH 1 /* max # cpus system can run */
#define MACHSIZE BY2PG
@@ 141,6 141,11 @@
#define PPN(x) ((x)&~(BY2PG-1))
/*
+ * First pte word
+ */
+#define PTE0(v, vsid, h, va) (((v)<<31)|((vsid)<<7)|((h)<<6)|(((va)>>22)&0x3f))
+
+/*
* Second pte word, known by fault.c, passed to putmmu()
*/
#define PTEVALID 0 /* implied for putmmu -- real V bit in first pte word */
M mtx/mmu.c => mtx/mmu.c +4 -4
@@ 106,11 106,11 @@ putmmu(ulong va, ulong pa, Page*)
vsid = VSID(mp, va>>28);
hash = (vsid ^ (va>>12)&0xffff) & ptab.mask;
- ptehi = BIT(0)|(vsid<<7)|((va>>22)&0x3f);
+ ptehi = PTE0(1, vsid, 0, va);
- pteg = ptab.base + 64*hash;
+ pteg = ptab.base + BY2PTEG*hash;
p = (ulong*)pteg;
- ep = (ulong*)(pteg+64);
+ ep = (ulong*)(pteg+BY2PTEG);
q = nil;
lock(&ptab);
tlbflush(va);
@@ 127,7 127,7 @@ if(q[1] == pa) panic("putmmu already set pte");
}
if(q == nil) {
q = (ulong*)(pteg+ptab.slotgen);
- ptab.slotgen = (ptab.slotgen + 8) & 0x3f;
+ ptab.slotgen = (ptab.slotgen + BY2PTE) & (BY2PTEG-1);
}
q[0] = ptehi;
q[1] = pa;
M mtx/trap.c => mtx/trap.c +41 -20
@@ 143,10 143,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
xfree(v);
}
-void faultpower(Ureg *ur, ulong addr, int read);
void syscall(Ureg* ureg);
void noted(Ureg*, ulong);
-void reset(void);
char *excname[] =
{
@@ 208,8 206,6 @@ char *regname[]={
"R30", "R31",
};
-static int lastecode;
-
void
trap(Ureg *ur)
{
@@ 232,7 228,28 @@ trap(Ureg *ur)
clockintr(ur);
break;
case CSYSCALL:
+ if(!user)
+ panic("syscall in kernel: srr1 0x%4.4uX\n", ur->srr1);
syscall(ur);
+ return; /* syscall() calls notify itself, don't do it again */
+ case CFPU:
+ if(!user || up == nil) {
+ dumpregs(ur);
+ panic("floating point in kernel");
+ }
+ switch(up->fpstate){
+ case FPinit:
+ fprestore(&initfp);
+ up->fpstate = FPactive;
+ break;
+ case FPinactive:
+ fprestore(&up->fpsave);
+ up->fpstate = FPactive;
+ break;
+ default:
+ panic("fpstate");
+ }
+ ur->srr1 |= MSR_FP;
break;
case CISI:
faultpower(ur, ur->pc, 1);
@@ 274,12 291,11 @@ trap(Ureg *ur)
panic("%s", excname[ecode]);
panic("unknown trap/intr: %d\n", ecode);
}
-lastecode = ecode;
- if(user && (up->procctl || up->nnote)){
- splhi();
+ /* restoreureg must execute at high IPL */
+ splhi();
+ if(user)
notify(ur);
- }
}
void
@@ 299,7 315,6 @@ faultpower(Ureg *ureg, ulong addr, int read)
panic("fault: 0x%lux", addr);
}
dumpregs(ureg);
-print("last ecode %x\n", lastecode);
sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr);
postnote(up, 1, buf, NDebug);
}
@@ 406,6 421,15 @@ fpexcname(Ureg *ur, ulong fpscr, char *buf)
return buf;
}
+void
+fpoff(Proc *p)
+{
+ Ureg *ur;
+
+ ur = p->dbgreg;
+ ur->srr1 &= ~MSR_FP;
+}
+
/*
* Fill in enough of Ureg to get a stack trace, and call a function.
* Used by debugging interface rdb.
@@ 510,6 534,7 @@ execregs(ulong entry, ulong ssize, ulong nargs)
ureg = up->dbgreg;
ureg->usp = (ulong)sp;
ureg->pc = entry;
+ ureg->srr1 &= ~MSR_FP;
return USTKTOP-BY2WD; /* address of user-level clock */
}
@@ 581,19 606,14 @@ dbgpc(Proc *p)
*/
#include "../port/systab.h"
-/*
- * Syscall should be called directly from assembler without going through trap().
- */
+/* TODO: make this trap a separate asm entry point, like on other RISC architectures */
void
syscall(Ureg* ureg)
{
char *e;
- ulong sp;
+ ulong sp;
long ret;
- int i, scallnr;
-
- if((ureg->srr1 & MSR_PR) == 0)
- panic("syscall: srr1 0x%4.4uX\n", ureg->srr1);
+ int i, scallnr;
m->syscall++;
up->insyscall = 1;
@@ 651,11 671,12 @@ syscall(Ureg* ureg)
if(scallnr == NOTED)
noted(ureg, *(ulong*)(sp+BY2WD));
- if(scallnr!=RFORK && (up->procctl || up->nnote)){
- splhi();
+ /* restoreureg must execute at high IPL */
+ splhi();
+ if(scallnr!=RFORK)
notify(ureg);
- }
}
+
/*
* Call user, if necessary, with note.
* Pass user the Ureg struct and the note on his stack.