forked from pool/mcelog
260 lines
5.9 KiB
Diff
260 lines
5.9 KiB
Diff
|
Add F15h decoding support
|
||
|
|
||
|
Signed-off-by: Borislav Petkov <bp@suse.de>
|
||
|
Index: mcelog-1.0.1/amd.c
|
||
|
===================================================================
|
||
|
--- mcelog-1.0.1.orig/amd.c
|
||
|
+++ mcelog-1.0.1/amd.c
|
||
|
@@ -72,6 +72,43 @@ static char *nbextendederr[] = {
|
||
|
"L3 Cache LRU Error"
|
||
|
};
|
||
|
|
||
|
+static const char * const f15h_mc1_mce_desc[] = {
|
||
|
+ "UC during a demand linefill from L2",
|
||
|
+ "Parity error during data load from IC",
|
||
|
+ "Parity error for IC valid bit",
|
||
|
+ "Main tag parity error",
|
||
|
+ "Parity error in prediction queue",
|
||
|
+ "PFB data/address parity error",
|
||
|
+ "Parity error in the branch status reg",
|
||
|
+ "PFB promotion address error",
|
||
|
+ "Tag error during probe/victimization",
|
||
|
+ "Parity error for IC probe tag valid bit",
|
||
|
+ "PFB non-cacheable bit parity error",
|
||
|
+ "PFB valid bit parity error", /* xec = 0xd */
|
||
|
+ "Microcode Patch Buffer", /* xec = 010 */
|
||
|
+ "uop queue",
|
||
|
+ "insn buffer",
|
||
|
+ "predecode buffer",
|
||
|
+ "fetch address FIFO"
|
||
|
+};
|
||
|
+
|
||
|
+static const char * const f15h_mc2_mce_desc[] = {
|
||
|
+ "Fill ECC error on data fills", /* xec = 0x4 */
|
||
|
+ "Fill parity error on insn fills",
|
||
|
+ "Prefetcher request FIFO parity error",
|
||
|
+ "PRQ address parity error",
|
||
|
+ "PRQ data parity error",
|
||
|
+ "WCC Tag ECC error",
|
||
|
+ "WCC Data ECC error",
|
||
|
+ "WCB Data parity error",
|
||
|
+ "VB Data ECC or parity error",
|
||
|
+ "L2 Tag ECC error", /* xec = 0x10 */
|
||
|
+ "Hard L2 Tag ECC error",
|
||
|
+ "Multiple hits on L2 tag",
|
||
|
+ "XAB parity error",
|
||
|
+ "PRB address parity error"
|
||
|
+};
|
||
|
+
|
||
|
static const char * const mc4_mce_desc[] = {
|
||
|
"DRAM ECC error detected on the NB",
|
||
|
"CRC error detected on HT link",
|
||
|
@@ -161,6 +198,8 @@ enum cputype select_amd_cputype(u32 fami
|
||
|
return CPU_F12H;
|
||
|
case 0x14:
|
||
|
return CPU_F14H;
|
||
|
+ case 0x15:
|
||
|
+ return CPU_F15H;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
@@ -435,6 +474,53 @@ static bool cat_mc0_mce(u16 ec, u8 xec)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static bool f15h_mc0_mce(u16 ec, u8 xec)
|
||
|
+{
|
||
|
+ bool ret = true;
|
||
|
+
|
||
|
+ if (MEM_ERROR(ec)) {
|
||
|
+
|
||
|
+ switch (xec) {
|
||
|
+ case 0x0:
|
||
|
+ Wprintf("Data Array access error.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x1:
|
||
|
+ Wprintf("UC error during a linefill from L2/NB.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x2:
|
||
|
+ case 0x11:
|
||
|
+ Wprintf("STQ access error.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x3:
|
||
|
+ Wprintf("SCB access error.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x10:
|
||
|
+ Wprintf("Tag error.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x12:
|
||
|
+ Wprintf("LDQ access error.\n");
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ ret = false;
|
||
|
+ }
|
||
|
+ } else if (BUS_ERROR(ec)) {
|
||
|
+
|
||
|
+ if (!xec)
|
||
|
+ Wprintf("System Read Data Error.\n");
|
||
|
+ else
|
||
|
+ Wprintf(" Internal error condition type %d.\n", xec);
|
||
|
+ } else
|
||
|
+ ret = false;
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static void decode_mc0_mce(struct amd_decoder_ops *ops, struct mce *m)
|
||
|
{
|
||
|
u16 ec = EC(m->status);
|
||
|
@@ -481,6 +567,36 @@ static bool cat_mc1_mce(u16 ec, u8 xec)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static bool f15h_mc1_mce(u16 ec, u8 xec)
|
||
|
+{
|
||
|
+ bool ret = true;
|
||
|
+
|
||
|
+ if (!MEM_ERROR(ec))
|
||
|
+ return false;
|
||
|
+
|
||
|
+ switch (xec) {
|
||
|
+ case 0x0 ... 0xa:
|
||
|
+ Wprintf("%s.\n", f15h_mc1_mce_desc[xec]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0xd:
|
||
|
+ Wprintf("%s.\n", f15h_mc1_mce_desc[xec-2]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x10:
|
||
|
+ Wprintf("%s.\n", f15h_mc1_mce_desc[xec-4]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x11 ... 0x14:
|
||
|
+ Wprintf("Decoder %s parity error.\n", f15h_mc1_mce_desc[xec-4]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ ret = false;
|
||
|
+ }
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static void decode_mc1_mce(struct amd_decoder_ops *ops, struct mce *m)
|
||
|
{
|
||
|
u16 ec = EC(m->status);
|
||
|
@@ -537,6 +653,40 @@ static bool k8_mc2_mce(u16 ec, u8 xec)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+static bool f15h_mc2_mce(u16 ec, u8 xec)
|
||
|
+{
|
||
|
+ bool ret = true;
|
||
|
+
|
||
|
+ if (TLB_ERROR(ec)) {
|
||
|
+ if (xec == 0x0)
|
||
|
+ Wprintf("Data parity TLB read error.\n");
|
||
|
+ else if (xec == 0x1)
|
||
|
+ Wprintf("Poison data provided for TLB fill.\n");
|
||
|
+ else
|
||
|
+ ret = false;
|
||
|
+ } else if (BUS_ERROR(ec)) {
|
||
|
+ if (xec > 2)
|
||
|
+ ret = false;
|
||
|
+
|
||
|
+ Wprintf("Error during attempted NB data read.\n");
|
||
|
+ } else if (MEM_ERROR(ec)) {
|
||
|
+ switch (xec) {
|
||
|
+ case 0x4 ... 0xc:
|
||
|
+ Wprintf("%s.\n", f15h_mc2_mce_desc[xec - 0x4]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ case 0x10 ... 0x14:
|
||
|
+ Wprintf("%s.\n", f15h_mc2_mce_desc[xec - 0x7]);
|
||
|
+ break;
|
||
|
+
|
||
|
+ default:
|
||
|
+ ret = false;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return ret;
|
||
|
+}
|
||
|
+
|
||
|
static void decode_mc2_mce(struct amd_decoder_ops *ops, struct mce *m)
|
||
|
{
|
||
|
u16 ec = EC(m->status);
|
||
|
@@ -741,6 +891,12 @@ struct amd_decoder_ops fam_ops[] = {
|
||
|
.mc1_mce = cat_mc1_mce,
|
||
|
.mc2_mce = k8_mc2_mce,
|
||
|
},
|
||
|
+ [AMD_F15H] = {
|
||
|
+ .cpu = AMD_F15H,
|
||
|
+ .mc0_mce = f15h_mc0_mce,
|
||
|
+ .mc1_mce = f15h_mc1_mce,
|
||
|
+ .mc2_mce = f15h_mc2_mce,
|
||
|
+ },
|
||
|
};
|
||
|
|
||
|
static void __decode_amd_mc(enum cputype cpu, struct mce *mce)
|
||
|
@@ -760,6 +916,10 @@ static void __decode_amd_mc(enum cputype
|
||
|
case CPU_F14H:
|
||
|
ops = &fam_ops[AMD_F14H];
|
||
|
break;
|
||
|
+ case CPU_F15H:
|
||
|
+ xec_mask = 0x1f;
|
||
|
+ ops = &fam_ops[AMD_F15H];
|
||
|
+ break;
|
||
|
default:
|
||
|
Eprintf("Huh? What family is it: 0x%x?!\n", cpu);
|
||
|
return;
|
||
|
Index: mcelog-1.0.1/mcelog.h
|
||
|
===================================================================
|
||
|
--- mcelog-1.0.1.orig/mcelog.h
|
||
|
+++ mcelog-1.0.1/mcelog.h
|
||
|
@@ -111,6 +111,7 @@ enum cputype {
|
||
|
CPU_F11H,
|
||
|
CPU_F12H,
|
||
|
CPU_F14H,
|
||
|
+ CPU_F15H,
|
||
|
CPU_P4,
|
||
|
CPU_NEHALEM,
|
||
|
CPU_DUNNINGTON,
|
||
|
Index: mcelog-1.0.1/amd.h
|
||
|
===================================================================
|
||
|
--- mcelog-1.0.1.orig/amd.h
|
||
|
+++ mcelog-1.0.1/amd.h
|
||
|
@@ -97,4 +97,5 @@ enum rrrr_ids {
|
||
|
case CPU_F10H: \
|
||
|
case CPU_F11H: \
|
||
|
case CPU_F12H: \
|
||
|
- case CPU_F14H
|
||
|
+ case CPU_F14H: \
|
||
|
+ case CPU_F15H
|
||
|
Index: mcelog-1.0.1/mcelog.c
|
||
|
===================================================================
|
||
|
--- mcelog-1.0.1.orig/mcelog.c
|
||
|
+++ mcelog-1.0.1/mcelog.c
|
||
|
@@ -226,6 +226,7 @@ static char *cputype_name[] = {
|
||
|
[CPU_F11H] = "AMD Griffin",
|
||
|
[CPU_F12H] = "AMD Llano",
|
||
|
[CPU_F14H] = "AMD Bobcat",
|
||
|
+ [CPU_F15H] = "AMD Bulldozer",
|
||
|
[CPU_P4] = "Intel P4",
|
||
|
[CPU_NEHALEM] = "Intel Xeon 5500 series / Core i3/5/7 (\"Nehalem/Westmere\")",
|
||
|
[CPU_DUNNINGTON] = "Intel Xeon 7400 series",
|
||
|
@@ -248,6 +249,7 @@ static struct config_choice cpu_choices[
|
||
|
{ "f11h", CPU_F11H },
|
||
|
{ "f12h", CPU_F12H },
|
||
|
{ "f14h", CPU_F14H },
|
||
|
+ { "f15h", CPU_F15H },
|
||
|
{ "p4", CPU_P4 },
|
||
|
{ "dunnington", CPU_DUNNINGTON },
|
||
|
{ "xeon74xx", CPU_DUNNINGTON },
|