summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBorislav Petkov <borislav.petkov@amd.com>2010-09-22 15:28:59 +0200
committerBorislav Petkov <borislav.petkov@amd.com>2011-01-07 11:54:19 +0100
commit8259a7e5724c42c89d927b92cda3e0ab15b9ade9 (patch)
tree9b6f55194f8566c4a13350059d61562c6e116b5b
parent05cd667d668eb08845dd49c02130e5223121b715 (diff)
EDAC, MCE: Add F15 EX MCE decoder
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>
-rw-r--r--drivers/edac/mce_amd.c41
1 files changed, 34 insertions, 7 deletions
diff --git a/drivers/edac/mce_amd.c b/drivers/edac/mce_amd.c
index efbcb5389e8..afda6de5d7e 100644
--- a/drivers/edac/mce_amd.c
+++ b/drivers/edac/mce_amd.c
@@ -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");