diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-12-17 16:35:26 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2016-12-17 16:35:26 +0100 |
commit | ea30cf94a5f247dd00c32c01325b8a47ad5f105a (patch) | |
tree | f9fbad860ac9499b11ad56778069b23ce826ca96 /sys/src/9/pc64 | |
parent | d48a0894865e810f46e1ef2f07476c4f3101698a (diff) |
pat write combinding support for 386 kernel, honor cpuid bits
Diffstat (limited to 'sys/src/9/pc64')
-rw-r--r-- | sys/src/9/pc64/dat.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc64/mmu.c | 21 |
2 files changed, 16 insertions, 6 deletions
diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index b6333c5ff..e3554a1be 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -279,6 +279,7 @@ enum { Mtrr = 1<<12, /* memory-type range regs. */ Pge = 1<<13, /* page global extension */ Mca = 1<<14, /* machine-check architecture */ + Pat = 1<<16, /* page attribute table */ Pse2 = 1<<17, /* more page size extensions */ Clflush = 1<<19, Acpif = 1<<22, /* therm control msr */ diff --git a/sys/src/9/pc64/mmu.c b/sys/src/9/pc64/mmu.c index ffd077e31..6f27ac25e 100644 --- a/sys/src/9/pc64/mmu.c +++ b/sys/src/9/pc64/mmu.c @@ -135,10 +135,12 @@ mmuinit(void) wrmsr(0xc0000084, 0x200); /* IA32_PAT write combining */ - rdmsr(0x277, &v); - v &= ~(255LL<<(PATWC*8)); - v |= 1LL<<(PATWC*8); /* WC */ - wrmsr(0x277, v); + if((MACHP(0)->cpuiddx & Pat) != 0 + && rdmsr(0x277, &v) != -1){ + v &= ~(255LL<<(PATWC*8)); + v |= 1LL<<(PATWC*8); /* WC */ + wrmsr(0x277, v); + } } /* @@ -549,13 +551,20 @@ vunmap(void *v, int) * mark pages as write combining (used for framebuffer) */ void -patwc(void *v, int n) +patwc(void *a, int n) { uintptr *pte, mask, attr, va; int z, l; + vlong v; + + /* check if pat is usable */ + if((MACHP(0)->cpuiddx & Pat) == 0 + || rdmsr(0x277, &v) == -1 + || ((v >> PATWC*8) & 7) != 1) + return; /* set the bits for all pages in range */ - for(va = (uintptr)v; n > 0; n -= z, va += z){ + for(va = (uintptr)a; n > 0; n -= z, va += z){ l = 0; pte = mmuwalk(m->pml4, va, l, 0); if(pte == 0) |