<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>