EDAC, MCE: Add F15 EX MCE decoder
authorBorislav Petkov <borislav.petkov@amd.com>
Wed, 22 Sep 2010 13:28:59 +0000 (15:28 +0200)
committerBorislav Petkov <borislav.petkov@amd.com>
Fri, 7 Jan 2011 10:54:19 +0000 (11:54 +0100)
Integrate the single FIROB signature into an expanded table along with
the new BD MCE types.

Signed-off-by: Borislav Petkov <borislav.petkov@amd.com>
drivers/edac/mce_amd.c

index efbcb5389e80f456b756ad63a2c7fc79e144e95d..afda6de5d7e3727ac831ed761bc51ce856002443 100644 (file)
@@ -112,6 +112,22 @@ static const char * const f15h_cu_mce_desc[] = {
        "PRB address parity error"
 };
 
+static const char * const fr_ex_mce_desc[] = {
+       "CPU Watchdog timer expire",
+       "Wakeup array dest tag",
+       "AG payload array",
+       "EX payload array",
+       "IDRF array",
+       "Retire dispatch queue",
+       "Mapper checkpoint array",
+       "Physical register file EX0 port",
+       "Physical register file EX1 port",
+       "Physical register file AG0 port",
+       "Physical register file AG1 port",
+       "Flag register file",
+       "DE correctable error could not be corrected"
+};
+
 static bool f12h_dc_mce(u16 ec, u8 xec)
 {
        bool ret = false;
@@ -651,15 +667,26 @@ EXPORT_SYMBOL_GPL(amd_decode_nb_mce);
 
 static void amd_decode_fr_mce(struct mce *m)
 {
-       if (boot_cpu_data.x86 == 0xf ||
-           boot_cpu_data.x86 == 0x11)
+       struct cpuinfo_x86 *c = &boot_cpu_data;
+       u8 xec = (m->status >> 16) & xec_mask;
+
+       if (c->x86 == 0xf || c->x86 == 0x11)
                goto wrong_fr_mce;
 
-       /* we have only one error signature so match all fields at once. */
-       if ((m->status & 0xffff) == 0x0f0f) {
-               pr_emerg(HW_ERR "FR Error: CPU Watchdog timer expire.\n");
-               return;
-       }
+       if (c->x86 != 0x15 && xec != 0x0)
+               goto wrong_fr_mce;
+
+       pr_emerg(HW_ERR "%s Error: ",
+                (c->x86 == 0x15 ? "Execution Unit" : "FIROB"));
+
+       if (xec == 0x0 || xec == 0xc)
+               pr_cont("%s.\n", fr_ex_mce_desc[xec]);
+       else if (xec < 0xd)
+               pr_cont("%s parity error.\n", fr_ex_mce_desc[xec]);
+       else
+               goto wrong_fr_mce;
+
+       return;
 
 wrong_fr_mce:
        pr_emerg(HW_ERR "Corrupted FR MCE info?\n");