pc, pc64: initial machine check architecture support
This commit is contained in:
parent
3fe38f7001
commit
3a6a754051
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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*);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue