diff --git a/intel.c b/intel.c index 099c4ad..ba353c2 100644 --- a/intel.c +++ b/intel.c @@ -32,7 +32,8 @@ void intel_cpu_init(enum cputype cpu) { if (cpu == CPU_NEHALEM || cpu == CPU_XEON75XX || cpu == CPU_INTEL || cpu == CPU_SANDY_BRIDGE || cpu == CPU_SANDY_BRIDGE_EP || - cpu == CPU_IVY_BRIDGE || cpu == CPU_IVY_BRIDGE_EPEX) + cpu == CPU_IVY_BRIDGE || cpu == CPU_IVY_BRIDGE_EPEX || + cpu == CPU_HASWELL) memory_error_support = 1; } @@ -58,7 +59,7 @@ enum cputype select_intel_cputype(int family, int model) return CPU_NEHALEM; else if (model == 0x2e || model == 0x2f) return CPU_XEON75XX; - else if (model == 0x2a || model == 0x3a) + else if (model == 0x2a) return CPU_SANDY_BRIDGE; else if (model == 0x2d) return CPU_SANDY_BRIDGE_EP; @@ -66,6 +67,8 @@ enum cputype select_intel_cputype(int family, int model) return CPU_IVY_BRIDGE; else if (model == 0x3e) return CPU_IVY_BRIDGE_EPEX; + else if (model == 0x3c || model == 0x45 || model == 0x46) + return CPU_HASWELL; if (model > 0x1a) { Eprintf("Family 6 Model %x CPU: only decoding architectural errors\n", model); diff --git a/intel.h b/intel.h index 105f806..b2b949a 100644 --- a/intel.h +++ b/intel.h @@ -17,5 +17,6 @@ extern int memory_error_support; case CPU_SANDY_BRIDGE_EP: \ case CPU_SANDY_BRIDGE: \ case CPU_IVY_BRIDGE: \ - case CPU_IVY_BRIDGE_EPEX + case CPU_IVY_BRIDGE_EPEX: \ + case CPU_HASWELL diff --git a/ivy-bridge.c b/ivy-bridge.c index 46ef7ae..5908ee2 100644 --- a/ivy-bridge.c +++ b/ivy-bridge.c @@ -76,6 +76,7 @@ static char *memctrl_1[] = { [0x010] = "Uncorrected patrol scrub error", [0x020] = "Corrected spare error", [0x040] = "Uncorrected spare error", + [0x080] = "Corrected memory read error", [0x100] = "iMC, WDB, parity errors", }; diff --git a/leaky-bucket.c b/leaky-bucket.c index 66c2f08..6bb345a 100644 --- a/leaky-bucket.c +++ b/leaky-bucket.c @@ -69,7 +69,7 @@ static int timeconv(char unit, int *out) unsigned corr = 1; switch (unit) { case 'd': corr *= 24; - case 'h': corr *= 3600; + case 'h': corr *= 60; case 'm': corr *= 60; case 0: break; default: return -1; diff --git a/mcelog.c b/mcelog.c index 1a4c691..83eb607 100644 --- a/mcelog.c +++ b/mcelog.c @@ -227,6 +227,7 @@ static char *cputype_name[] = { [CPU_SANDY_BRIDGE_EP] = "Sandy Bridge EP", /* Fill in better name */ [CPU_IVY_BRIDGE] = "Ivy Bridge", /* Fill in better name */ [CPU_IVY_BRIDGE_EPEX] = "Ivy Bridge EP/EX", /* Fill in better name */ + [CPU_HASWELL] = "Haswell", /* Fill in better name */ }; static struct config_choice cpu_choices[] = { @@ -262,6 +263,7 @@ static struct config_choice cpu_choices[] = { { "ivybridge", CPU_IVY_BRIDGE }, /* Fill in better name */ { "ivybridge-ep", CPU_IVY_BRIDGE_EPEX }, /* Fill in better name */ { "ivybridge-ex", CPU_IVY_BRIDGE_EPEX }, /* Fill in better name */ + { "haswell", CPU_HASWELL }, /* Fill in better name */ {} }; diff --git a/mcelog.h b/mcelog.h index ad69351..ddf90ac 100644 --- a/mcelog.h +++ b/mcelog.h @@ -117,6 +117,7 @@ enum cputype { CPU_SANDY_BRIDGE_EP, CPU_IVY_BRIDGE, CPU_IVY_BRIDGE_EPEX, + CPU_HASWELL, }; enum option_ranges { diff --git a/p4.c b/p4.c index b5b34e2..93b59f3 100644 --- a/p4.c +++ b/p4.c @@ -360,6 +360,23 @@ void decode_intel_mc(struct mce *log, int cputype, int *ismemerr, unsigned size) ivb_decode_model(cputype, log->bank, log->status, log->misc); break; } + + /* IO MCA - reported as bus/interconnect with specific PP,T,RRRR,II,LL values + * and MISCV set. MISC register points to root port that reported the error + * need to cross check with AER logs for more details. + * See: http://www.intel.com/content/www/us/en/architecture-and-technology/enhanced-mca-logging-xeon-paper.html + */ + if ((log->status & MCI_STATUS_MISCV) && + (log->status & 0xefff) == 0x0e0b) { + int seg, bus, dev, fn; + + seg = EXTRACT(log->misc, 32, 39); + bus = EXTRACT(log->misc, 24, 31); + dev = EXTRACT(log->misc, 19, 23); + fn = EXTRACT(log->misc, 16, 18); + Wprintf("IO MCA reported by root port %x:%02x:%02x.%x\n", + seg, bus, dev, fn); + } } char *intel_bank_name(int num)