M gnot/fns.h => gnot/fns.h +1 -0
@@ 14,6 14,7 @@ void firmware(void);
void flushcpucache(void);
#define flushpage(x) if(x)
int fpcr(int);
+ulong fpiar(void);
void fpregrestore(char*);
void fpregsave(char*);
void fprestore(FPsave*);
M gnot/l.s => gnot/l.s +0 -1
@@ 170,7 170,6 @@ TEXT fpcr(SB), $0
MOVL R1, FPCR
RTS
-
TEXT rfnote(SB), $0
MOVL uregp+0(FP), A7
M gnot/trap.c => gnot/trap.c +9 -2
@@ 79,6 79,7 @@ char*
excname(unsigned vo, ulong pc)
{
static char buf[32]; /* BUG: not reentrant! */
+ ulong fppc;
vo &= 0x0FFF;
vo >>= 2;
@@ 90,7 91,10 @@ excname(unsigned vo, ulong pc)
return buf;
}
if(49<=vo && vo<=54){
- sprint(buf, "fp: %s", fptrapname[vo-49]);
+ fppc = 0;
+ if(u)
+ fppc = *(ulong*)(u->fpsave.reg+8);
+ sprint(buf, "fp: %s fppc=0x%lux", fptrapname[vo-49], fppc);
return buf;
}
sprint(buf, "offset 0x%ux", vo<<2);
@@ 109,6 113,9 @@ trap(Ureg *ur)
u->dbgreg = ur;
if(user){
+ splhi();
+ procsave(u->p);
+ spllo();
sprint(buf, "sys: %s", excname(ur->vo, ur->pc));
postnote(u->p, 1, buf, NDebug);
}else{
@@ 174,7 181,7 @@ notify(Ureg *ur)
l = strlen(n->msg);
if(l > ERRLEN-15) /* " pc=0x12345678\0" */
l = ERRLEN-15;
- sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
+ sprint(n->msg+l, " pc=0x%lux", ur->pc);
}
if(n->flag!=NUser && (u->notified || u->notify==0)){
if(n->flag == NDebug)
M pc/dat.h => pc/dat.h +13 -1
@@ 45,7 45,19 @@ enum
struct FPsave
{
- uchar regs[108];
+ ushort control;
+ ushort r1;
+ ushort status;
+ ushort r2;
+ ushort tag;
+ ushort r3;
+ ulong pc;
+ ushort selector;
+ ushort r4;
+ ulong operand;
+ ushort oselector;
+ ushort r5;
+ uchar regs[80]; /* floating point registers */
};
struct Conf
M pc/fns.h => pc/fns.h +1 -0
@@ 16,6 16,7 @@ void fault386(Ureg*);
void faultinit(void);
void fclock(Ureg*);
void fclockinit(void);
+void fpenv(FPsave*);
void fpinit(void);
void fpoff(void);
void fprestore(FPsave*);
M pc/kbd.c => pc/kbd.c +14 -18
@@ 36,7 36,7 @@ enum {
Caps= Spec|0x64,
Num= Spec|0x65,
Middle= Spec|0x66,
- No= Spec|0x7F, /* no mapping */
+ No= 0x00, /* peter */
Home= KF|13,
Up= KF|14,
@@ 59,11 59,11 @@ uchar kbtab[] =
[0x18] 'o', 'p', '[', ']', '\n', Ctrl, 'a', 's',
[0x20] 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';',
[0x28] '\'', '`', Shift, '\\', 'z', 'x', 'c', 'v',
-[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, No,
+[0x30] 'b', 'n', 'm', ',', '.', '/', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
-[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home,
-[0x48] No, No, No, No, No, No, No, No,
-[0x50] No, No, No, No, No, No, No, KF|11,
+[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, '7',
+[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
+[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
};
@@ 75,11 75,11 @@ uchar kbtabshift[] =
[0x18] 'O', 'P', '{', '}', '\n', Ctrl, 'A', 'S',
[0x20] 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':',
[0x28] '"', '~', Shift, '|', 'Z', 'X', 'C', 'V',
-[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, No,
+[0x30] 'B', 'N', 'M', '<', '>', '?', Shift, '*',
[0x38] Latin, ' ', Ctrl, KF|1, KF|2, KF|3, KF|4, KF|5,
-[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, Home,
-[0x48] No, No, No, No, No, No, No, No,
-[0x50] No, No, No, No, No, No, No, KF|11,
+[0x40] KF|6, KF|7, KF|8, KF|9, KF|10, Num, KF|12, '7',
+[0x48] '8', '9', '-', '4', '5', '6', '+', '1',
+[0x50] '2', '3', '0', '.', No, No, No, KF|11,
[0x58] KF|12, No, No, No, No, No, No, No,
};
@@ 88,14 88,14 @@ uchar kbtabesc1[] =
[0x00] No, No, No, No, No, No, No, No,
[0x08] No, No, No, No, No, No, No, No,
[0x10] No, No, No, No, No, No, No, No,
-[0x18] No, No, No, No, No, Ctrl, No, No,
+[0x18] No, No, No, No, '\n', Ctrl, No, No,
[0x20] No, No, No, No, No, No, No, No,
-[0x28] No, No, No, No, No, No, No, No,
-[0x30] No, No, No, No, No, No, No, Print,
+[0x28] No, No, Shift, No, No, No, No, No,
+[0x30] No, No, No, No, No, '/', No, Print,
[0x38] Latin, No, No, No, No, No, No, No,
[0x40] No, No, No, No, No, No, Break, Home,
-[0x48] Up, Pgup, No, Down, No, Right, No, End,
-[0x50] Left, Pgdown, Ins, Del, No, No, No, No,
+[0x48] Up, Pgup, No, Left, No, Right, No, End,
+[0x50] Down, Pgdown, Ins, Del, No, No, No, No,
[0x58] No, No, No, No, No, No, No, No,
};
@@ 338,9 338,6 @@ kbdintr0(void)
if(esc1){
c = kbtabesc1[c];
esc1 = 0;
- if(!keyup)
- goto dochar;
- return 0;
} else if(esc2){
esc2--;
return 0;
@@ 373,7 370,6 @@ kbdintr0(void)
/*
* normal character
*/
-dochar:
if(!(c & Spec)){
if(ctl)
c &= 0x1f;
M pc/l.s => pc/l.s +5 -0
@@ 330,6 330,11 @@ TEXT fpstatus(SB),$0 /* get floating point status */
FSTSW AX
RET
+TEXT fpenv(SB),$0 /* save floating point environment without waiting */
+ MOVL p+0(FP),AX
+ FSTENV 0(AX)
+ RET
+
/*
* special traps
*/
M pc/main.c => pc/main.c +16 -5
@@ 287,16 287,27 @@ matherror(Ureg *ur)
*/
outb(0xF0, 0xFF);
- status = fpstatus() & 0xffff;
- msg = "unknown";
+ /*
+ * save floating point state to check out error
+ */
+ fpenv(&u->fpsave);
+ status = u->fpsave.status;
+
+ msg = 0;
for(i = 0; i < 8; i++)
if((1<<i) & status){
msg = mathmsg[i];
+ sprint(note, "sys: fp: %s fppc=0x%lux", msg, u->fpsave.pc);
+ postnote(u->p, 1, note, NDebug);
break;
}
- sprint(note, "sys: fp: %s, status 0x%ux, pc 0x%lux", msg, status, ur->pc);
-print("%s cr0 %lux\n", note, getcr0());
- postnote(u->p, 1, note, NDebug);
+ if(msg == 0){
+ sprint(note, "sys: fp: unknown fppc=0x%lux", u->fpsave.pc);
+ postnote(u->p, 1, note, NDebug);
+ }
+ if(ur->pc & KZERO)
+ panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,
+ u->fpsave.pc, ur->pc);
}
/*
M pc/trap.c => pc/trap.c +2 -2
@@ 110,9 110,9 @@ trapinit(void)
sethvec(11, intr11, SEGTG, 0);
sethvec(12, intr12, SEGTG, 0);
sethvec(13, intr13, SEGTG, 0);
- sethvec(14, intr14, SEGIG, 0);
+ sethvec(14, intr14, SEGIG, 0); /* page fault, interrupts off */
sethvec(15, intr15, SEGTG, 0);
- sethvec(16, intr16, SEGTG, 0);
+ sethvec(16, intr16, SEGIG, 0); /* math coprocessor, interrupts off */
/*
* device interrupts
M power/fptrap.c => power/fptrap.c +2 -1
@@ 30,6 30,7 @@ fptrap(Ureg *ur, ulong fcr31)
ulong iw, npc;
savefpregs(&u->fpsave);
+ u->p->fpstate = FPinactive; /* will get turned on again in trap() */
if((fcr31&(1<<17)) == 0)
return 0;
if(ur->cause & (1<<31))
@@ 45,7 46,7 @@ fptrap(Ureg *ur, ulong fcr31)
return 0;
}else
ur->pc += 4;
- restfpregs(&u->fpsave, fcr31);
+ u->fpsave.fpstatus = fcr31 & ~(1<<17);
}
return 1;
}
M power/trap.c => power/trap.c +24 -13
@@ 45,7 45,7 @@ char *excname[] =
/* the following is made up */
"trap: floating point exception" /* FPEXC */
};
-char *fpexcname(ulong);
+char *fpexcname(Ureg*, ulong, char*);
char *regname[]={
"STATUS", "PC",
@@ 77,7 77,7 @@ trap(Ureg *ur)
int ecode;
int user, x;
ulong fcr31;
- char buf[ERRLEN];
+ char buf[2*ERRLEN], buf1[ERRLEN];
SET(fcr31);
ecode = EXCCODE(ur->cause);
@@ 151,7 151,7 @@ trap(Ureg *ur)
if(user){
spllo();
if(ecode == FPEXC)
- sprint(buf, "sys: fp: %s FCR31 %lux", fpexcname(fcr31), fcr31);
+ sprint(buf, "sys: fp: %s", fpexcname(ur, fcr31, buf1));
else
sprint(buf, "sys: %s", excname[ecode]);
@@ 159,7 159,7 @@ trap(Ureg *ur)
}else{
print("%s %s pc=%lux\n", user? "user": "kernel", excname[ecode], ur->pc);
if(ecode == FPEXC)
- print("fp: %s FCR31 %lux\n", fpexcname(fcr31), fcr31);
+ print("fp: %s\n", fpexcname(ur, fcr31, buf1));
dumpregs(ur);
if(m->machno == 0)
spllo();
@@ 319,7 319,7 @@ intr(Ureg *ur)
}
char*
-fpexcname(ulong fcr31)
+fpexcname(Ureg *ur, ulong fcr31, char *buf)
{
static char *str[]={
"inexact operation",
@@ 329,15 329,26 @@ fpexcname(ulong fcr31)
"invalid operation",
};
int i;
+ char *s;
+ ulong fppc;
+ fppc = ur->pc;
+ if(ur->cause & (1<<31)) /* branch delay */
+ fppc += 4;
+ s = 0;
if(fcr31 & (1<<17))
- return "unimplemented operation";
- fcr31 >>= 7; /* trap enable bits */
- fcr31 &= (fcr31>>5); /* anded with exceptions */
- for(i=0; i<5; i++)
- if(fcr31 & (1<<i))
- return str[i];
- return "no floating point exception";
+ s = "unimplemented operation";
+ else{
+ fcr31 >>= 7; /* trap enable bits */
+ fcr31 &= (fcr31>>5); /* anded with exceptions */
+ for(i=0; i<5; i++)
+ if(fcr31 & (1<<i))
+ s = str[i];
+ }
+ if(s == 0)
+ return "no floating point exception";
+ sprint(buf, "%s fppc=0x%lux", s, fppc);
+ return buf;
}
void
@@ 396,7 407,7 @@ notify(Ureg *ur)
l = strlen(n->msg);
if(l > ERRLEN-15) /* " pc=0x12345678\0" */
l = ERRLEN-15;
- sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
+ sprint(n->msg+l, " pc=0x%lux", ur->pc);
}
if(n->flag!=NUser && (u->notified || u->notify==0)){
if(n->flag == NDebug)
M ss/faultsparc.c => ss/faultsparc.c +3 -3
@@ 28,8 28,8 @@ faultsparc(Ureg *ur)
/*
* According to the book, this isn't good enough. We'll see.
*/
- addr = getw2(SEVAR);
- ser = getw2(SER);
+ addr = getsysspace(SEVAR);
+ ser = getsysspace(SER);
if(ser&(SE_WRITE|SE_PROT))
read = 0;
}
@@ 62,7 62,7 @@ faultasync(Ureg *ur)
{
int user;
- print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getw2(ASER), getw2(ASEVAR), getw2(SER));
+ print("interrupt 15 ASER %lux ASEVAR %lux SER %lux\n", getsysspace(ASER), getsysspace(ASEVAR), getsysspace(SER));
dumpregs(ur);
/*
* Clear interrupt by toggling low bit of interrupt register
M ss/fns.h => ss/fns.h +3 -12
@@ 19,10 19,9 @@ void fpregsave(char*);
void fprestore(FPsave*);
void fpsave(FPsave*);
int fptrap(void);
-int getb2(ulong);
int getfpq(ulong*);
ulong getfsr(void);
-int getw2(ulong);
+ulong (*getsysspace)(ulong);
void intrinit(void);
void ioinit(void);
int kbdstate(IOQ*, int);
@@ 46,22 45,14 @@ void printinit(void);
#define procrestore(p)
#define procsave(p)
#define procsetup(x) ((p)->fpstate = FPinit)
-void putb2(ulong, int);
-void putcontext(int);
-void putcxreg(int);
void putcxsegm(int, ulong, int);
+void (*putenab)(ulong);
void putpmeg(ulong, ulong);
void putsegm(ulong, int);
+void (*putsysspace)(ulong, ulong);
void putstr(char*);
void putstrn(char*, long);
void puttbr(ulong);
-void putw2(ulong, ulong);
-void putw4(ulong, ulong);
-void putwC(ulong, ulong);
-void putwD16(ulong, ulong);
-void putwD(ulong, ulong);
-void putwE16(ulong, ulong);
-void putwE(ulong, ulong);
void systemreset(void);
void restfpregs(FPsave*, ulong);
void screeninit(void);
M ss/l.s => ss/l.s +2 -179
@@ 11,8 11,8 @@ TEXT start(SB), $-4
MOVW $KZERO, R7
MOVB R0, (R7, 3)
MOVW $(KZERO+BY2SEGM), R7
- MOVW $1, R8
- MOVB R8, (R7, 3)
+ MOVW $1, R9
+ MOVB R9, (R7, 3)
/* now mapped correctly. jmpl to where we want to be */
MOVW $setSB(SB), R2
MOVW $startvirt(SB), R7
@@ 333,183 333,6 @@ TEXT getpsr(SB), $0
MOVW PSR, R7
RETURN
-TEXT putcxreg(SB), $0
-
- MOVW $CONTEXT, R8
- MOVB R7, (R8, 2)
- RETURN
-
-TEXT putb2(SB), $0
-
- MOVW 4(FP), R8
- MOVB R8, (R7, 2)
- RETURN
-
-TEXT getb2(SB), $0
-
- MOVB (R7, 2), R7
- RETURN
-
-TEXT getw2(SB), $0
-
- MOVW (R7, 2), R7
- RETURN
-
-TEXT putw2(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 2)
- RETURN
-
-TEXT putw4(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 4)
- RETURN
-
-TEXT putw6(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 6)
- RETURN
-
-TEXT putw8(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 8)
- RETURN
-
-TEXT getw4(SB), $0
-
- MOVW (R7, 4), R7
- RETURN
-
-TEXT putwC(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xC)
- RETURN
-
-TEXT putwD(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xD)
- RETURN
-
-TEXT putw716(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- ADD $BY2PG, R7
- MOVW R8, (R7, 0x7)
- RETURN
-
-TEXT putwD16(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xD)
- RETURN
-
-TEXT putwE(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xE)
- RETURN
-
-TEXT putwE16(SB), $0
-
- MOVW 4(FP), R8
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- ADD $VACLINESZ, R7
- MOVW R8, (R7, 0xE)
- RETURN
-
TEXT putsegm(SB), $0
MOVW 4(FP), R8
M ss/mmu.c => ss/mmu.c +200 -33
@@ 5,16 5,29 @@
#include "fns.h"
#include "io.h"
+void compile(void);
+#define NCODE 1024
+static ulong code[NCODE];
+static ulong *codep = code;
+
+void (*putcontext)(ulong);
+void (*putenab)(ulong);
+ulong (*getenab)(void);
+void (*putpmegspace)(ulong, ulong);
+void (*putsysspace)(ulong, ulong);
+ulong (*getsysspace)(ulong);
+ulong (*flushcx)(ulong);
+ulong (*flushpg)(ulong);
+
struct
{
Lock;
- int init;
int lowpmeg;
KMap *free;
KMap arena[(IOEND-IOSEGM)/BY2PG];
}kmapalloc;
-#define NKLUDGE 12
+#define NKLUDGE 11 /* <= ((TOPPMEG-kmap.lowpmeg)/NCONTEXT) */
/*
* On SPARC, tlbpid i == context i-1 so that 0 means unallocated
@@ 112,21 125,14 @@ newpid(Proc *p)
}
void
-putcontext(int c)
-{
- putcxreg(c);
-}
-
-void
flushcontext(void)
{
- int i;
+ ulong a;
- /*
- * Clear context from cache
- */
- for(i=0; i<VACSIZE; i+=16*VACLINESZ)
- putwE16(i, 0);
+ a = 0;
+ do
+ a = flushcx(a);
+ while(a < VACSIZE);
}
void
@@ 141,10 147,11 @@ mmuinit(void)
{
ulong ktop, l, i, j, c, pte;
+ compile();
/*
- * TEMP: just map the first 4M of bank 0 for the kernel - philw
+ * xinit sets conf.npage0 to maximum kernel address
*/
- ktop = 4*1024*1024;
+ ktop = PADDR(conf.npage0);
/*
* First map lots of memory as kernel addressable in all contexts
*/
@@ 263,16 270,26 @@ print("putmmu %lux %d %s\n", tlbvirt, seg, p->text);
void
putpmeg(ulong virt, ulong phys)
{
- int i;
+ ulong a, evirt;
virt &= VAMASK;
virt &= ~(BY2PG-1);
+#ifdef asdf
+ if(conf.ss2)
+ putw6(virt, 0);
+ else
+ for(i=0; i<BY2PG; i+=16*VACLINESZ)
+ putwD16(virt+i, 0);
+#endif
/*
* Flush old entries from cache
*/
- for(i=0; i<BY2PG; i+=16*VACLINESZ)
- putwD16(virt+i, 0);
- putw4(virt, phys);
+ a = virt;
+ evirt = virt+BY2PG;
+ do
+ a = flushpg(a);
+ while(a < evirt);
+ putpmegspace(virt, phys);
}
void
@@ 280,14 297,12 @@ putpmegnf(ulong virt, ulong phys) /* no need to flush */
{
virt &= VAMASK;
virt &= ~(BY2PG-1);
- putw4(virt, phys);
+ putpmegspace(virt, phys);
}
-int nflushmmu;
void
flushmmu(void)
{
-nflushmmu++;
splhi();
u->p->newtlb = 1;
mapstack(u->p);
@@ 297,23 312,20 @@ nflushmmu++;
void
cacheinit(void)
{
- int c, i;
+ int i;
+ putcontext(0);
/*
* Initialize cache by clearing the valid bit
* (along with the others) in all cache entries
*/
- for(c=0; c<NCONTEXT; c++){ /* necessary? */
- putcontext(c);
- for(i=0; i<VACSIZE; i+=VACLINESZ)
- putw2(CACHETAGS+i, 0);
- }
- putcontext(0);
+ for(i=0; i<VACSIZE; i+=VACLINESZ)
+ putsysspace(CACHETAGS+i, 0);
/*
* Turn cache on
*/
- putb2(ENAB, getb2(ENAB)|ENABCACHE); /**/
+ putenab(getenab()|ENABCACHE); /**/
}
void
@@ 322,8 334,6 @@ kmapinit(void)
KMap *k;
int i;
- print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
-
kmapalloc.free = 0;
k = kmapalloc.arena;
for(i=0; i<(IOEND-IOSEGM)/BY2PG; i++,k++){
@@ 389,3 399,160 @@ invalidateu(void)
{
putpmeg(USERADDR, INVALIDPTE);
}
+
+/*
+ * Compile MMU code for this machine, since the MMU can only
+ * be addressed from parameterless machine instructions.
+ * What's wrong with MMUs you can talk to from C?
+ */
+
+/* op3 */
+#define LD 0
+#define ADD 0
+#define OR 2
+#define LDA 16
+#define LDUBA 17
+#define STA 20
+#define STBA 21
+#define JMPL 56
+/* op2 */
+#define SETHI 4
+
+void *compileconst(int, ulong, int); /* value to/from constant address */
+void *compileldaddr(int, int); /* value from parameter address */
+void *compilestaddr(int, int); /* value to parameter address */
+void *compile16(ulong, int); /* 16 stores of zero */
+void *compile1(ulong, int); /* 1 stores of zero */
+
+#define ret() {*codep++ = (2<<30)|(0<<25)|(JMPL<<19)|(15<<14)|(1<<13)|8;}
+#define nop() {*codep++ = (0<<30)|(0<<25)|(SETHI<<22)|(0>>10);}
+
+void
+compile(void)
+{
+ putcontext = compileconst(STBA, CONTEXT, 2);
+ getenab = compileconst(LDUBA, ENAB, 2);
+ putenab = compileconst(STBA, ENAB, 2);
+ putpmegspace = compilestaddr(STA, 4);
+ putsysspace = compilestaddr(STA, 2);
+ getsysspace = compileldaddr(LDA, 2);
+ if(conf.ss2){
+ flushpg = compile1(BY2PG, 6);
+ flushcx = compile16(VACLINESZ, 7);
+ }else{
+ flushpg = compile16(VACLINESZ, 0xD);
+ flushcx = compile16(VACLINESZ, 0xE);
+ }
+}
+
+void
+parameter(int param, int reg)
+{
+ param += 1; /* 0th parameter is 1st word on stack */
+ param *= 4;
+ /* LD #param(R1), Rreg */
+ *codep++ = (3<<30)|(reg<<25)|(LD<<19)|(1<<14)|(1<<13)|param;
+}
+
+void
+constant(ulong c, int reg)
+{
+ *codep++ = (0<<30)|(reg<<25)|(SETHI<<22)|(c>>10);
+ if(c & 0x3FF)
+ *codep++ = (2<<30)|(reg<<25)|(OR<<19)|(reg<<14)|(1<<13)|(c&0x3FF);
+}
+
+/*
+ * void f(int c) { *(word*,asi)addr = c } for stores
+ * ulong f(void) { return *(word*,asi)addr } for loads
+ */
+void*
+compileconst(int op3, ulong addr, int asi)
+{
+ void *a;
+
+ a = codep;
+ constant(addr, 8); /* MOVW $CONSTANT, R8 */
+ ret(); /* JMPL 8(R15), R0 */
+ /* in delay slot st or ld R7, (R8+R0, asi) */
+ *codep++ = (3<<30)|(7<<25)|(op3<<19)|(8<<14)|(asi<<5);
+ return a;
+}
+
+/*
+ * ulong f(ulong addr) { return *(word*,asi)addr }
+ */
+void*
+compileldaddr(int op3, int asi)
+{
+ void *a;
+
+ a = codep;
+ ret(); /* JMPL 8(R15), R0 */
+ /* in delay slot ld (R7+R0, asi), R7 */
+ *codep++ = (3<<30)|(7<<25)|(op3<<19)|(7<<14)|(asi<<5);
+ return a;
+}
+
+/*
+ * void f(ulong addr, int c) { *(word*,asi)addr = c }
+ */
+void*
+compilestaddr(int op3, int asi)
+{
+ void *a;
+
+ a = codep;
+ parameter(1, 8); /* MOVW (4*1)(FP), R8 */
+ ret(); /* JMPL 8(R15), R0 */
+ /* in delay slot st R8, (R7+R0, asi) */
+ *codep++ = (3<<30)|(8<<25)|(op3<<19)|(7<<14)|(asi<<5);
+ return a;
+}
+
+/*
+ * ulong f(ulong addr) { *addr=0; addr+=offset; return addr}
+ * offset can be anything
+ */
+void*
+compile1(ulong offset, int asi)
+{
+ void *a;
+
+ a = codep;
+ /* ST R0, (R7+R0, asi) */
+ *codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5);
+ if(offset < (1<<12)){
+ ret(); /* JMPL 8(R15), R0 */
+ /* in delay slot ADD $offset, R7 */
+ *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset;
+ }else{
+ constant(offset, 8);
+ ret(); /* JMPL 8(R15), R0 */
+ /* in delay slot ADD R8, R7 */
+ *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(0<<13)|8;
+ }
+ return a;
+}
+
+/*
+ * ulong f(ulong addr) { for(i=0;i<16;i++) {*addr=0; addr+=offset}; return addr}
+ * offset must be less than 1<<12
+ */
+void*
+compile16(ulong offset, int asi)
+{
+ void *a;
+ int i;
+
+ a = codep;
+ for(i=0; i<16; i++){
+ /* ST R0, (R7+R0, asi) */
+ *codep++ = (3<<30)|(0<<25)|(STA<<19)|(7<<14)|(asi<<5);
+ /* ADD $offset, R7 */
+ *codep++ = (2<<30)|(7<<25)|(ADD<<19)|(7<<14)|(1<<13)|offset;
+ }
+ ret(); /* JMPL 8(R15), R0 */
+ nop();
+ return a;
+}
M ss/trap.c => ss/trap.c +4 -4
@@ 58,7 58,7 @@ excname(ulong tbr)
if(m->fpunsafe==0 && u->p->fpstate!=FPactive)
panic("fptrap not active\n");
fsr = u->fpsave.fsr;
- sprint(excbuf, "fp: %s FQpc=0x%lux",
+ sprint(excbuf, "fp: %s fppc=0x%lux",
fptrapname[(fsr>>14)&7],
u->fpsave.q[0].a, fsr);
}
@@ 110,7 110,7 @@ trap(Ureg *ur)
tbr = (ur->tbr&0xFFF)>>4;
/* SS2 bug: flush cache line holding trap entry in table */
if(conf.ss2)
- putw2(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
+ putsysspace(CACHETAGS+((TRAPS+16*tbr)&(VACSIZE-1)), 0);
if(tbr > 16){ /* interrupt */
if(u && u->p->state==Running){
/* if active, FPop at head of Q is probably an excep */
@@ 407,7 407,7 @@ notify(Ureg *ur)
l = strlen(n->msg);
if(l > ERRLEN-15) /* " pc=0x12345678\0" */
l = ERRLEN-15;
- sprint(n->msg+l, " pc=0x%.8lux", ur->pc);
+ sprint(n->msg+l, " pc=0x%lux", ur->pc);
}
if(n->flag!=NUser && (u->notified || u->notify==0)){
if(n->flag == NDebug)
@@ 521,7 521,7 @@ syscall(Ureg *aur)
/* SS2 bug: flush cache line holding trap entry in table */
if(conf.ss2)
- putw2(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);
+ putsysspace(CACHETAGS+((TRAPS+16*128)&(VACSIZE-1)), 0);
if(u->p->fpstate == FPactive) {
fpquiet();
M ss/u.h => ss/u.h +1 -0
@@ 1,3 1,4 @@
+typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char uchar;
typedef unsigned long ulong;