## diffname ss/mmu.c 1990/1223
## diff -e /dev/null /n/bootesdump/1990/1223/sys/src/9/sparc/mmu.c
0a
#include "u.h"
#include "lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
struct
{
Lock;
int init;
KMap *free;
KMap arena[4*1024*1024/BY2PG]; /* kernel mmu maps up to 4MB */
}kmapalloc;
/*
* Called splhi, not in Running state
*/
void
mapstack(Proc *p)
{
ulong tlbvirt, tlbphys;
ulong next;
MMU *mm, *mn, *me;
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)))
panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va);
tlbvirt = USERADDR;
tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL;
putkmmu(tlbvirt, tlbphys);
u = (User*)USERADDR;
/*
* if not a kernel process and this process was not the
* last process on this machine, flush & preload mmu
*/
if(!p->kp && p!=m->lproc){
flushmmu();
/*
* preload the MMU with the last (up to) NMMU user entries
* previously faulted into it for this process.
*/
mn = &u->mc.mmu[u->mc.next&(NMMU-1)];
me = &u->mc.mmu[NMMU];
if(u->mc.next >= NMMU){
for(mm = mn; mm < me; mm++)
UMAP[mm->va] = mm->pa;
}
for(mm = u->mc.mmu; mm < mn; mm++)
UMAP[mm->va] = mm->pa;
m->lproc = p;
}
}
void
putkmmu(ulong tlbvirt, ulong tlbphys)
{
if(!(tlbvirt&KZERO))
panic("putkmmu");
tlbvirt &= ~KZERO;
KMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
}
void
putmmu(ulong tlbvirt, ulong tlbphys)
{
if(tlbvirt&KZERO)
panic("putmmu");
tlbphys |= VTAG(tlbvirt)<<24;
tlbvirt = (tlbvirt&0x003FE000L)>>2;
if(u){
MMU *mp;
int s;
s = splhi();
mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]);
mp->pa = tlbphys;
mp->va = tlbvirt;
u->mc.next++;
splx(s);
}
UMAP[tlbvirt] = tlbphys;
}
void
flushmmu(void)
{
flushcpucache();
*PARAM &= ~TLBFLUSH_;
*PARAM |= TLBFLUSH_;
}
void
clearmmucache(void)
{
if(u == 0)
panic("flushmmucache");
u->mc.next = 0;
}
void
kmapinit(void)
{
KMap *k;
int i, e;
if(kmapalloc.init == 0){
k = &kmapalloc.arena[0];
k->va = KZERO|(4*1024*1024-256*1024-BY2PG);
k->next = 0;
kmapalloc.free = k;
kmapalloc.init = 1;
return;
}
e = (4*1024*1024 - 256*1024)/BY2PG; /* screen lives at top 256K */
i = (((ulong)ialloc(0, 0))&~KZERO)/BY2PG;
print("%lud free map registers\n", e-i);
kmapalloc.free = 0;
for(k=&kmapalloc.arena[i]; i<e; i++,k++){
k->va = i*BY2PG|KZERO;
kunmap(k);
}
}
KMap*
kmap(Page *pg)
{
KMap *k;
lock(&kmapalloc);
k = kmapalloc.free;
if(k == 0){
dumpstack();
panic("kmap");
}
kmapalloc.free = k->next;
unlock(&kmapalloc);
k->pa = pg->pa;
putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL);
return k;
}
void
kunmap(KMap *k)
{
k->pa = 0;
lock(&kmapalloc);
k->next = kmapalloc.free;
kmapalloc.free = k;
putkmmu(k->va, INVALIDPTE);
unlock(&kmapalloc);
}
void
invalidateu(void)
{
putkmmu(USERADDR, INVALIDPTE);
}
.
## diffname ss/mmu.c 1990/1226
## diff -e /n/bootesdump/1990/1223/sys/src/9/sparc/mmu.c /n/bootesdump/1990/1226/sys/src/9/sparc/mmu.c
158c
putpmeg(USERADDR, INVALIDPTE);
.
151c
putpmeg(k->va, INVALIDPTE);
.
146a
ulong pte;
int i;
.
143a
KMap*
kmap(Page *pg)
{
return kmap1(pg, PTEMAINMEM);
}
.
140c
/*
* Cache is virtual and a pain to deal with.
* Must avoid having the same entry in the cache twice, so
* must use NOCACHE or else extreme cleverness elsewhere.
*/
putpmeg(k->va, PPN(k->pa)|PTEVALID|PTEKERNEL|PTEWRITE|PTENOCACHE|flag);
.
127c
kmap1(Page *pg, ulong flag)
.
120,121c
k = kmapalloc.arena;
for(i=0; i<(IOEND-IOSEGM)/BY2PG; i++,k++){
k->va = IOSEGM+i*BY2PG;
.
108,118c
print("low pmeg %d\n", kmapalloc.lowpmeg);
.
106c
int i;
.
97,99c
int i;
/*
* Initialize cache by clearing the valid bit
* (along with the others) in all cache entries
*/
for(i=0; i<0x1000; i++)
putw2(CACHETAGS+(i<<4), 0);
/*
* Turn cache on
*/
putb2(ENAB, getb2(ENAB)|ENABCACHE); /**/
.
95c
cacheinit(void)
.
89,91c
splhi();
/* easiest is to forget what pid we had.... */
memset(u->p->pidonmach, 0, sizeof u->p->pidonmach);
/* ....then get a new one by trying to map our stack */
mapstack(u->p);
spllo();
.
83c
/*
* kludge part 2: make sure we've got a valid segment
*/
if(tlbvirt>=TSTKTOP || (UZERO+BY2SEGM<=tlbvirt && tlbvirt<(TSTKTOP-BY2SEGM)))
panic("putmmu %lux", tlbvirt);
putpmeg(tlbvirt, tlbphys);
m->pidhere[tp] = 1;
p->state = Running;
spllo();
.
76,81c
splhi();
p = u->p;
/* if(p->state != Running)
panic("putmmu state %lux %lux %s\n", u, p, statename[p->state]);
*/
p->state = MMUing;
tp = p->pidonmach[m->machno];
if(tp == 0){
tp = newpid(p);
p->pidonmach[m->machno] = tp;
.
68,74c
short tp;
Proc *p;
.
64a
.
59,62c
ulong l, i, j, c, pte;
/*
* First map lots of memory as kernel addressable in all contexts
*/
i = 0; /* used */
for(c=0; c<NCONTEXT; c++)
for(i=0; i<conf.maxialloc/BY2SEGM; i++)
putcxsegm(c, KZERO+i*BY2SEGM, i);
kmapalloc.lowpmeg = i;
/*
* Make sure cache is turned on for kernel
*/
pte = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
for(i=0; i<conf.maxialloc/BY2PG; i++)
putpmeg(KZERO+i*BY2PG, pte+i);
/*
* Create invalid pmeg; use highest segment
*/
putsegm(INVALIDSEGM, INVALIDPMEG);
for(i=0; i<PG2SEGM; i++)
putpmeg(INVALIDSEGM+i*BY2PG, INVALIDPTE);
for(c=0; c<NCONTEXT; c++){
putcontext(c);
putsegm(INVALIDSEGM, INVALIDPMEG);
/*
* Invalidate user addresses
*/
/*
for(l=UZERO; l<KZERO; l+=BY2SEGM)
putsegm(l, INVALIDPMEG);
*/
putsegm(0x0000, INVALIDPMEG);
/*
* One segment for screen
*/
putsegm(SCREENSEGM, SCREENPMEG);
if(c == 0){
pte = PTEVALID|PTEWRITE|PTEKERNEL|PTENOCACHE|
PTEIO|((DISPLAYRAM>>PGSHIFT)&0xFFFF);
for(i=0; i<PG2SEGM; i++)
putpmeg(SCREENSEGM+i*BY2PG, pte+i);
}
/*
* First page of IO space includes ROM; be careful
*/
putsegm(IOSEGM0, IOPMEG0); /* IOSEGM == ROMSEGM */
if(c == 0){
pte = PTEVALID|PTEKERNEL|PTENOCACHE|
PTEIO|((EPROM>>PGSHIFT)&0xFFFF);
for(i=0; i<PG2ROM; i++)
putpmeg(IOSEGM0+i*BY2PG, pte+i);
for(; i<PG2SEGM; i++)
putpmeg(IOSEGM0+i*BY2PG, INVALIDPTE);
}
/*
* Remaining segments for IO and kmap
*/
for(j=1; j<NIOSEGM; j++){
putsegm(IOSEGM0+j*BY2SEGM, IOPMEG0+j);
if(c == 0)
for(i=0; i<PG2SEGM; i++)
putpmeg(IOSEGM0+j*BY2SEGM+i*BY2PG, INVALIDPTE);
}
}
putcontext(0);
.
57c
mmuinit(void)
.
55a
.
52,53c
if(m->pidhere[pid] == 0)
return;
print("purge pid %d\n", pid);
memset(m->pidhere, 0, sizeof m->pidhere);
putcontext(pid-1);
/*
* Clear context from cache
*/
for(i=0; i<0x1000; i++)
putwE((i<<4), 0);
print("purge done\n");
.
39,50c
void
purgepid(int pid)
{
int i, rpid;
.
36,37c
putsegm(UZERO, kmapalloc.lowpmeg+(2*i));
putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+(2*i)+1);
for(j=0; j<PG2SEGM; j++){
putpmeg(UZERO+j*BY2PG, INVALIDPTE);
putpmeg((TSTKTOP-BY2SEGM)+j*BY2PG, INVALIDPTE);
}
return i;
}
.
33,34c
* kludge: each context is allowed 2 pmegs, one for text and one for stack
.
31a
/*
* Process must be non-interruptible
*/
int
newpid(Proc *p)
{
int i, j;
Proc *sp;
i = m->lastpid+1;
if(i >= NCONTEXT+1)
i = 1;
sp = m->pidproc[i];
if(sp){
sp->pidonmach[m->machno] = 0;
purgepid(i);
}
m->pidproc[i] = p;
m->lastpid = i;
print("new context %d\n", i);
.
30a
}
.
27,29c
/* don't set m->pidhere[*tp] because we're only writing U entry */
tlbphys = PPN(p->upage->pa)|PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
putcontext(tp-1);
putpmeg(USERADDR, tlbphys);
.
24a
tp = p->pidonmach[m->machno];
if(tp == 0){
tp = newpid(p);
p->pidonmach[m->machno] = tp;
}
.
21,23c
short tp;
ulong tlbphys;
.
15a
* On SPARC, tlbpid i == context i-1 so that 0 means unallocated
*/
int newpid(Proc*);
void purgepid(int);
/*
.
12c
KMap arena[(IOEND-IOSEGM)/BY2PG];
.
10a
int lowpmeg;
.
5a
#include "io.h"
.
## diffname ss/mmu.c 1990/1227
## diff -e /n/bootesdump/1990/1226/sys/src/9/sparc/mmu.c /n/bootesdump/1990/1227/sys/src/9/sparc/mmu.c
271c
return kmappa(pg->pa, PTEMAINMEM);
.
264c
putpmeg(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|PTENOCACHE|flag);
.
258c
k->pa = pa;
.
246c
kmappa(ulong pa, ulong flag)
.
236d
202a
putpmeg(ulong virt, ulong phys)
{
int i;
virt &= VAMASK;
virt &= ~(BY2PG-1);
/*
* Flush old entries from cache
*/
for(i=0; i<0x100; i++)
putwD(virt+(i<<4), 0);
putw4(virt, phys);
}
void
.
171,173d
134,135c
.
131,132c
for(l=UZERO; l<(KZERO&VAMASK); l+=BY2SEGM)
.
66a
putcontext(i-1);
.
42a
/*
* putw4(USERADDR, tlbphys) might be good enough but
* there is that fuss in pexit/pwait() copying between
* u areas and that might surprise any cache entries
*/
.
## diffname ss/mmu.c 1990/1231
## diff -e /n/bootesdump/1990/1227/sys/src/9/sparc/mmu.c /n/bootesdump/1990/1231/sys/src/9/sparc/mmu.c
215a
if(u && u->p)
m->pidhere[u->p->pidonmach[m->machno]] = 1; /* UGH! */
.
207a
int tp;
.
199,200d
184,187d
85a
putcontext(int c)
{
m->pidhere[c] = 1;
putcxreg(c);
}
void
.
71d
## diffname ss/mmu.c 1991/0108
## diff -e /n/bootesdump/1990/1231/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0108/sys/src/9/sparc/mmu.c
177a
/*
* Lance
*/
putsegm(LANCESEGM, LANCEPMEG);
.
## diffname ss/mmu.c 1991/0109
## diff -e /n/bootesdump/1991/0108/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0109/sys/src/9/sparc/mmu.c
202c
if(tlbvirt>=TSTKTOP || (UZERO+4*BY2SEGM<=tlbvirt && tlbvirt<(TSTKTOP-BY2SEGM)))
.
106c
/* print("purge done\n");/**/
.
98c
/* print("purge pid %d\n", pid);/**/
.
78c
for(k=0; k<4; k++)
putpmeg(UZERO+k*BY2SEGM+j*BY2PG, INVALIDPTE);
.
75,76c
for(j=0; j<4; j++)
putsegm(UZERO, kmapalloc.lowpmeg+(2*i)+j);
putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+(2*i)+4);
.
73c
* kludge: each context is allowed 5 pmegs, four for text & data and one for stack
.
71a
/* print("new pid %d\n", i); /**/
.
58c
int i, j, k;
.
## diffname ss/mmu.c 1991/0110
## diff -e /n/bootesdump/1991/0109/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0110/sys/src/9/sparc/mmu.c
290a
#endif
splx(s);
.
289a
s = splhi();
#ifdef stupid
{
int i, c, d;
c = u->p->pidonmach[m->machno];
/*
* Flush old entries from cache
*/
for(d=0; d<NCONTEXT; d++){
putcontext(d);
for(i=0; i<0x100; i+=16)
putwD16(k->va+(i<<4), 0);
}
putcontext(c-1);
if(u && u->p)
m->pidhere[c] = 1; /* UGH! */
putw4(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|PTENOCACHE|flag);
}
#else
.
274a
ulong s;
.
262a
print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
.
249,250c
for(c=0; c<NCONTEXT; c++){ /* necessary? */
putcontext(c);
for(i=0; i<0x1000; i++)
putw2(CACHETAGS+(i<<4), 0);
}
putcontext(0);
.
243c
int c, i;
.
232a
flushcontext();
tp = u->p->pidonmach[m->machno];
if(tp)
pidtime[tp] = 0;
.
231a
int tp;
.
222,223c
for(i=0; i<0x100; i+=16)
putwD16(virt+(i<<4), 0);
.
205,206c
if(tlbvirt>=TSTKTOP || (UZERO+(NKLUDGE-1)*BY2SEGM<=tlbvirt && tlbvirt<(TSTKTOP-BY2SEGM))){
pprint("putmmu %lux", tlbvirt);
pexit("Suicide", 0);
}
.
181,184d
132d
104,109c
flushcontext();
.
101d
98a
/*
* Clear context from cache
*/
for(i=0; i<0x1000; i+=16)
putwE16((i<<4), 0);
}
void
purgepid(int pid)
{
.
97c
int i;
.
95c
flushcontext(void)
.
90c
m->pidhere[c+1] = 1;
.
80c
for(k=0; k<NKLUDGE-1; k++)
.
76,78c
for(j=0; j<NKLUDGE-1; j++)
putsegm(UZERO+j*BY2SEGM, kmapalloc.lowpmeg+(NKLUDGE*(i-1))+j);
putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+(NKLUDGE*(i-1))+(NKLUDGE-1));
.
74c
* kludge: each context is allowed NKLUDGE pmegs, NKLUDGE-1 for text & data and 1 for stack
.
72d
68a
pidtime[i] = m->ticks;
.
61,63c
t = ~0;
i = 1+((m->ticks)&(NCONTEXT-1)); /* random guess */
for(j=1; j<NTLBPID; j++)
if(pidtime[j] < t){
i = j;
t = pidtime[j];
}
.
58a
ulong t;
.
44,46c
* shouldn't need putpmeg because nothing has been mapped at
* USERADDR in this context except this page. however, it crashes.
.
39,40c
panic("mapstack %s %d %lux 0x%lux 0x%lux", p->text, p->pid, p->upage, p->upage->pa, p->upage->va);
.
22a
int pidtime[NTLBPID]; /* should be per m */
.
16a
#define NKLUDGE 8
.
## diffname ss/mmu.c 1991/0111
## diff -e /n/bootesdump/1991/0110/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0111/sys/src/9/sparc/mmu.c
332d
312,330d
213c
pexit("Suicide", 1);
.
160a
* Invalidate high kernel addresses
*/
for(l=conf.maxialloc; l<IOSEGM0; l+=BY2SEGM)
putsegm(l, INVALIDPMEG);
#endif
/*
.
159a
#ifdef doesntwork
.
156d
79a
.
17c
#define NKLUDGE 12
.
## diffname ss/mmu.c 1991/0112
## diff -e /n/bootesdump/1991/0111/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0112/sys/src/9/sparc/mmu.c
222a
/*
* Prepare mmu up to this address
*/
tp--; /* now tp==context */
tp = tp*NKLUDGE;
l = UZERO+p->nmmuseg*BY2SEGM;
for(j=p->nmmuseg; j<=seg; j++){
putsegm(l, kmapalloc.lowpmeg+tp+j);
for(k=0; k<PG2SEGM; k++,l+=BY2PG)
putpmeg(l, INVALIDPTE);
}
p->nmmuseg = seg+1;
put:
.
219,220c
if(TSTKTOP-BY2SEGM<=tlbvirt && tlbvirt<TSTKTOP) /* stack; easy */
goto put;
/* UZERO is known to be zero here */
if(tlbvirt < UZERO+p->nmmuseg*BY2SEGM) /* in range; easy */
goto put;
seg = tlbvirt/BY2SEGM;
if(seg >= (UZERO/BY2SEGM)+(NKLUDGE-1)){
pprint("putmmu %lux\n", tlbvirt);
print("putmmu %lux %d %s\n", tlbvirt, seg, p->text);
.
207a
ulong seg, l;
int j, k;
.
91,92c
return i+1;
.
85,89c
putsegm(UZERO+j*BY2SEGM, INVALIDPMEG);
putsegm(TSTKTOP-BY2SEGM, kmapalloc.lowpmeg+NKLUDGE*i+(NKLUDGE-1));
for(j=0; j<PG2SEGM; j++)
.
83a
i--; /* now i==context */
p->nmmuseg = 0;
.
82c
* kludge: each context is allowed NKLUDGE pmegs.
* NKLUDGE-1 for text & data and 1 for stack.
* initialize by giving just a stack segment.
.
## diffname ss/mmu.c 1991/0115
## diff -e /n/bootesdump/1991/0112/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0115/sys/src/9/sparc/mmu.c
263,264d
236,237c
tp = (tp-1)*NKLUDGE; /* now tp==base of pmeg area for this proc */
.
118,120d
99d
79d
74,75c
purgepid(i); /* also does putcontext */
.
72c
if(sp)
.
## diffname ss/mmu.c 1991/01151
## diff -e /n/bootesdump/1991/0115/sys/src/9/sparc/mmu.c /n/bootesdump/1991/01151/sys/src/9/sparc/mmu.c
155,162d
## diffname ss/mmu.c 1991/0507
## diff -e /n/bootesdump/1991/0201/sys/src/9/sparc/mmu.c /n/bootesdump/1991/0507/sys/src/9/slc/mmu.c
52a
void
mmurelease(Proc *p)
{
memset(p->pidonmach, 0, sizeof p->pidonmach);
}
.
## diffname ss/mmu.c 1991/0706
## diff -e /n/bootesdump/1991/0507/sys/src/9/slc/mmu.c /n/bootesdump/1991/0706/sys/src/9/slc/mmu.c
197c
putmmu(ulong tlbvirt, ulong tlbphys, Page *pg)
.
35a
if(p->newtlb) {
flushcontext();
tp = u->p->pidonmach[m->machno];
if(tp)
pidtime[tp] = 0;
/* easiest is to forget what pid we had.... */
memset(u->p->pidonmach, 0, sizeof u->p->pidonmach);
p->newtlb = 0;
}
.
24a
void flushcontext(void);
.
## diffname ss/mmu.c 1991/0928
## diff -e /n/bootesdump/1991/0706/sys/src/9/slc/mmu.c /n/bootesdump/1991/0928/sys/src/9/slc/mmu.c
53c
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0)
.
## diffname ss/mmu.c 1991/1007
## diff -e /n/bootesdump/1991/0928/sys/src/9/slc/mmu.c /n/bootesdump/1991/1007/sys/src/9/slc/mmu.c
275,281c
u->p->newtlb = 1;
.
273a
nflushmmu++;
.
269a
putpmegnf(ulong virt, ulong phys) /* no need to flush */
{
virt &= VAMASK;
virt &= ~(BY2PG-1);
putw4(virt, phys);
}
int nflushmmu;
void
.
245c
putpmegnf(l, INVALIDPTE);
.
108c
putpmegnf((TSTKTOP-BY2SEGM)+j*BY2PG, INVALIDPTE);
.
83c
for(j=1; t && j<NTLBPID; j++)
.
67a
int tp;
tp = p->pidonmach[m->machno];
if(tp)
pidtime[tp] = 0;
/* easiest is to forget what pid we had.... */
.
61c
putpmegnf(USERADDR, tlbphys);
.
58,59c
* Don't need to flush cache because no other page has been
* mapped at USERADDR in this context; can call putpmegnf.
.
39,44c
mmurelease(p);
.
25a
void putpmegnf(ulong, ulong);
.
## diffname ss/mmu.c 1992/0101
## diff -e /n/bootesdump/1991/1007/sys/src/9/slc/mmu.c /n/bootesdump/1992/0101/sys/src/9/slc/mmu.c
357a
/*
* Here we know it's a permanent entry and can be cached.
*/
.
356c
kmapperm(Page *pg)
.
349,352c
return kmappa(pg->pa, PTEMAINMEM|PTENOCACHE);
.
343a
s = splhi();
putpmeg(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|flag);
splx(s);
return k;
}
KMap*
kmap(Page *pg)
{
.
## diffname ss/mmu.c 1992/0321
## diff -e /n/bootesdump/1992/0101/sys/src/9/slc/mmu.c /n/bootesdump/1992/0321/sys/src/9/slc/mmu.c
2c
#include "../port/lib.h"
.
## diffname ss/mmu.c 1992/0619
## diff -e /n/bootesdump/1992/0321/sys/src/9/slc/mmu.c /n/bootesdump/1992/0619/sys/src/9/slc/mmu.c
320c
print("low pmeg %d high pmeg %d\n", kmapalloc.lowpmeg, TOPPMEG);
.
165a
.
157c
ktop /= BY2PG;
for(i=0; i < ktop; i++)
.
152a
.
151a
.
150c
for(i=0; i < ktop/BY2SEGM; i++)
.
145a
* TEMP: just map the first 4M of bank 0 for the kernel - philw
*/
ktop = 4*1024*1024;
/*
.
143c
ulong ktop, l, i, j, c, pte;
.
139d
## diffname ss/mmu.c 1992/0711
## diff -e /n/bootesdump/1992/0619/sys/src/9/slc/mmu.c /n/bootesdump/1992/0711/sys/src/9/slc/mmu.c
381,383d
290,291d
266d
224a
USED(pg);
.
79c
int i, j;
.
## diffname ss/mmu.c 1992/0722
## diff -e /n/bootesdump/1992/0711/sys/src/9/slc/mmu.c /n/bootesdump/1992/0722/sys/src/9/slc/mmu.c
273,274c
for(i=0; i<VACSIZE; i+=16*VACLINESZ)
putwD16(virt+i, 0);
.
147c
ktop = 8*1024*1024;
.
145c
* TEMP: just map the first 8M of bank 0 for the kernel - philw
.
## diffname ss/mmu.c 1992/0724
## diff -e /n/bootesdump/1992/0722/sys/src/9/slc/mmu.c /n/bootesdump/1992/0724/sys/src/9/slc/mmu.c
308,309c
for(i=0; i<VACSIZE; i+=VACLINESZ)
putw2(CACHETAGS+i, 0);
.
273c
for(i=0; i<BY2PG; i+=16*VACLINESZ)
.
147c
ktop = 4*1024*1024;
.
145c
* TEMP: just map the first 4M of bank 0 for the kernel - philw
.
128,129c
for(i=0; i<VACSIZE; i+=16*VACLINESZ)
putwE16(i, 0);
.
## diffname ss/mmu.c 1992/0806
## diff -e /n/bootesdump/1992/0724/sys/src/9/slc/mmu.c /n/bootesdump/1992/0806/sys/src/9/slc/mmu.c
390a
}
/*
* 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;
.
325,326d
316c
putenab(getenab()|ENABCACHE); /**/
.
306,311c
for(i=0; i<VACSIZE; i+=VACLINESZ)
putsysspace(CACHETAGS+i, 0);
.
301a
putcontext(0);
.
300c
int i;
.
290d
286d
283c
putpmegspace(virt, phys);
.
273,275c
a = virt;
evirt = virt+BY2PG;
do
a = flushpg(a);
while(a < evirt);
putpmegspace(virt, phys);
.
269a
#ifdef asdf
if(conf.ss2)
putw6(virt, 0);
else
for(i=0; i<BY2PG; i+=16*VACLINESZ)
putwD16(virt+i, 0);
#endif
.
266c
ulong a, evirt;
.
147c
ktop = PADDR(conf.npage0);
.
145c
* xinit sets conf.npage0 to maximum kernel address
.
143a
compile();
.
125,129c
a = 0;
do
a = flushcx(a);
while(a < VACSIZE);
.
123c
ulong a;
.
115,120d
17c
#define NKLUDGE 11 /* <= ((TOPPMEG-kmap.lowpmeg)/NCONTEXT) */
.
11d
7a
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);
.
## diffname ss/mmu.c 1992/0807
## diff -e /n/bootesdump/1992/0807/sys/src/9/slc/mmu.c /n/bootesdump/1992/0807/sys/src/9/ss/mmu.c
443,444c
flushpg = compile16(conf.vaclinesize, 0xD);
flushcx = compile16(conf.vaclinesize, 0xE);
.
441c
flushcx = compile16(conf.vaclinesize, 7);
.
322c
for(i=0; i<conf.vacsize; i+=conf.vaclinesize)
.
277,283d
180c
for(c=0; c<conf.ncontext; c++){
.
159c
for(c=0; c<conf.ncontext; c++)
.
135c
while(a < conf.vacsize);
.
97,98c
nc = conf.ncontext;
i = 1+((m->ticks)&(nc-1)); /* random guess */
nc++;
for(j=1; t && j<nc; j++)
.
92c
int i, j, nc;
.
## diffname ss/mmu.c 1992/0812
## diff -e /n/bootesdump/1992/0807/sys/src/9/ss/mmu.c /n/bootesdump/1992/0812/sys/src/9/ss/mmu.c
358a
}
ulong
kmapregion(ulong pa, ulong n, ulong flag)
{
KMap *k;
ulong va;
int i, j;
/*
* kmap's are initially in reverse order so rearrange them.
*/
i = (n+(BY2PG-1))/BY2PG;
va = 0;
for(j=i-1; j>=0; j--){
k = kmappa(pa+j*BY2PG, flag);
if(va && va != k->va+BY2PG)
systemreset();
va = k->va;
}
return va;
.
334,335c
for(i=0; i<(IOEND-IOSEGM0)/BY2PG; i++,k++){
k->va = IOSEGM0+i*BY2PG;
.
223a
NKLUDGE = ((TOPPMEG-kmapalloc.lowpmeg)/conf.ncontext);
if(NKLUDGE>11)NKLUDGE=11;
.
216c
for(j=0; j<NIOSEGM; j++){
.
214c
* Segments for IO and kmap
.
196,205d
194c
putsegm(ROMSEGM, ROMPMEG);
.
192c
* Map ROM
.
165a
if(PADDR(ktop) & (BY2SEGM-1))
kmapalloc.lowpmeg++;
.
30c
int NKLUDGE;
.
27c
KMap arena[(IOEND-IOSEGM0)/BY2PG];
.
## diffname ss/mmu.c 1992/0813
## diff -e /n/bootesdump/1992/0812/sys/src/9/ss/mmu.c /n/bootesdump/1992/0813/sys/src/9/ss/mmu.c
217d
203c
putpmeg(ROMSEGM+i*BY2PG, INVALIDPTE);
.
201c
putpmeg(ROMSEGM+i*BY2PG, pte+i);
.
199c
PTEIO|PPN(EPROM);
.
166c
if(ktop & (BY2SEGM-1))
.
## diffname ss/mmu.c 1992/0911
## diff -e /n/bootesdump/1992/0813/sys/src/9/ss/mmu.c /n/bootesdump/1992/0911/sys/src/9/ss/mmu.c
386,567d
353a
void
kunmap(KMap *k)
{
k->pa = 0;
lock(&kmapalloc);
k->next = kmapalloc.free;
kmapalloc.free = k;
putpme(k->va, INVALIDPTE, 1);
unlock(&kmapalloc);
}
.
349c
putpme(k->va, PPN(pa)|PTEVALID|PTEKERNEL|PTEWRITE|flag, 1);
.
327,328c
for(va = IOSEGM; va < IOSEGM + IOSEGSIZE; va += BY2PG, k++){
k->va = va;
.
323c
ulong va;
.
318a
struct
{
Lock;
KMap *free;
KMap arena[IOSEGSIZE/BY2PG];
}kmapalloc;
.
303,316c
putpme(USERADDR, INVALIDPTE, 1);
.
301c
invalidateu(void)
.
295,296c
c = u->p->ctxonmach[m->machno];
if(c == 0)
panic("flushmmu");
while(p = c->pmeg){
c->pmeg = p->cnext;
freepmeg(p, 1);
mkfirst(&m->plist, p);
}
.
293a
Ctx *c;
Pmeg *p;
.
286,288c
Ctx *c;
ulong tlbphys;
Pmeg *pm, *f, **l;
if(p->upage->va != (USERADDR|(p->pid&0xFFFF)) && p->pid != 0)
panic("mapstack %s %d %lux 0x%lux 0x%lux",
p->text, p->pid, p->upage, p->upage->pa, p->upage->va);
/* free a pmeg if a process needs one */
if(m->needpmeg){
pm = (Pmeg*)m->plist;
if(c = pm->ctx){
/* remove from context list */
l = &c->pmeg;
for(f = *l; f; f = f->cnext){
if(f == pm){
*l = f->cnext;
break;
}
l = &f->cnext;
}
/* flush cache & remove mappings */
putctx(c);
freepmeg(pm, 1);
}
m->needpmeg = 0;
}
/* give up our context if it is unclean */
if(p->newtlb){
c = p->ctxonmach[m->machno];
if(c)
freectx(c, 1);
p->newtlb = 0;
}
/* set to this proc's context */
c = p->ctxonmach[m->machno];
if(c == 0)
allocctx(p);
else
putctx(c);
/* make sure there's a mapping for u-> */
tlbphys = PPN(p->upage->pa)|PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
putpmegspace(USERADDR, tlbphys);
u = (User*)USERADDR;
.
284c
mapstack(Proc *p)
.
282a
/*
* set up context for a process
*/
.
270,280c
c = p->ctxonmach[m->machno];
if(c == 0)
return;
freectx(c, 1);
mkfirst(&m->clist, c);
.
268c
Ctx *c;
.
266c
mmurelease(Proc *p)
.
264a
/*
* give up our mmu context
*/
.
259,262c
m->cctx = ctx = xalloc(conf.ncontext * sizeof(Ctx));
for(i = 0; i < conf.ncontext; i++, ctx++){
ctx->index = i;
add(&m->clist, ctx);
}
putctx(m->cctx);
.
252,257c
m->pmeg = p = xalloc((INVALIDPMEG - fp) * sizeof(Pmeg));
m->pfirst = fp;
for(; fp < INVALIDPMEG; fp++, p++){
p->index = fp;
add(&m->plist, p);
.
250c
* allocate MMU management data for this CPU
.
248a
.
238,247c
for(c = 0; c < conf.ncontext; c++){
putcontext(c);
for(va = UZERO; va < (KZERO & VAMASK); va += BY2SEGM)
putsegspace(va, INVALIDPMEG);
for(va = ktop; va < IOSEGM; va += BY2SEGM)
putsegspace(va, INVALIDPMEG);
.
236c
* invalidate everything outside the kernel in every context
.
234a
.
219,233c
/*
* Invalidate all entries in all other pmegs
*/
for(j = fp; j < conf.npmeg; j++){
putsegspace(INVALIDSEGM, j);
for(va = INVALIDSEGM; va < INVALIDSEGM+BY2SEGM; va += BY2PG)
putpme(va, INVALIDPTE, 1);
.
215,217c
fp = i;
.
186,213c
i = fp;
for(va = IOSEGM; va < IOSEGM+IOSEGSIZE; va += BY2SEGM)
putsegspace(va, i++);
.
180,184c
for(c = 0; c < conf.ncontext; c++){
.
178c
* allocate pmegs for kmap'ing
.
172,175c
va = ROUNDUP(ktop, BY2SEGM);
for(; ktop < va; ktop += BY2PG)
putpme(ktop, INVALIDPTE, 1);
.
170c
* invalidate rest of kernel's PMEG
.
165,168d
160,163c
pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
i = 0;
for(va = KZERO; va < ktop; va += BY2PG, i++)
putpme(va, pme+i, 1);
.
158c
* Make sure cache is turned on for kernel
.
156c
ktop = PGROUND(conf.npage0);
i = 0;
for(c = 0; c < conf.ncontext; c++){
i = 0;
for(va = KZERO; va < ktop; va += BY2SEGM)
putcxsegm(c, va, i++);
}
fp = i;
.
154c
* First map kernel text, data, bss, and xalloc regions.
* xinit sets conf.npage0 to end of these.
.
152a
.
151a
conf.ncontext = 1; /**/
.
150c
int c, i, j;
ulong va, ktop, pme;
int fp; /* first free pmeg */
Pmeg *p;
Ctx *ctx;
.
147a
cacheinit(void)
{
int i;
for(i=0; i<conf.vacsize; i+=conf.vaclinesize)
putsysspace(CACHETAGS+i, 0);
/*
* Turn cache on
*/
putenab(getenab()&~ENABCACHE);
}
/*
* set up initial mappings and a the LRU lists for contexts and pmegs
*/
void
.
146a
/*
* Initialize cache by clearing the valid bit
* (along with the others) in all cache entries
*/
.
143,144c
ulong x, v;
Pmeg *p;
int s;
USED(pg);
s = splhi();
v = virt & ~(BY2SEGM-1);
x = getsegspace(v);
if(x == INVALIDPMEG)
p = allocpmeg(v);
else
p = &m->pmeg[x - m->pfirst];
if(virt < p->lo)
p->lo = virt;
if(virt > p->hi)
p->hi = virt;
putpme(virt, phys, 1);
splx(s);
.
141c
putmmu(ulong virt, ulong phys, Page *pg)
.
139a
/*
* stuff an entry into a pmeg
*/
static void
putpme(ulong virt, ulong phys, int flush)
{
virt = virt & ~(BY2PG-1);
if(flush)
flushpage(virt);
putpmegspace(virt, phys);
}
/*
* put a mapping into current context
*/
.
136,137c
a = flushpg(a);
while(a < evirt);
.
134c
static void
flushpage(ulong virt)
{
ulong a, evirt;
a = virt;
evirt = virt+BY2PG;
.
132c
putcontext(c->index);
m->cctx = c;
}
.
129,130c
static void
putctx(Ctx *c)
.
114,126c
static void
freectx(Ctx *c, int flush)
{
Pmeg *p;
putctx(c);
/* give back mappings */
while(p = c->pmeg){
c->pmeg = p->cnext;
freepmeg(p, flush);
mkfirst(&m->plist, p);
}
/* flush u-> */
flushpage(USERADDR);
/* detach from process */
c->proc->ctxonmach[m->machno] = 0;
c->proc = 0;
.
96,112c
c = (Ctx*)m->clist;
putctx(c);
if(c->proc)
freectx(c, 1);
c->proc = proc;
c->proc->ctxonmach[m->machno] = c;
mklast(&m->clist, c);
return c;
}
.
92,94c
Ctx *c;
.
89,90c
static Ctx*
allocctx(Proc *proc)
.
87c
* get a context for a process.
.
85a
static void
freepmeg(Pmeg *p, int flush)
{
ulong x;
/* invalidate any used PTE's, flush cache */
for(x = p->lo; x <= p->hi; x += BY2PG)
putpme(x, INVALIDPTE, flush);
/* invalidate segment pointer */
putsegspace(p->virt, INVALIDPMEG);
p->hi = 0;
p->lo = 0;
p->cnext = 0;
p->ctx = 0;
p->virt = 0;
}
.
79,83c
virt = virt & ~(BY2SEGM-1);
for(;;){
p = (Pmeg*)m->plist;
c = p->ctx;
if(c == 0)
break;
m->needpmeg = 1;
sched();
splhi();
}
/* add to current context */
p->ctx = m->cctx;
p->cnext = m->cctx->pmeg;
m->cctx->pmeg = p;
p->virt = virt;
p->lo = virt;
p->hi = virt;
putsegspace(p->virt, p->index);
mklast(&m->plist, p);
return p;
.
77c
Pmeg *p;
Ctx *c;
.
74,75c
/*
* add a pmeg to the current context for the given address
*/
static Pmeg*
allocpmeg(ulong virt)
.
62,71c
*list = entry;
.
57,60c
/* remove from list */
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
/* chain back in */
entry->prev = first->prev;
entry->next = first;
first->prev->next = entry;
first->prev = entry;
}
/*
* move to front of use list
*/
static void
mkfirst(List **list, List *entry)
{
List *first;
first = *list;
if(entry == first)
return; /* already at front */
/* unchain */
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
/* chain back in */
entry->prev = first->prev;
entry->next = first;
first->prev->next = entry;
first->prev = entry;
*list = entry;
}
/*
* remove from list
*/
static void
remove(List **list, List *entry)
{
if(*list == entry)
*list = entry->next;
entry->prev->next = entry->next;
entry->next->prev = entry->prev;
}
/*
* add to list
*/
static void
add(List **list, List *entry)
{
List *first;
first = *list;
if(first == 0){
entry->prev = entry;
entry->next = entry;
} else {
entry->prev = first->prev;
entry->next = first;
first->prev->next = entry;
first->prev = entry;
.
52,54c
ulong lo; /* low water mark of used entries */
ulong hi; /* high water mark of used entries */
ushort index; /* which Pmeg this is */
ulong virt; /* virtual address this Pmeg represents */
Ctx *ctx; /* context Pmeg belongs to */
Pmeg *cnext; /* next pmeg used in same context */
};
#define HOWMANY(x, y) (((x)+((y)-1))/(y))
#define ROUNDUP(x, y) (HOWMANY((x), (y))*(y))
static Pmeg* allocpmeg(ulong);
static void freepmeg(Pmeg*, int);
static Ctx* allocctx(Proc*);
static void freectx(Ctx*, int);
static void putpme(ulong, ulong, int);
static void mklast(List**, List*);
static void mkfirst(List**, List*);
static void remove(List**, List*);
static void add(List**, List*);
static void flushpage(ulong);
static void putctx(Ctx*);
/*
* move to end of use list
*/
static void
mklast(List **list, List *entry)
{
List *first;
first = *list;
if(entry == first){
*list = first->next;
return;
.
49,50c
List; /* MUST BE FIRST IN STRUCTURE!! */
.
46,47c
struct Pmeg
.
44c
* a Sparc PMEG description
.
41c
Proc *proc; /* process that owns this context */
Pmeg *pmeg; /* list of pmeg's used by this context */
ushort index; /* which context this is */
};
.
36,39c
/*
* a Sparc context description
*/
struct Ctx
{
List; /* MUST BE FIRST IN STRUCTURE!! */
.
34a
/*
* doubly linked list for LRU algorithm
*/
struct List
{
List *prev; /* less recently used */
List *next; /* more recently used */
};
.
33c
* WARNING: Even though all MMU data is in the mach structure or
* pointed to by it, this code will not work on a multi-processor
* without modification.
.
31a
doprint(buf, buf+sizeof(buf), fmt, (&fmt+1));
rawputs(buf);
}
static void
rawpanic(char *fmt, ...)
{
char buf[PRINTSIZE];
int s;
s = splhi();
doprint(buf, buf+sizeof(buf), fmt, (&fmt+1));
rawputs("rawpanic: ");
rawputs(buf);
systemreset();
splx(s);
}
.
30c
void
rawprint(char *fmt, ...)
{
char buf[PRINTSIZE];
.
24,28c
while(*s)
rawputc(*s++);
}
.
22c
void
rawputs(char *s)
.
13,20c
static int
rawputc(int c)
{
if(c == '\n')
rawputc('\r');
while((getsysspaceb(SERIALPORT+4) & (1<<2)) == 0)
delay(10);
putsysspaceb(SERIALPORT+6, c);
if(c == '\n')
delay(20);
return c;
}
.
8,11c
#define SERIALPORT 0xF0000000 /* MMU bypass */
.
1,6c
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
.
## diffname ss/mmu.c 1992/0912
## diff -e /n/bootesdump/1992/0911/sys/src/9/ss/mmu.c /n/bootesdump/1992/0912/sys/src/9/ss/mmu.c
635d
568a
kmapalloc.inited = 1;
.
554a
int inited;
.
539d
519a
if(c->proc != p || p->ctxonmach[m->machno] != c)
panic("mapstack c->proc != p\n");
.
516c
c = allocctx(p);
.
496a
if(f != pm)
panic("mapstack f != pm\n");
.
467d
417,425d
405a
* Invalidate all entries in all other pmegs
*/
for(j = fp; j < conf.npmeg; j++){
putsegspace(INVALIDSEGM, j);
for(va = 0; va < BY2SEGM; va += BY2PG)
putpmegspace(INVALIDSEGM+va, INVALIDPTE);
}
if(conf.base1 < conf.npage1){
/*
* map kernel region 1, this may overlap kernel region 0's
* PMEG's.
*/
ktop1 = PGROUND(conf.npage1);
kbot1 = conf.base1 & ~(BY2SEGM - 1);
if(kbot1 < ktop)
kbot1 = ktop;
for(c = 0; c < conf.ncontext; c++){
i = fp;
putcontext(c);
for(va = kbot1; va < ktop1; va += BY2SEGM)
putsegspace(va, i++);
}
fp = i;
/*
* Make sure cache is turned on for kernel region 1
*/
kbot1 = conf.base1 & ~(BY2PG - 1);
pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
i = PPN(kbot1 & ~KZERO);
for(va = kbot1; va < ktop1; va += BY2PG, i++)
putpme(va, pme+i, 1);
}
/*
.
399c
* invalidate rest of kernel's region 0's PMEG's
.
391c
* Make sure cache is turned on for kernel region 0
.
378,379c
* map all of kernel region 0.
.
374c
/*
* mmuinit is entered with PMEG's 0 & 1 providing mappng
* for virtual addresses KZERO<->KZERO+2*BY2SEGM to physical
* 0<->2*BY2SEGM
*/
.
369c
ulong va, ktop, pme, kbot1, ktop1;
.
359c
putenab(getenab()|ENABCACHE);
.
334a
if(x != p->index)
panic("putmmu %d/%d\n", x, p->index);
}
.
333c
else {
.
304a
.
283a
mkfirst(&m->clist, c);
.
275d
272a
if(p->ctx != c)
panic("freectx: %lux/%lux\n", p->ctx, c);
.
269a
if(c->proc->ctxonmach[m->machno] != c)
panic("freectx %lux %lux\n", c->proc->ctxonmach[m->machno], c);
.
257a
}
if(c->pmeg)
panic("allocctx c->pmeg %lux\n", c->pmeg);
.
256c
if(c->proc){
.
243a
mkfirst(&m->plist, p);
.
232c
/* invalidate any used PTE's */
.
220c
p->lo = virt + BY2PG;
.
207,208c
if(p->ctx == 0)
.
202d
162,174d
## diffname ss/mmu.c 1992/0913
## diff -e /n/bootesdump/1992/0912/sys/src/9/ss/mmu.c /n/bootesdump/1992/0913/sys/src/9/ss/mmu.c
660a
ulong va;
KMap *k;
/*
* avoid an alias: if part of kernel memory, just return map
*/
va = pg->pa|KZERO;
if((KZERO<=va && va<(ulong)end) ||
(conf.base0<=va && va<conf.npage0) ||
(conf.base1<=va && va<conf.npage1)){
lock(&kmapalloc);
k = kmapalloc.free;
if(k == 0){
dumpstack();
panic("kmap");
}
kmapalloc.free = k->next;
unlock(&kmapalloc);
k->va = va;
k->pa = va;
return k;
}
.
633c
if(pa != k->pa)
putpme(k->va, INVALIDPTE, 1);
.
628a
ulong pa;
pa = k->pa;
.
439a
ktop = ktop1;
.
414a
if(conf.base0 < conf.npage0){
/*
* map kernel region 0, this may overlap kernel text image
*/
ktop1 = PGROUND(conf.npage0);
kbot1 = conf.base0 & ~(BY2SEGM - 1);
if(kbot1 < ktop)
kbot1 = ktop;
for(c = 0; c < conf.ncontext; c++){
i = fp;
putcontext(c);
for(va = kbot1; va < ktop1; va += BY2SEGM)
putsegspace(va, i++);
}
fp = i;
/*
* Make sure cache is turned on for kernel region 0
*/
kbot1 = conf.base0 & ~(BY2PG - 1);
pme = PTEVALID|PTEWRITE|PTEKERNEL|PTEMAINMEM;
i = PPN(kbot1 & ~KZERO);
for(va = kbot1; va < ktop1; va += BY2PG, i++)
putpme(va, pme+i, 1);
ktop = ktop1;
}
.
392c
* Make sure cache is turned on for program and data
.
382c
ktop = PGROUND((ulong)end);
.
380c
* map all of text image
.
244d
242c
if(c->proc)
.
## diffname ss/mmu.c 1992/0914
## diff -e /n/bootesdump/1992/0913/sys/src/9/ss/mmu.c /n/bootesdump/1992/0914/sys/src/9/ss/mmu.c
8,52d
## diffname ss/mmu.c 1993/0123
## diff -e /n/bootesdump/1992/0914/sys/src/9/ss/mmu.c /n/bootesdump/1993/0123/sys/src/9/ss/mmu.c
327,329c
* mmuinit is entered with PMEG's 0-3 providing mapping
* for virtual addresses KZERO<->KZERO+4*BY2SEGM to physical
* 0<->4*BY2SEGM
.
## diffname ss/mmu.c 1993/0501 # deleted
## diff -e /n/bootesdump/1993/0123/sys/src/9/ss/mmu.c /n/fornaxdump/1993/0501/sys/src/brazil/ss/mmu.c
1,676d
|