Add F14h decoding support Signed-off-by: Borislav Petkov --- amd.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ amd.h | 3 +- mcelog.c | 2 + mcelog.h | 1 4 files changed, 93 insertions(+), 1 deletion(-) Index: mcelog-189/amd.c =================================================================== --- mcelog-189.orig/amd.c +++ mcelog-189/amd.c @@ -159,6 +159,8 @@ enum cputype select_amd_cputype(u32 fami return CPU_F11H; case 0x12: return CPU_F12H; + case 0x14: + return CPU_F14H; default: break; } @@ -381,6 +383,58 @@ static bool k8_mc0_mce(u16 ec, u8 xec) return f10h_mc0_mce(ec, xec); } +static bool cat_mc0_mce(u16 ec, u8 xec) +{ + u8 r4 = R4(ec); + bool ret = true; + + if (MEM_ERROR(ec)) { + + if (TT(ec) != TT_DATA || LL(ec) != LL_L1) + return false; + + switch (r4) { + case R4_DRD: + case R4_DWR: + Wprintf("Data/Tag parity error due to %s.\n", + (r4 == R4_DRD ? "load/hw prf" : "store")); + break; + case R4_EVICT: + Wprintf("Copyback parity error on a tag miss.\n"); + break; + case R4_SNOOP: + Wprintf("Tag parity error during snoop.\n"); + break; + default: + ret = false; + } + } else if (BUS_ERROR(ec)) { + + if ((II(ec) != II_MEM && II(ec) != II_IO) || LL(ec) != LL_LG) + return false; + + Wprintf("System read data error on a "); + + switch (r4) { + case R4_RD: + Wprintf("TLB reload.\n"); + break; + case R4_DWR: + Wprintf("store.\n"); + break; + case R4_DRD: + Wprintf("load.\n"); + break; + default: + ret = false; + } + } else { + ret = false; + } + + return ret; +} + static void decode_mc0_mce(struct amd_decoder_ops *ops, struct mce *m) { u16 ec = EC(m->status); @@ -402,6 +456,31 @@ static void decode_mc0_mce(struct amd_de Eprintf("Corrupted MC0 MCE info?\n"); } +static bool cat_mc1_mce(u16 ec, u8 xec) +{ + u8 r4 = R4(ec); + bool ret = true; + + if (!MEM_ERROR(ec)) + return false; + + if (TT(ec) != TT_INSTR) + return false; + + if (r4 == R4_IRD) + Wprintf("Data/tag array parity error for a tag hit.\n"); + else if (r4 == R4_SNOOP) + Wprintf("Tag error during snoop/victimization.\n"); + else if (xec == 0x0) + Wprintf("Tag parity error from victim castout.\n"); + else if (xec == 0x2) + Wprintf("Microcode patch RAM parity error.\n"); + else + ret = false; + + return ret; +} + static void decode_mc1_mce(struct amd_decoder_ops *ops, struct mce *m) { u16 ec = EC(m->status); @@ -656,6 +735,12 @@ struct amd_decoder_ops fam_ops[] = { .mc1_mce = k8_mc1_mce, .mc2_mce = k8_mc2_mce, }, + [AMD_F14H] = { + .cpu = AMD_F14H, + .mc0_mce = cat_mc0_mce, + .mc1_mce = cat_mc1_mce, + .mc2_mce = k8_mc2_mce, + }, }; static void __decode_amd_mc(enum cputype cpu, struct mce *mce) @@ -672,6 +757,9 @@ static void __decode_amd_mc(enum cputype case CPU_F12H: ops = &fam_ops[AMD_F12H]; break; + case CPU_F14H: + ops = &fam_ops[AMD_F14H]; + break; default: Eprintf("Huh? What family is it: 0x%x?!\n", cpu); return;