kernel: make Page.txtflush into an array
To avoid a MAXMACH limit of 32 and make txtflush into an array for the bitmap. Provide portable macros for testing and clearing the bits: needtxtflush(), donetxtflush(). On pc/pc64, define inittxtflush()/settxtflush() as no-op macros, avoiding the storage overhead of the txtflush array alltogether.
This commit is contained in:
parent
6e64d30454
commit
6f9838a6a5
19 changed files with 46 additions and 42 deletions
|
@ -254,11 +254,10 @@ putmmu(uintptr va, uintptr pa, Page* page)
|
|||
/* clear out the current entry */
|
||||
mmuinvalidateaddr(PPN(va));
|
||||
|
||||
if((page->txtflush & (1<<m->machno)) != 0){
|
||||
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
|
||||
if(needtxtflush(page)){
|
||||
cachedwbse((void*)(page->pa|KZERO), BY2PG);
|
||||
cacheiinvse((void*)page->va, BY2PG);
|
||||
page->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(page);
|
||||
}
|
||||
//checkmmu(va, PPN(pa));
|
||||
splx(s);
|
||||
|
|
|
@ -460,11 +460,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
|
|||
flushasidva((uvlong)up->asid<<48 | va>>12);
|
||||
*pte = pa | PTEPAGE | PTEUSER | PTEPXN | PTENG | PTEAF |
|
||||
(((pa & PTEMA(7)) == PTECACHED)? PTESH(SHARE_INNER): PTESH(SHARE_OUTER));
|
||||
if(pg->txtflush & (1UL<<m->machno)){
|
||||
/* pio() sets PG_TXTFLUSH whenever a text pg has been written */
|
||||
if(needtxtflush(pg)){
|
||||
cachedwbinvse(kmap(pg), BY2PG);
|
||||
cacheiinvse((void*)va, BY2PG);
|
||||
pg->txtflush &= ~(1UL<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
|
|
@ -168,14 +168,14 @@ putmmu(uintptr va, uintptr pa, Page *pg)
|
|||
old = *e;
|
||||
*e = pa | L2VALID | L2USER | L2LOCAL;
|
||||
tmpunmap(l2);
|
||||
splx(s);
|
||||
if((old & L2VALID) != 0)
|
||||
flushpg((void *) va);
|
||||
if(pg->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(pg)){
|
||||
cleandse((void *) va, (void *) (va + BY2PG));
|
||||
invalise((void *) va, (void *) (va + BY2PG));
|
||||
pg->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -345,9 +345,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
|
|||
* rather than direct mapped.
|
||||
*/
|
||||
cachedwbinv();
|
||||
if(page->txtflush){
|
||||
if(needtxtflush(page)){
|
||||
cacheiinv();
|
||||
page->txtflush = 0;
|
||||
donetxtflush(page);
|
||||
}
|
||||
//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
|
||||
}
|
||||
|
|
|
@ -218,10 +218,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
|
|||
q[1] = pa;
|
||||
sync();
|
||||
|
||||
if(pg->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(pg)){
|
||||
dcflush((void*)pg->va, BY2PG);
|
||||
icflush((void*)pg->va, BY2PG);
|
||||
pg->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -322,9 +322,9 @@ putmmu(uintptr va, uintptr pa, Page* page)
|
|||
* rather than direct mapped.
|
||||
*/
|
||||
cachedwbinv();
|
||||
if(page->txtflush){
|
||||
if(needtxtflush(page)){
|
||||
cacheiinv();
|
||||
page->txtflush = 0;
|
||||
donetxtflush(page);
|
||||
}
|
||||
//print("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
|
||||
}
|
||||
|
|
|
@ -159,6 +159,9 @@ struct PMMU
|
|||
void *vmx;
|
||||
};
|
||||
|
||||
#define inittxtflush(p)
|
||||
#define settxtflush(p,c)
|
||||
|
||||
#include "../port/portdat.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#define BLOCKALIGN 8
|
||||
#define FPalign 16
|
||||
|
||||
/*
|
||||
* In 32-bit mode, the MAXMACH limit is 32 without
|
||||
* changing the way active.machs is defined and used
|
||||
* (unfortunately, it is also used in the port code).
|
||||
*/
|
||||
#define MAXMACH 32 /* max # cpus system can run */
|
||||
#define KSTACK 4096 /* Size of kernel stack */
|
||||
|
||||
|
|
|
@ -169,6 +169,9 @@ struct PMMU
|
|||
void *vmx;
|
||||
};
|
||||
|
||||
#define inittxtflush(p)
|
||||
#define settxtflush(p,c)
|
||||
|
||||
#include "../port/portdat.h"
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -523,7 +523,7 @@ fixedseg(uintptr va, ulong len)
|
|||
p->ref = 1;
|
||||
p->va = va;
|
||||
p->modref = 0;
|
||||
p->txtflush = ~0;
|
||||
settxtflush(p, 1);
|
||||
|
||||
k = kmap(p);
|
||||
memset((void*)VA(k), 0, BY2PG);
|
||||
|
|
|
@ -135,8 +135,7 @@ retry:
|
|||
}
|
||||
done:
|
||||
putpage(new);
|
||||
if(s->flushme)
|
||||
(*p)->txtflush = ~0;
|
||||
settxtflush(*p, s->flushme);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -202,8 +201,7 @@ fixfault(Segment *s, uintptr addr, int read)
|
|||
new = newpage(0, &s, addr);
|
||||
if(s == nil)
|
||||
return -1;
|
||||
if(s->flushme)
|
||||
new->txtflush = ~0;
|
||||
settxtflush(new, s->flushme);
|
||||
*pg = new;
|
||||
copypage(old, *pg);
|
||||
putpage(old);
|
||||
|
@ -242,8 +240,7 @@ mapphys(Segment *s, uintptr addr, int attr)
|
|||
pg.ref = 1;
|
||||
pg.va = addr;
|
||||
pg.pa = s->pseg->pa+(addr-s->base);
|
||||
if(s->flushme)
|
||||
pg.txtflush = ~0;
|
||||
settxtflush(&pg, s->flushme);
|
||||
|
||||
mmuphys = PPN(pg.pa) | PTEVALID;
|
||||
if((attr & SG_RONLY) == 0)
|
||||
|
|
|
@ -227,7 +227,7 @@ newpage(int clear, Segment **s, uintptr va)
|
|||
p->ref = 1;
|
||||
p->va = va;
|
||||
p->modref = 0;
|
||||
p->txtflush = 0;
|
||||
inittxtflush(p);
|
||||
|
||||
if(clear) {
|
||||
k = kmap(p);
|
||||
|
@ -345,7 +345,6 @@ cachedel(Image *i, uintptr daddr)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
Pte*
|
||||
ptecpy(Pte *old)
|
||||
{
|
||||
|
|
|
@ -329,10 +329,19 @@ struct Page
|
|||
uintptr va; /* Virtual address for user */
|
||||
uintptr daddr; /* Disc address on swap */
|
||||
Image *image; /* Associated text or swap image */
|
||||
ulong txtflush; /* Flush icache for putmmu */
|
||||
ushort refage; /* Swap reference age */
|
||||
char modref; /* Simulated modify/reference bits */
|
||||
char color; /* Cache coloring */
|
||||
|
||||
#ifndef inittxtflush
|
||||
/* Flush icache bitmap for putmmu() */
|
||||
ulong txtflush[(MAXMACH+31)/32];
|
||||
|
||||
#define inittxtflush(p) memset((p)->txtflush, 0, sizeof((p)->txtflush))
|
||||
#define settxtflush(p, c) if(c) memset((p)->txtflush, ~0, sizeof((p)->txtflush))
|
||||
#define needtxtflush(p) ((p)->txtflush[m->machno>>5] & (1 << (m->machno&0x1F)))
|
||||
#define donetxtflush(p) ((p)->txtflush[m->machno>>5] &= ~(1 << (m->machno&0x1F)))
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Swapalloc
|
||||
|
|
|
@ -718,8 +718,7 @@ segflush(void *va, uintptr len)
|
|||
pg = &pte->pages[off/BY2PG];
|
||||
pe = pg + len/BY2PG;
|
||||
while(pg < pe) {
|
||||
if(!pagedout(*pg))
|
||||
(*pg)->txtflush = ~0;
|
||||
settxtflush(*pg, !pagedout(*pg));
|
||||
pg++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ proc0(void*)
|
|||
k = kmap(p);
|
||||
memmove((void*)VA(k), initcode, sizeof(initcode));
|
||||
kunmap(k);
|
||||
p->txtflush = ~0;
|
||||
settxtflush(p, 1);
|
||||
segpage(up->seg[TSEG], p);
|
||||
up->seg[TSEG]->flushme = 1;
|
||||
|
||||
|
|
|
@ -245,10 +245,10 @@ putmmu(uintptr va, uintptr pa, Page *pg)
|
|||
q[0] = ptehi;
|
||||
q[1] = pa;
|
||||
|
||||
if(pg->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(pg)){
|
||||
dcflush((void*)pg->va, BY2PG);
|
||||
icflush((void*)pg->va, BY2PG);
|
||||
pg->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -389,9 +389,9 @@ putmmu(ulong tlbvirt, ulong tlbphys, Page *pg)
|
|||
x = gettlbp(tlbvirt, tlbent);
|
||||
if(x < 0) x = getrandom();
|
||||
puttlbx(x, entry->virt, entry->phys0, entry->phys1, PGSZ);
|
||||
if(pg->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(pg)){
|
||||
icflush((void*)pg->va, BY2PG);
|
||||
pg->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
|
|
@ -574,10 +574,11 @@ putmmu(uintptr va, uintptr pa, Page* page)
|
|||
*/
|
||||
l1cache->wb();
|
||||
|
||||
if(page->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(page)){
|
||||
cacheiinv();
|
||||
page->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(page);
|
||||
}
|
||||
|
||||
if (Debug)
|
||||
iprint("putmmu %#p %#p %#p\n", va, pa, PPN(pa)|x);
|
||||
}
|
||||
|
|
|
@ -176,14 +176,14 @@ putmmu(uintptr va, uintptr pa, Page *pg)
|
|||
old = *e;
|
||||
*e = pa | L2VALID | L2USER | L2LOCAL;
|
||||
tmpunmap(l2);
|
||||
splx(s);
|
||||
if((old & L2VALID) != 0)
|
||||
flushpg((void *) va);
|
||||
if(pg->txtflush & (1<<m->machno)){
|
||||
if(needtxtflush(pg)){
|
||||
cleandse((void *) va, (void *) (va + BY2PG));
|
||||
invalise((void *) va, (void *) (va + BY2PG));
|
||||
pg->txtflush &= ~(1<<m->machno);
|
||||
donetxtflush(pg);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Reference in a new issue