diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-07-09 22:45:51 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-07-09 22:45:51 +0200 |
commit | 3a6a754051a6f3f1ba742f12be0a2c33d309ca53 (patch) | |
tree | 5170261d4d211c331b732f3df9e5b94a0b7ab5dd /sys | |
parent | 3fe38f70014256cdd1d3b1b42f7b8760e6e80778 (diff) |
pc, pc64: initial machine check architecture support
Diffstat (limited to 'sys')
-rw-r--r-- | sys/src/9/pc/dat.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc/devarch.c | 71 | ||||
-rw-r--r-- | sys/src/9/pc/fns.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc/trap.c | 11 | ||||
-rw-r--r-- | sys/src/9/pc64/dat.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc64/fns.h | 1 | ||||
-rw-r--r-- | sys/src/9/pc64/trap.c | 11 |
7 files changed, 77 insertions, 20 deletions
diff --git a/sys/src/9/pc/dat.h b/sys/src/9/pc/dat.h index a4544debf..a8f46aaca 100644 --- a/sys/src/9/pc/dat.h +++ b/sys/src/9/pc/dat.h @@ -321,6 +321,7 @@ enum { Cpuapic = 1<<9, Mtrr = 1<<12, /* memory-type range regs. */ Pge = 1<<13, /* page global extension */ + Mca = 1<<14, /* machine-check architecture */ Pse2 = 1<<17, /* more page size extensions */ Clflush = 1<<19, Acpif = 1<<22, /* therm control msr */ diff --git a/sys/src/9/pc/devarch.c b/sys/src/9/pc/devarch.c index 7cd845c08..fce3c5bc5 100644 --- a/sys/src/9/pc/devarch.c +++ b/sys/src/9/pc/devarch.c @@ -824,12 +824,37 @@ cpuidentify(void) nomce = strtoul(p, 0, 0); else nomce = 0; - if((m->cpuiddx & Mce) && !nomce){ - cr4 |= 0x40; /* machine check enable */ - if(family == 5){ + if((m->cpuiddx & Mce) != 0 && !nomce){ + if((m->cpuiddx & Mca) != 0){ + vlong cap; + int bank; + + cap = 0; + rdmsr(0x179, &cap); + + if(cap & 0x100) + wrmsr(0x17B, ~0ULL); /* enable all mca features */ + + bank = cap & 0xFF; + if(bank > 64) + bank = 64; + + /* init MCi .. MC1 (except MC0) */ + while(--bank > 0){ + wrmsr(0x400 + bank*4, ~0ULL); + wrmsr(0x401 + bank*4, 0); + } + + if(family != 6 || model >= 0x1A) + wrmsr(0x400, ~0ULL); + + wrmsr(0x401, 0); + } + else if(family == 5){ rdmsr(0x00, &mca); rdmsr(0x01, &mct); } + cr4 |= 0x40; /* machine check enable */ } /* @@ -854,7 +879,7 @@ cpuidentify(void) putcr4(cr4); - if(m->cpuiddx & Mce) + if((m->cpuiddx & (Mca|Mce)) == Mce) rdmsr(0x01, &mct); } @@ -1195,3 +1220,41 @@ isaconfig(char *class, int ctlrno, ISAConf *isa) } return 1; } + +void +dumpmcregs(void) +{ + vlong v, w; + int bank; + + if((m->cpuiddx & (Mce|Cpumsr)) != (Mce|Cpumsr)) + return; + if((m->cpuiddx & Mca) == 0){ + rdmsr(0x00, &v); + rdmsr(0x01, &w); + iprint("MCA %8.8llux MCT %8.8llux\n", v, w); + return; + } + rdmsr(0x179, &v); + rdmsr(0x17A, &w); + iprint("MCG CAP %.16llux STATUS %.16llux\n", v, w); + + bank = v & 0xFF; + if(bank > 64) + bank = 64; + while(--bank >= 0){ + rdmsr(0x401 + bank*4, &v); + if((v & (1ull << 63)) == 0) + continue; + iprint("MC%d STATUS %.16llux", bank, v); + if(v & (1ull << 58)){ + rdmsr(0x402 + bank*4, &w); + iprint(" ADDR %.16llux", w); + } + if(v & (1ull << 59)){ + rdmsr(0x403 + bank*4, &w); + iprint(" MISC %.16llux", w); + } + iprint("\n"); + } +} diff --git a/sys/src/9/pc/fns.h b/sys/src/9/pc/fns.h index c3bd2e58c..99fa4b671 100644 --- a/sys/src/9/pc/fns.h +++ b/sys/src/9/pc/fns.h @@ -28,6 +28,7 @@ int dmainit(int, int); #define DMAREAD 1 #define DMALOOP 2 long dmasetup(int, void*, long, int); +void dumpmcregs(void); #define evenaddr(x) /* x86 doesn't care */ void fpclear(void); void fpenv(FPsave*); diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index c25ab3e49..38f6e0b0f 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -528,8 +528,6 @@ dumpregs2(Ureg* ureg) void dumpregs(Ureg* ureg) { - vlong mca, mct; - dumpregs2(ureg); /* @@ -542,12 +540,9 @@ dumpregs(Ureg* ureg) iprint(" CR0 %8.8lux CR2 %8.8lux CR3 %8.8lux", getcr0(), getcr2(), getcr3()); if(m->cpuiddx & (Mce|Tsc|Pse|Vmex)){ - iprint(" CR4 %8.8lux", getcr4()); - if((m->cpuiddx & (Mce|Cpumsr)) == (Mce|Cpumsr)){ - rdmsr(0x00, &mca); - rdmsr(0x01, &mct); - iprint("\n MCA %8.8llux MCT %8.8llux", mca, mct); - } + iprint(" CR4 %8.8lux\n", getcr4()); + if(ureg->trap == 18) + dumpmcregs(); } iprint("\n ur %#p up %#p\n", ureg, up); } diff --git a/sys/src/9/pc64/dat.h b/sys/src/9/pc64/dat.h index c5426b986..0bf421d79 100644 --- a/sys/src/9/pc64/dat.h +++ b/sys/src/9/pc64/dat.h @@ -286,6 +286,7 @@ enum { Cpuapic = 1<<9, Mtrr = 1<<12, /* memory-type range regs. */ Pge = 1<<13, /* page global extension */ + Mca = 1<<14, /* machine-check architecture */ Pse2 = 1<<17, /* more page size extensions */ Clflush = 1<<19, Acpif = 1<<22, /* therm control msr */ diff --git a/sys/src/9/pc64/fns.h b/sys/src/9/pc64/fns.h index 0e2d8263c..04e1c5d69 100644 --- a/sys/src/9/pc64/fns.h +++ b/sys/src/9/pc64/fns.h @@ -28,6 +28,7 @@ int dmainit(int, int); #define DMAREAD 1 #define DMALOOP 2 long dmasetup(int, void*, long, int); +void dumpmcregs(void); #define evenaddr(x) /* x86 doesn't care */ void (*fprestore)(FPsave*); void (*fpsave)(FPsave*); diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c index e8360d15f..2c2001115 100644 --- a/sys/src/9/pc64/trap.c +++ b/sys/src/9/pc64/trap.c @@ -503,14 +503,9 @@ dumpregs(Ureg* ureg) iprint(" CR0 %8.8llux CR2 %16.16llux CR3 %16.16llux", getcr0(), getcr2(), getcr3()); if(m->cpuiddx & (Mce|Tsc|Pse|Vmex)){ - iprint(" CR4 %16.16llux", getcr4()); - if((m->cpuiddx & (Mce|Cpumsr)) == (Mce|Cpumsr)){ - vlong mca, mct; - - rdmsr(0x00, &mca); - rdmsr(0x01, &mct); - iprint("\n MCA %8.8llux MCT %8.8llux", mca, mct); - } + iprint(" CR4 %16.16llux\n", getcr4()); + if(ureg->type == 18) + dumpmcregs(); } iprint("\n ur %#p up %#p\n", ureg, up); } |