summaryrefslogtreecommitdiff
path: root/sys/src/9/pc64
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2016-12-17 16:35:26 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2016-12-17 16:35:26 +0100
commitea30cf94a5f247dd00c32c01325b8a47ad5f105a (patch)
treef9fbad860ac9499b11ad56778069b23ce826ca96 /sys/src/9/pc64
parentd48a0894865e810f46e1ef2f07476c4f3101698a (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.h1
-rw-r--r--sys/src/9/pc64/mmu.c21
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)