M gnot/dat.h => gnot/dat.h +17 -0
@@ 16,6 16,8 @@ typedef struct KMap KMap;
typedef struct Label Label;
typedef struct List List;
typedef struct Lock Lock;
+typedef struct MMU MMU;
+typedef struct MMUCache MMUCache;
typedef struct Mach Mach;
typedef struct Mount Mount;
typedef struct Mtab Mtab;
@@ 337,6 339,20 @@ struct Proc
ulong pc; /* DEBUG only */
};
+struct MMU
+{
+ ulong va;
+ ulong pa;
+ int pid;
+};
+
+#define NMMU 16
+struct MMUCache
+{
+ ulong next;
+ MMU mmu[NMMU];
+};
+
#define NERR 15
#define NNOTE 5
#define NFD 100
@@ 360,6 376,7 @@ struct User
short nnote;
short notified; /* sysnoted is due */
int (*notify)(void*, char*);
+ MMUCache mc;
void *ureg;
};
M gnot/fns.h => gnot/fns.h +1 -0
@@ 51,6 51,7 @@ void firmware(void);
void flowctl(Queue*);
void flushcpucache(void);
void flushmmu(void);
+void flushmmucache(void);
void forkmod(Seg*, Seg*, Proc*);
int fpcr(int);
void fpsave(FPsave*);
M gnot/main.c => gnot/main.c +2 -0
@@ 31,6 31,7 @@ void unloadboot(void);
void
main(void)
{
+ u = 0;
unloadboot();
machinit();
mmuinit();
@@ 154,6 155,7 @@ userinit(void)
k = kmap(p->upage);
up = (User*)VA(k);
up->p = p;
+ up->mc.next = 0;
kunmap(k);
/*
M gnot/mmu.c => gnot/mmu.c +44 -0
@@ 12,6 12,17 @@ struct
KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */
}kmapalloc;
+void
+putxmmu(ulong tlbvirt, ulong tlbphys, int pid)
+{
+ if(pid != u->p->pid)
+ panic("putxmmu %ld %ld\n", pid, u->p->pid);
+ if(tlbvirt&KZERO)
+ panic("putmmu");
+ tlbphys |= VTAG(tlbvirt)<<24;
+ UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
+}
+
/*
* Called splhi, not in Running state
*/
@@ 19,6 30,7 @@ void
mapstack(Proc *p)
{
ulong tlbvirt, tlbphys;
+ ulong i;
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)))
panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);
@@ 27,6 39,14 @@ mapstack(Proc *p)
putkmmu(tlbvirt, tlbphys);
flushmmu();
u = (User*)USERADDR;
+
+ if(u->mc.next >= NMMU){
+ u->mc.next &= NMMU - 1;
+ for(i = u->mc.next; i < NMMU; i++)
+ putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);
+ }
+ for(i = 0; i < u->mc.next; i++)
+ putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);/**/
}
void
@@ 43,6 63,14 @@ putmmu(ulong tlbvirt, ulong tlbphys)
{
if(tlbvirt&KZERO)
panic("putmmu");
+ if(u){
+ MMU *mp;
+ mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]);
+ mp->pa = tlbphys;
+ mp->va = tlbvirt;
+ mp->pid = u->p->pid;
+ u->mc.next++;
+ }/**/
tlbphys |= VTAG(tlbvirt)<<24;
UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
}
@@ 56,6 84,22 @@ flushmmu(void)
}
void
+flushmmucache(void)
+{
+ if(u == 0)
+ panic("flushmmucache");
+ u->mc.next = 0;
+}
+
+void
+clearmmucache(void)
+{
+ if(u == 0)
+ panic("clearmmucache");
+ memset(&u->mc, 0, sizeof u->mc);
+}
+
+void
kmapinit(void)
{
KMap *k;
M gnot/proc.c => gnot/proc.c +1 -0
@@ 621,6 621,7 @@ kproc(char *name, void (*func)(void *), void *arg)
/*
* Save time: only copy u-> data and useful stack
*/
+ clearmmucache();
memcpy(up, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
M gnot/sysproc.c => gnot/sysproc.c +2 -0
@@ 41,6 41,7 @@ sysfork(ulong *arg)
/*
* Save time: only copy u-> data and useful stack
*/
+ clearmmucache();
memcpy((void*)upa, u, sizeof(User));
n = USERADDR+BY2PG - (ulong)&lastvar;
n = (n+32) & ~(BY2WD-1); /* be safe & word align */
@@ 361,6 362,7 @@ sysexec(ulong *arg)
unlock(o);
flushmmu();
+ clearmmucache();
((Ureg*)UREGADDR)->pc = exec.entry;
sp = (ulong*)(USTKTOP - ssize);
*--sp = nargs;