pc, pc64: exclude memory regions with unusual MTRR cache attributes
Use the MTRR registers to exclude memory ranges that do not have the expected cache attributes: RAM -> writeback UMB -> uncached UPA -> uncached
This commit is contained in:
parent
4ca5e1b3a3
commit
99696c414a
4 changed files with 48 additions and 0 deletions
|
@ -101,6 +101,7 @@ void mfence(void);
|
||||||
void mmuinit(void);
|
void mmuinit(void);
|
||||||
ulong* mmuwalk(ulong*, ulong, int, int);
|
ulong* mmuwalk(ulong*, ulong, int, int);
|
||||||
char* mtrr(uvlong, uvlong, char *);
|
char* mtrr(uvlong, uvlong, char *);
|
||||||
|
char* mtrrattr(uvlong, uvlong *);
|
||||||
void mtrrclock(void);
|
void mtrrclock(void);
|
||||||
int mtrrprint(char *, long);
|
int mtrrprint(char *, long);
|
||||||
void mtrrsync(void);
|
void mtrrsync(void);
|
||||||
|
|
|
@ -320,6 +320,27 @@ umbexclude(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mtrrexclude(int type, char *expect)
|
||||||
|
{
|
||||||
|
uvlong base, top, next, pa;
|
||||||
|
char *attr;
|
||||||
|
|
||||||
|
for(base = memmapnext(-1, type); base != -1; base = memmapnext(base, type)){
|
||||||
|
top = base + memmapsize(base, 0);
|
||||||
|
for(pa = base; pa < top; pa = next){
|
||||||
|
next = top;
|
||||||
|
attr = mtrrattr(pa, &next);
|
||||||
|
if(attr != nil && strcmp(attr, expect) != 0){
|
||||||
|
if(next > top)
|
||||||
|
next = top;
|
||||||
|
memmapadd(pa, next - pa, MemReserved);
|
||||||
|
}
|
||||||
|
base = pa;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
e820scan(void)
|
e820scan(void)
|
||||||
{
|
{
|
||||||
|
@ -362,6 +383,9 @@ e820scan(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* RAM needs to be writeback */
|
||||||
|
mtrrexclude(MemRAM, "wb");
|
||||||
|
|
||||||
for(base = memmapnext(-1, MemRAM); base != -1; base = memmapnext(base, MemRAM)){
|
for(base = memmapnext(-1, MemRAM); base != -1; base = memmapnext(base, MemRAM)){
|
||||||
size = memmapsize(base, BY2PG) & ~(BY2PG-1);
|
size = memmapsize(base, BY2PG) & ~(BY2PG-1);
|
||||||
if(size != 0)
|
if(size != 0)
|
||||||
|
@ -376,6 +400,7 @@ ramscan(uintptr pa, uintptr top, uintptr chunk)
|
||||||
{
|
{
|
||||||
ulong save, pat, seed, *v, *k0;
|
ulong save, pat, seed, *v, *k0;
|
||||||
int i, n, w;
|
int i, n, w;
|
||||||
|
char *attr;
|
||||||
|
|
||||||
pa += chunk-1;
|
pa += chunk-1;
|
||||||
pa &= ~(chunk-1);
|
pa &= ~(chunk-1);
|
||||||
|
@ -389,6 +414,10 @@ ramscan(uintptr pa, uintptr top, uintptr chunk)
|
||||||
|
|
||||||
pat = 0x12345678UL;
|
pat = 0x12345678UL;
|
||||||
for(; pa < top; pa += chunk){
|
for(; pa < top; pa += chunk){
|
||||||
|
attr = mtrrattr(pa, nil);
|
||||||
|
if(attr != nil && strcmp(attr, "wb") != 0)
|
||||||
|
goto Skip;
|
||||||
|
|
||||||
/* write pattern */
|
/* write pattern */
|
||||||
seed = pat;
|
seed = pat;
|
||||||
if((v = vmap(pa, chunk)) == nil)
|
if((v = vmap(pa, chunk)) == nil)
|
||||||
|
@ -420,6 +449,7 @@ ramscan(uintptr pa, uintptr top, uintptr chunk)
|
||||||
Bad:
|
Bad:
|
||||||
vunmap(v, chunk);
|
vunmap(v, chunk);
|
||||||
|
|
||||||
|
Skip:
|
||||||
if(pa+chunk <= 16*MB)
|
if(pa+chunk <= 16*MB)
|
||||||
memmapadd(pa, chunk, MemUMB);
|
memmapadd(pa, chunk, MemUMB);
|
||||||
|
|
||||||
|
@ -488,6 +518,12 @@ meminit0(void)
|
||||||
*/
|
*/
|
||||||
if(e820scan() < 0)
|
if(e820scan() < 0)
|
||||||
ramscan(MemMin, -((uintptr)MemMin), 4*MB);
|
ramscan(MemMin, -((uintptr)MemMin), 4*MB);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exclude UMB's and UPA's with unusual cache attributes.
|
||||||
|
*/
|
||||||
|
mtrrexclude(MemUMB, "uc");
|
||||||
|
mtrrexclude(MemUPA, "uc");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -691,6 +691,16 @@ mtrr(uvlong base, uvlong size, char *tstr)
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char*
|
||||||
|
mtrrattr(uvlong pa, uvlong *pnext)
|
||||||
|
{
|
||||||
|
if(cpu0state.mask == 0)
|
||||||
|
return nil;
|
||||||
|
if(pnext != nil)
|
||||||
|
*pnext = getnext(&cpu0state, pa, nil);
|
||||||
|
return type2str(gettype(&cpu0state, pa, nil));
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
mtrrprint(char *buf, long bufsize)
|
mtrrprint(char *buf, long bufsize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -99,6 +99,7 @@ void mfence(void);
|
||||||
void mmuinit(void);
|
void mmuinit(void);
|
||||||
uintptr *mmuwalk(uintptr*, uintptr, int, int);
|
uintptr *mmuwalk(uintptr*, uintptr, int, int);
|
||||||
char* mtrr(uvlong, uvlong, char *);
|
char* mtrr(uvlong, uvlong, char *);
|
||||||
|
char* mtrrattr(uvlong, uvlong *);
|
||||||
void mtrrclock(void);
|
void mtrrclock(void);
|
||||||
int mtrrprint(char *, long);
|
int mtrrprint(char *, long);
|
||||||
void mtrrsync(void);
|
void mtrrsync(void);
|
||||||
|
|
Loading…
Reference in a new issue