pc, pc64: initial machine check architecture support

This commit is contained in:
cinap_lenrek 2014-07-09 22:45:51 +02:00
parent 3fe38f7001
commit 3a6a754051
7 changed files with 77 additions and 20 deletions

View file

@ -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 */

View file

@ -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");
}
}

View file

@ -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*);

View file

@ -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);
}

View file

@ -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 */

View file

@ -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*);

View file

@ -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);
}