<p>Marshall Dawson has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/28480">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">NOT_FOR_MERGE: Add code to dump BERT region contents<br><br>Has been useful for development and debug.<br><br>Change-Id: I8ecf920499a662db34a332e9df05e4ee2383b6d4<br>Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com><br>---<br>M src/soc/amd/stoneyridge/Makefile.inc<br>A src/soc/amd/stoneyridge/bertdump.c<br>M src/soc/amd/stoneyridge/finalize.c<br>3 files changed, 474 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/80/28480/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>index a8db2c2..45e8aa3 100644</span><br><span>--- a/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>+++ b/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>@@ -37,6 +37,8 @@</span><br><span> subdirs-y += ../../../cpu/x86/pae</span><br><span> subdirs-y += ../../../cpu/x86/smm</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-y += bertdump.c</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> bootblock-$(CONFIG_STONEYRIDGE_UART) += uart.c</span><br><span> bootblock-y += BiosCallOuts.c</span><br><span> bootblock-y += bootblock/bootblock.c</span><br><span>diff --git a/src/soc/amd/stoneyridge/bertdump.c b/src/soc/amd/stoneyridge/bertdump.c</span><br><span>new file mode 100644</span><br><span>index 0000000..187ca24</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/amd/stoneyridge/bertdump.c</span><br><span>@@ -0,0 +1,465 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright 2018 Advanced Micro Devices, Inc.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/acpi.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/amd/amdfam15.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/cpu.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <lib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/helpers.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/bert_storage.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cper.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////////////////////////////////////////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////////////////////////////////////////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+//</span><br><span style="color: hsl(120, 100%, 40%);">+//</span><br><span style="color: hsl(120, 100%, 40%);">+// Table checker code</span><br><span style="color: hsl(120, 100%, 40%);">+//</span><br><span style="color: hsl(120, 100%, 40%);">+//</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////////////////////////////////////////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+/////////////////////////////////////////////////////////////////////////</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void print_guid(guid_t guid)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ u8 *g = (u8 *)&guid;</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, "{{0x%02x%02x%02x%02x, 0x%02x%02x, 0x%02x%02x, {0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ g[3], g[2], g[1], g[0],</span><br><span style="color: hsl(120, 100%, 40%);">+ g[5], g[4],</span><br><span style="color: hsl(120, 100%, 40%);">+ g[7], g[6],</span><br><span style="color: hsl(120, 100%, 40%);">+ g[8], g[9], g[10], g[11], g[12], g[13], g[14], g[15]);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+// Status and Error Data structures have idential Error Severity definitions</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *acpi_severity[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "Recoverable",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Fatal",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Corrected",</span><br><span style="color: hsl(120, 100%, 40%);">+ "None",</span><br><span style="color: hsl(120, 100%, 40%);">+ "you did something wrong"</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *acpi_sev(u32 sev)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (sev > 3)</span><br><span style="color: hsl(120, 100%, 40%);">+ return acpi_severity[4];</span><br><span style="color: hsl(120, 100%, 40%);">+ return acpi_severity[sev];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void x86_chkprint_with_valid(u64 check, u64 valid)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (check & 0xffff & ~valid) /* validation bits are 15:0 */</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e * Invalid bits %llx\n", check & ~valid);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_XACT_MASK)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Transaction Type = %llx %s\n", check & X86_PROC_CHK_XACT_MASK >> X86_PROC_CHK_XACT_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_XACT_MASK ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_OPERATION_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Operation = %llx %s\n", check & X86_PROC_CHK_OPER_MASK >> X86_PROC_CHK_OPER_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_OPERATION_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_LEVEL_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Cache Level = %llx %s\n", check & X86_PROC_CHK_LEVEL_MASK >> X86_PROC_CHK_LEVEL_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_LEVEL_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_CONTEXT_CORPT_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Context Corrupt = %x %s\n", !!(check & X86_PROC_CHK_CTX_CORRUPT),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_CONTEXT_CORPT_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_UNCORRECTED_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Uncorrected = %x %s\n", !!(check & X86_PROC_CHK_UNCORRECTED),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_UNCORRECTED_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_PRECISE_IP_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Precise IP = %x %s\n", !!(check & X86_PROC_CHK_PRECISE_IP),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_PRECISE_IP_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_RESTARTABLE_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Restartable IP = %x %s\n", !!(check & X86_PROC_CHK_RESTARTABLE_IP),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_RESTARTABLE_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_OVERFLOW_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Overflow = %x %s\n", !!(check & X86_PROC_CHK_OVERFLOW),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_OVERFLOW_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_PART_TYPE_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Participation Type = %llx %s\n", check & X86_PROC_CHK_PARTIC_MASK >> X86_PROC_CHK_PARTIC_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_PART_TYPE_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_TIMEOUT)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Time Out = %x %s\n", !!(check & X86_PROC_CHK_OVERFLOW),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_TIMEOUT ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_ADDR_SPACE_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Address Space = %llx %s\n", check & X86_PROC_CHK_PARTIC_MASK >> X86_PROC_CHK_PARTIC_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_ADDR_SPACE_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void x86_mschkprint_with_valid(u64 check, u64 valid)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (check & 0xffff & ~valid) /* validation bits are 15:0 */</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e * Invalid bits %llx\n", check & ~valid);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_XACT_MASK)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Transaction Type = %llx %s\n", check & X86_PROC_MS_CHK_XACT_MASK >> X86_PROC_MS_CHK_XACT_SH,</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_XACT_MASK ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_UNCORRECTED_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Uncorrected = %x %s\n", !!(check & X86_PROC_MS_CHK_UNCORRECTED),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_UNCORRECTED_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_PRECISE_IP_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Precise IP = %x %s\n", !!(check & X86_PROC_MS_CHK_PRECISE_IP),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_PRECISE_IP_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_RESTARTABLE_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Restartable IP = %x %s\n", !!(check & X86_PROC_MS_CHK_RESTARTABLE_IP),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_RESTARTABLE_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (valid & X86_PROC_CHK_OVERFLOW_VALID)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Overflow = %x %s\n", !!(check & X86_PROC_MS_CHK_OVERFLOW),</span><br><span style="color: hsl(120, 100%, 40%);">+ check & X86_PROC_CHK_OVERFLOW_VALID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *check_guid_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "CACHE_CHK_ERROR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "TLB_CHK_ERROR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "BUS_CHK_ERROR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "MS_CHK_ERROR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "you did something wrong"</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *check_guid_name(guid_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&type, &X86_PROCESSOR_CACHE_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_guid_names[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&type, &X86_PROCESSOR_TLB_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_guid_names[1];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&type, &X86_PROCESSOR_BUS_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_guid_names[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&type, &X86_PROCESSOR_MS_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_guid_names[3];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return check_guid_names[4];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t parse_x86_error_info(cper_ia32x64_proc_error_info_t *err)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ CPER IA32/x64 Processor Error (Check) Information @0x%p - 0x%p (size 0x%zx) ___\n", err, err + 1, sizeof(*err));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Structure Type GUID = %s\n", check_guid_name(err->type));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Structure Type = ");</span><br><span style="color: hsl(120, 100%, 40%);">+ print_guid(err->type);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e Validation Bits = %llx\n", err->validation);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&err->type, &X86_PROCESSOR_CACHE_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ x86_chkprint_with_valid(err->check_info, X86_PROC_CHK_XACT_TYPE_VALID | X86_PROC_CHK_OPERATION_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_LEVEL_VALID | X86_PROC_CHK_CONTEXT_CORPT_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_UNCORRECTED_VALID | X86_PROC_CHK_PRECISE_IP_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_RESTARTABLE_VALID | X86_PROC_CHK_OVERFLOW_VALID);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (!guidcmp(&err->type, &X86_PROCESSOR_TLB_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ x86_chkprint_with_valid(err->check_info, X86_PROC_CHK_XACT_TYPE_VALID | X86_PROC_CHK_OPERATION_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_LEVEL_VALID | X86_PROC_CHK_CONTEXT_CORPT_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_UNCORRECTED_VALID | X86_PROC_CHK_PRECISE_IP_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_RESTARTABLE_VALID | X86_PROC_CHK_OVERFLOW_VALID);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (!guidcmp(&err->type, &X86_PROCESSOR_BUS_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ x86_chkprint_with_valid(err->check_info, X86_PROC_CHK_XACT_TYPE_VALID | X86_PROC_CHK_OPERATION_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_LEVEL_VALID | X86_PROC_CHK_CONTEXT_CORPT_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_UNCORRECTED_VALID | X86_PROC_CHK_PRECISE_IP_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_RESTARTABLE_VALID | X86_PROC_CHK_OVERFLOW_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_PART_TYPE_VALID | X86_PROC_CHK_TIMEOUT_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_ADDR_SPACE_VALID);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (!guidcmp(&err->type, &X86_PROCESSOR_MS_CHK_ERROR_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ x86_mschkprint_with_valid(err->check_info, X86_PROC_CHK_XACT_TYPE_VALID | X86_PROC_CHK_OPERATION_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_LEVEL_VALID | X86_PROC_CHK_CONTEXT_CORPT_VALID</span><br><span style="color: hsl(120, 100%, 40%);">+ | X86_PROC_CHK_UNCORRECTED_VALID | X86_PROC_CHK_PRECISE_IP_VALID);</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " e INVALID CHECK TYPE!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return sizeof(*err);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *context_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "Unclassified data",</span><br><span style="color: hsl(120, 100%, 40%);">+ "MSR Registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "32-bit mode execution registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "64-bit mode execution registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "FXSAVE context",</span><br><span style="color: hsl(120, 100%, 40%);">+ "32-bit mode debug registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "64-bit mode debug registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "Memory mapped registers",</span><br><span style="color: hsl(120, 100%, 40%);">+ "you did something wrong"</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *context_name(int type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case 0:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 2:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 3:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 4:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 5:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 6:</span><br><span style="color: hsl(120, 100%, 40%);">+ case 7:</span><br><span style="color: hsl(120, 100%, 40%);">+ return context_names[type];</span><br><span style="color: hsl(120, 100%, 40%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ return context_names[8];</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t parse_x86_context_info(cper_ia32x64_context_t *ctx)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ CPER IA32/x64 Processor Context Information @0x%p - 0x%p (size 0x%zx) ___\n", ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ (u8 *)ctx + ALIGN_UP(sizeof(*ctx) + ctx->array_size, 16),</span><br><span style="color: hsl(120, 100%, 40%);">+ ALIGN_UP(sizeof(*ctx) + ctx->array_size, 16));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t Context Type = %x %s\n", ctx->type, context_name(ctx->type));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t Array Size = %x\n", ctx->array_size);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t MSR Address = %x\n", ctx->msr_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t MM Address = %llx\n", ctx->mmap_addr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ u64 *array = (u64 *)(ctx + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t Data Array\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ int array_size = ctx->array_size / sizeof(u64);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0 ; i < array_size ; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " t %08x_%08x\n", (u32)(*(array + i) >> 32), (u32)*(array + i));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ return ALIGN_UP(sizeof(*ctx) + ctx->array_size, 16);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t parse_cper_structure_x86(cper_ia32x64_proc_error_section_t *ia32)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+ int errs = (ia32->validation & I32X64SEC_VALID_ERRNUM_MASK) >> I32X64SEC_VALID_ERRNUM_SH;</span><br><span style="color: hsl(120, 100%, 40%);">+ int ctxs = (ia32->validation & I32X64SEC_VALID_CTXNUM_MASK) >> I32X64SEC_VALID_CTXNUM_SH;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ CPER IA32/x64 Processor Error @0x%p sizeof(proc error section struct) is 0x%zx/%zd) ___\n", ia32, sizeof(*ia32), sizeof(*ia32));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x Validation Bits = %llx\n", ia32->validation);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x errors = %d\n", errs);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x contexts = %d\n", ctxs);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x Processor APIC ID = %llx %s\n", ia32->apicid, ia32->validation & I32X64SEC_VALID_LAPIC ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x Processor CPUID = EAX = %x %s\n", (u32)ia32->cpuid[0], ia32->validation & I32X64SEC_VALID_CPUID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x EBX = %x\n", (u32)ia32->cpuid[1]);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x ECX = %x\n", (u32)ia32->cpuid[2]);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " x EDX = %x\n", (u32)ia32->cpuid[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t adder = sizeof(*ia32);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0 ; i < errs ; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ adder += parse_x86_error_info((cper_ia32x64_proc_error_info_t *)((u8 *)ia32 + adder));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0 ; i < ctxs ; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+ adder += parse_x86_context_info((cper_ia32x64_context_t *)((u8 *)ia32 + adder));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return adder;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t parse_cper_structure_generic(cper_proc_generic_error_section_t *gen)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ CPER Generic Processor Error @0x%p sizeof(generic error struct) is 0x%zx/%zd\n", gen, sizeof(*gen), sizeof(*gen));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Validation Bits = %llx\n", gen->validation);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Processor Type = %x %s\n", gen->proc_type, gen->validation & GENPROC_VALID_PROC_TYPE ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Processor ISA = %x %s\n", gen->proc_isa, gen->validation & GENPROC_VALID_PROC_ISA ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Processor Error Type = %x %s\n", gen->error_type, gen->validation & GENPROC_VALID_PROC_ERR_TYPE ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Operation = %x %s\n", gen->operation, gen->validation & GENPROC_VALID_OPERATION ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Flags = %x %s\n", gen->flags, gen->validation & GENPROC_VALID_FLAGS ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Level = %x %s\n", gen->level, gen->validation & GENPROC_VALID_LEVEL ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c CPU Version Info = %llx %s\n", gen->cpu_version, gen->validation & GENPROC_VALID_CPU_VERSION ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c CPU Brand String = %s %s\n", gen->cpu_brand_string, gen->validation & GENPROC_VALID_CPU_BRAND ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Processor ID = %llx %s\n", gen->proc_id, gen->validation & GENPROC_VALID_CPU_ID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Target Address = %llx %s\n", gen->target_addr, gen->validation & GENPROC_VALID_TGT_ADDR ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Requestor Identifier = %llx %s\n", gen->requestor_id, gen->validation & GENPROC_VALID_REQR_ID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Responder Identifier = %llx %s\n", gen->responder_id, gen->validation & GENPROC_VALID_RSPR_ID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " c Instruction IP = %llx %s\n", gen->instruction_ip, gen->validation & GENPROC_VALID_INSTR_IP ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return sizeof(*gen);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t parse_cper_structure(void *st, guid_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!guidcmp(&type, &CPER_SEC_PROC_GENERIC_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return parse_cper_structure_generic(st);</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (!guidcmp(&type, &CPER_SEC_PROC_IA32X64_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return parse_cper_structure_x86(st);</span><br><span style="color: hsl(120, 100%, 40%);">+ // else if...</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, "Error, you asked me to parse type for ");</span><br><span style="color: hsl(120, 100%, 40%);">+ print_guid(type);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t entry382_size(void *e382)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ acpi_hest_generic_data_t *entry = (acpi_hest_generic_data_t *)e382;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (entry->revision == HEST_GENERIC_ENTRY_V300)</span><br><span style="color: hsl(120, 100%, 40%);">+ return sizeof(acpi_hest_generic_data_v300_t) + entry->data_length;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return sizeof(acpi_hest_generic_data_t) + entry->data_length;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *guids382[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ "PROCESSOR_GENERIC",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PROCESSOR_SPECIFIC_X86_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PROCESSOR_SPECIFIC_ARM_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PLATFORM_MEMORY_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PLATFORM_MEMORY2_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCIE_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "FW_ERROR_RECORD_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCI_PCIX_BUS_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "PCI_DEVICE_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "DMAR_GENERIC_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "DIRECTED_IO_DMAR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "IOMMU_DMAR_GUID",</span><br><span style="color: hsl(120, 100%, 40%);">+ "you did something wrong"</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const char *guid382_name(guid_t guid)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PROC_GENERIC_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PROC_IA32X64_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[1];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PROC_ARM_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[2];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PLATFORM_MEM_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[3];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PLATFORM_MEM2_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[4];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PCIE_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[5];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_FW_ERR_REC_REF_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[6];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PCI_X_BUS_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[7];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_PCI_DEV_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[8];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_DMAR_GENERIC_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[9];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_DMAR_VT_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[10];</span><br><span style="color: hsl(120, 100%, 40%);">+ if(!guidcmp(&guid, &CPER_SEC_DMAR_IOMMU_GUID))</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[11];</span><br><span style="color: hsl(120, 100%, 40%);">+ return guids382[12];</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void parse_382_data(acpi_hest_generic_data_v300_t *entry, size_t size)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while (size > offset) {</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ 382 found @0x%p sizeof(%s) = 0x%zx/%zd ___\n", entry, entry->revision == 0x300 ? "v3" : "old-type",</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->revision == 0x300 ? sizeof(acpi_hest_generic_data_v300_t) : sizeof(acpi_hest_generic_data_t),</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->revision == 0x300 ? sizeof(acpi_hest_generic_data_v300_t) : sizeof(acpi_hest_generic_data_t));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Section Type GUID = %s\n", guid382_name(entry->section_type));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Section Type = ");</span><br><span style="color: hsl(120, 100%, 40%);">+ print_guid(entry->section_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Severity = %x: %s\n", entry->error_severity, acpi_sev(entry->error_severity));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Revision = %x\n", entry->revision);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Validation = %x\n", entry->validation_bits);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Flags = %x\n", entry->flags);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Error Data Length = %x\n", entry->data_length);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 FRU ID = <todo> %s\n", entry->validation_bits & ACPI_GENERROR_VALID_FRUID ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 FRU text = <todo> %s\n", entry->validation_bits & ACPI_GENERROR_VALID_FRUID_TEXT ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (entry->revision == HEST_GENERIC_ENTRY_V300) {</span><br><span style="color: hsl(120, 100%, 40%);">+ /* I can cheat on x300 because I know only diff is timestamp */</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 3 Timestamp = %02x, %02x%02x/%02x/%02x %02x:%02x:%02x %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->timestamp.precise,</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->timestamp.century, entry->timestamp.year,</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->timestamp.month, entry->timestamp.day,</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->timestamp.hour, entry->timestamp.min, entry->timestamp.sec,</span><br><span style="color: hsl(120, 100%, 40%);">+ entry->validation_bits & ACPI_GENERROR_VALID_TIMESTAMP ? "V" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " 333333333333333333333333333333333333333333333333333333333\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* each table-382 entry should contain 0 or 1 cper structure at its end */</span><br><span style="color: hsl(120, 100%, 40%);">+ if (entry->data_length) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (entry->revision == HEST_GENERIC_ENTRY_V300)</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_cper_structure((void *)(entry + 1), entry->section_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ else /* maybe I did this right? */</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_cper_structure((void *)((u8 *)entry + sizeof(acpi_hest_generic_data_t)), entry->section_type);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ offset += entry382_size(entry);</span><br><span style="color: hsl(120, 100%, 40%);">+ entry = (acpi_hest_generic_data_v300_t *)((u8 *)entry + entry382_size(entry));</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static size_t bert_entry_size(acpi_generic_error_status_t *bert_data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t size = sizeof(*bert_data);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bert_data->raw_data_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ size += bert_data->raw_data_offset + bert_data->data_length;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ size += bert_data->data_length;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return size;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static acpi_hest_generic_data_v300_t *ptr382_from_bert_entry(acpi_generic_error_status_t *bert_data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bert_data->data_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ return (acpi_hest_generic_data_v300_t *)((u8 *)bert_data + sizeof(*bert_data));</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return (acpi_hest_generic_data_v300_t *)NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static u8 *ptr_raw_from_bert_entry(acpi_generic_error_status_t *bert_data)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bert_data->raw_data_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ return (u8 *)bert_data + bert_data->raw_data_offset;</span><br><span style="color: hsl(120, 100%, 40%);">+ else</span><br><span style="color: hsl(120, 100%, 40%);">+ return (u8 *)NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void parse_bert_region(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void parse_bert_region(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ acpi_generic_error_status_t *bert_base;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_errors_region((void **)&bert_base, &size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ acpi_generic_error_status_t *bert_data = bert_base;</span><br><span style="color: hsl(120, 100%, 40%);">+ size_t offset = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ acpi_hest_generic_data_v300_t *gen382;</span><br><span style="color: hsl(120, 100%, 40%);">+ u8 *raw;</span><br><span style="color: hsl(120, 100%, 40%);">+ int entries;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, "***** BERT storage at 0x%p - 0x%p (%zd) *****\n", bert_base, (u8 *)bert_base + size, size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ while(offset < size) {</span><br><span style="color: hsl(120, 100%, 40%);">+ entries = (bert_data->block_status & GENERIC_ERR_STS_ENTRY_COUNT_MASK) >> GENERIC_ERR_STS_ENTRY_COUNT_SHIFT;</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " ___ BERT entry @0x%p - (sizeof(status)=0x%zx/%zd) ___\n", bert_data, sizeof(*bert_data), sizeof(*bert_data));</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b Block Status = %x\n", bert_data->block_status);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b severity =%s%s%s%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->block_status & BIT(0) ? " uncorrectable" : "",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->block_status & BIT(1) ? " correctable" : "",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->block_status & BIT(2) ? " mult-uncorrected" : "",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->block_status & BIT(3) ? " mult-corrected" : "");</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b count = %x\n", entries);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b Raw Data Offset = %x\n", bert_data->raw_data_offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b Raw Data Length = %x\n", bert_data->raw_data_length);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b Data Length = %x\n", bert_data->data_length);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b Error Severity = %x: %s\n", bert_data->error_severity, acpi_sev(bert_data->error_severity));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bert_data->data_length && bert_data->data_length < sizeof(acpi_hest_generic_data_v300_t))</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b ERROR: data length not large enough: %d < %zd\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->data_length, sizeof(acpi_hest_generic_data_v300_t));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (bert_data->raw_data_length && bert_data->raw_data_offset < sizeof(*bert_data) + bert_data->data_length)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " b ERROR: raw data offset is bad: %d < %zd + %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data->raw_data_offset, sizeof(*bert_data), bert_data->data_length);</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, " bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* can have zero or more data entries, of type 382 and/or of raw */</span><br><span style="color: hsl(120, 100%, 40%);">+ gen382 = ptr382_from_bert_entry(bert_data); // todo: this only handles a single 382 entry</span><br><span style="color: hsl(120, 100%, 40%);">+ if (gen382)</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_382_data(gen382, bert_data->data_length);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ raw = ptr_raw_from_bert_entry(bert_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (raw)</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(0, "todo: dump raw data\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ offset += bert_entry_size(bert_data);</span><br><span style="color: hsl(120, 100%, 40%);">+ bert_data = (acpi_generic_error_status_t *)((u8 *)bert_data + offset);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/soc/amd/stoneyridge/finalize.c b/src/soc/amd/stoneyridge/finalize.c</span><br><span>index 21d203c..25cfee9 100644</span><br><span>--- a/src/soc/amd/stoneyridge/finalize.c</span><br><span>+++ b/src/soc/amd/stoneyridge/finalize.c</span><br><span>@@ -49,10 +49,17 @@</span><br><span> printk(BIOS_WARNING, "Failed to finalize all cores\n");</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void parse_bert_region(void); // todo: remove me</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void soc_finalize(void *unused)</span><br><span> {</span><br><span> finalize_cores();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ /* In the event the region got misplaced and SMM_LOCKed, this is a</span><br><span style="color: hsl(120, 100%, 40%);">+ * good place to see that.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+ parse_bert_region();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> post_code(POST_OS_BOOT);</span><br><span> }</span><br><span> </span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/28480">change 28480</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/28480"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8ecf920499a662db34a332e9df05e4ee2383b6d4 </div>
<div style="display:none"> Gerrit-Change-Number: 28480 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Marshall Dawson <marshalldawson3rd@gmail.com> </div>