amd/stoneyridge: Dump MCA registers

Add a function to provide a rudimentary dump of the Machine Check
Architecture registers.  These values survive a warm reset.

BUG=b:65445599
TEST=Verify on a Grunt having propensity for #MC errors

Change-Id: Ib6875cabe3041e65c811d8b2232f7ac6bedd1a02
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/27926
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Martin Roth <martinroth@google.com>
diff --git a/src/soc/amd/stoneyridge/cpu.c b/src/soc/amd/stoneyridge/cpu.c
index 52b1c9c..09543b6 100644
--- a/src/soc/amd/stoneyridge/cpu.c
+++ b/src/soc/amd/stoneyridge/cpu.c
@@ -117,22 +117,65 @@
 	set_warm_reset_flag();
 }
 
-static void model_15_init(struct device *dev)
-{
-	printk(BIOS_DEBUG, "Model 15 Init.\n");
+static const char *const mca_bank_name[] = {
+	"Load-store unit",
+	"Instruction fetch unit",
+	"Combined unit",
+	"Reserved",
+	"Northbridge",
+	"Execution unit",
+	"Floating point unit"
+};
 
+static void check_mca(void)
+{
 	int i;
 	msr_t msr;
 	int num_banks;
 
-	/* zero the machine check error status registers */
 	msr = rdmsr(MCG_CAP);
 	num_banks = msr.lo & MCA_BANKS_MASK;
+
+	if (is_warm_reset()) {
+		for (i = 0 ; i < num_banks ; i++) {
+			if (i == 3) /* Reserved in Family 15h */
+				continue;
+
+			msr = rdmsr(MC0_STATUS + (i * 4));
+			if (msr.hi || msr.lo) {
+				int core = cpuid_ebx(1) >> 24;
+
+				printk(BIOS_WARNING, "#MC Error: core %d, bank %d %s\n",
+						core, i, mca_bank_name[i]);
+
+				printk(BIOS_WARNING, "   MC%d_STATUS =   %08x_%08x\n",
+						i, msr.hi, msr.lo);
+				msr = rdmsr(MC0_ADDR + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_ADDR =     %08x_%08x\n",
+						i, msr.hi, msr.lo);
+				msr = rdmsr(MC0_MISC + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_MISC =     %08x_%08x\n",
+						i, msr.hi, msr.lo);
+				msr = rdmsr(MC0_CTL + (i * 4));
+				printk(BIOS_WARNING, "   MC%d_CTL =      %08x_%08x\n",
+						i, msr.hi, msr.lo);
+				msr = rdmsr(MC0_CTL_MASK + i);
+				printk(BIOS_WARNING, "   MC%d_CTL_MASK = %08x_%08x\n",
+						i, msr.hi, msr.lo);
+			}
+		}
+	}
+
+	/* zero the machine check error status registers */
 	msr.lo = 0;
 	msr.hi = 0;
 	for (i = 0 ; i < num_banks ; i++)
 		wrmsr(MC0_STATUS + (i * 4), msr);
+}
 
+static void model_15_init(struct device *dev)
+{
+	check_mca();
 	setup_lapic();
 }