M alphapc/fns.h => alphapc/fns.h +1 -0
@@ 63,6 63,7 @@ ulong meminit(void);
void mmudump(void);
void mmuinit(void);
#define mmunewpage(x)
+void mmupark(void);
void mntdump(void);
void ns16552install(void);
void ns16552special(int, int, Queue**, Queue**, int (*)(Queue*, int));
M alphapc/main.c => alphapc/main.c +2 -11
@@ 233,18 233,8 @@ procsave(Proc *p)
if(p->fpstate == FPactive){
if(p->state == Moribund)
fpenab(0);
- else{
- /*
- * 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.
- */
+ else
savefpregs(&up->fpsave);
-//print("PS=%lux+", up->fpsave.fpstatus);
- }
p->fpstate = FPinactive;
}
@@ 256,6 246,7 @@ procsave(Proc *p)
* When this processor eventually has to get an entry from the
* trashed page tables it will crash.
*/
+ mmupark();
}
/* still to do */
M alphapc/mmu.c => alphapc/mmu.c +9 -4
@@ 74,6 74,14 @@ mmuswitch(Proc *proc)
icflush();
}
+/* point to protoype page map */
+void
+mmupark(void)
+{
+ setptb(origlvl1);
+ icflush();
+}
+
/*
* give all page table pages back to the free pool. This is called in sched()
* with palloc locked.
@@ 83,10 91,7 @@ mmurelease(Proc *proc)
{
Page *page, *next;
- /* point to protoype page map */
- setptb(origlvl1);
- icflush();
-
+ mmupark();
mmuptefree(proc);
proc->mmuused = 0;
if(proc->mmutop) {
M mtx/fns.h => mtx/fns.h +1 -0
@@ 54,6 54,7 @@ void insl(int, void*, int);
void intr(Ureg*);
void intrenable(int, void (*)(Ureg*, void*), void*, int, char*);
int ioalloc(int, int, int, char*);
+void iofree(int);
void ioinit(void);
int iprint(char*, ...);
int isaconfig(char*, int, ISAConf*);
M mtx/l.s => mtx/l.s +51 -4
@@ 56,6 56,8 @@
/* debugger sets R1 to top of usable memory +1 */
MOVW R1, memsize(SB)
+ BL kfpinit(SB)
+
/* set up Mach */
MOVW $mach0(SB), R(MACH)
ADD $(MACHSIZE-8), R(MACH), R1 /* set stack */
@@ 90,7 92,7 @@ tlbloop:
/* KZERO -> 0 */
MOVW $(KZERO|(0x7ff<<2)|2), R3
- MOVW $(0|(0<<3)|2), R4
+ MOVW $(PTEVALID|PTEWRITE), R4
MOVW R3, SPR(IBATU(0))
MOVW R4, SPR(IBATL(0))
MOVW R3, SPR(DBATU(0))
@@ 114,12 116,14 @@ tlbloop:
/* direct map last block, uncached, (?guarded) */
MOVW $((0xf<<28)|(0x7ff<<2)|2), R3
- MOVW $((0xf<<28)|(4<<3)|2), R4
- MOVW R3, SPR(IBATU(3))
- MOVW R4, SPR(IBATL(3))
+ MOVW $((0xf<<28)|PTE1_I|PTE1_G|PTE1_RW), R4
MOVW R3, SPR(DBATU(3))
MOVW R4, SPR(DBATL(3))
+ /* IBAT 3 unused */
+ MOVW R0, SPR(IBATU(3))
+ MOVW R0, SPR(IBATL(3))
+
/* enable MMU */
MOVW LR, R3
OR $KZERO, R3
@@ 131,6 135,49 @@ tlbloop:
RETURN
+TEXT kfpinit(SB), $0
+ MOVFL $0,FPSCR(7)
+ MOVFL $0xD,FPSCR(6) /* VE, OE, ZE */
+ MOVFL $0, FPSCR(5)
+ MOVFL $0, FPSCR(3)
+ MOVFL $0, FPSCR(2)
+ MOVFL $0, FPSCR(1)
+ MOVFL $0, FPSCR(0)
+
+ FMOVD $4503601774854144.0, F27
+ FMOVD $0.5, F29
+ FSUB F29, F29, F28
+ FADD F29, F29, F30
+ FADD F30, F30, F31
+ FMOVD F28, F0
+ FMOVD F28, F1
+ FMOVD F28, F2
+ FMOVD F28, F3
+ FMOVD F28, F4
+ FMOVD F28, F5
+ FMOVD F28, F6
+ FMOVD F28, F7
+ FMOVD F28, F8
+ FMOVD F28, F9
+ FMOVD F28, F10
+ FMOVD F28, F11
+ FMOVD F28, F12
+ FMOVD F28, F13
+ FMOVD F28, F14
+ FMOVD F28, F15
+ FMOVD F28, F16
+ FMOVD F28, F17
+ FMOVD F28, F18
+ FMOVD F28, F19
+ FMOVD F28, F20
+ FMOVD F28, F21
+ FMOVD F28, F22
+ FMOVD F28, F23
+ FMOVD F28, F24
+ FMOVD F28, F25
+ FMOVD F28, F26
+ RETURN
+
TEXT splhi(SB), $0
MOVW LR, R31
MOVW R31, 4(R(MACH)) /* save PC in m->splpc */
M mtx/main.c => mtx/main.c +3 -12
@@ 56,8 56,8 @@ machinit(void)
m->loopconst = 100000;
/* turn on caches (instruction only for now) */
- puthid0(gethid0() | BIT(16));
-//puthid0(gethid0() | BIT(16) | BIT(17)); /* and data */
+// puthid0(gethid0() | BIT(16));
+puthid0(gethid0() | BIT(16) | BIT(17)); /* and data */
active.machs = 1;
active.exiting = 0;
@@ 260,17 260,8 @@ void
procsave(Proc *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.
- */
+ if(p->state != Moribund)
fpsave(&up->fpsave);
- }
fpoff(p);
p->fpstate = FPinactive;
}
M mtx/mem.h => mtx/mem.h +18 -5
@@ 146,12 146,25 @@
#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()
+ * Second pte word; WIMG & PP(RW/RO) common to page table and BATs
*/
-#define PTEVALID 0 /* implied for putmmu -- real V bit in first pte word */
-#define PTEWRITE 2
-#define PTERONLY 3
-#define PTEUNCACHED BIT(26)
+#define PTE1_W BIT(25)
+#define PTE1_I BIT(26)
+#define PTE1_M BIT(27)
+#define PTE1_G BIT(28)
+
+#define PTE1_RW BIT(30)
+#define PTE1_RO BIT(31)
+
+/*
+ * PTE bits for fault.c. These belong to the second PTE word. Validity is
+ * implied for putmmu(), and we always set PTE0_V. PTEVALID is used
+ * here to set cache policy bits on a global basis.
+ */
+#define PTEVALID 0
+#define PTEWRITE PTE1_RW
+#define PTERONLY PTE1_RO
+#define PTEUNCACHED PTE1_I
/*
* Address spaces
M mtx/mmu.c => mtx/mmu.c +17 -1
@@ 94,9 94,10 @@ mmurelease(Proc* p)
}
void
-putmmu(ulong va, ulong pa, Page*)
+putmmu(ulong va, ulong pa, Page *pg)
{
int mp;
+ char *ctl;
ulong *p, *ep, *q, pteg;
ulong vsid, ptehi, x, hash;
@@ 133,6 134,21 @@ if(q[1] == pa) panic("putmmu already set pte");
q[1] = pa;
sync();
unlock(&ptab);
+
+ ctl = &pg->cachectl[m->machno];
+ switch(*ctl) {
+ case PG_NEWCOL:
+ default:
+ panic("putmmu: %d\n", *ctl);
+ break;
+ case PG_NOFLUSH:
+ break;
+ case PG_TXTFLUSH:
+ dcflush((void*)pg->va, BY2PG);
+ icflush((void*)pg->va, BY2PG);
+ *ctl = PG_NOFLUSH;
+ break;
+ }
}
int
M mtx/trap.c => mtx/trap.c +1 -2
@@ 314,7 314,6 @@ faultpower(Ureg *ureg, ulong addr, int read)
dumpregs(ureg);
panic("fault: 0x%lux", addr);
}
-dumpregs(ureg);
sprint(buf, "sys: trap: fault %s addr=0x%lux", read? "read" : "write", addr);
postnote(up, 1, buf, NDebug);
}
@@ 452,7 451,7 @@ _dumpstack(Ureg *ureg)
if(up == 0)
return;
- print("ktrace /kernel/path %.8lux %.8lux\n", ureg->pc, ureg->sp);
+ print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", ureg->pc, ureg->sp, ureg->lr);
i = 0;
for(l=(ulong)&l; l<(ulong)(up->kstack+KSTACK); l+=4){
v = *(ulong*)l;