<p>Marshall Dawson has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/29406">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">NOT_FOR_MERGE soc/amd/stoneridge: Add DRAM check for s3<br><br>Allocate cbmem space to store DRAM check data during S3.  Verify the<br>the data is unchanged during the resume.  Due to where the save and<br>verify steps are placed, the test cannot capture 100% of potential<br>memory corruption causes in coreboot.<br><br>The ranges to verify are determined by the coreboot tables that are<br>constructed at the end of POST.  If a failure occurs within RAM available<br>to the OS, the test reports "ERROR" to force suspend_stress_test to<br>stop.  Otherwise, the mismatch is reported as "FYI", e.g. in memory<br>owned by coreboot.<br><br>The granularity of blocks to check within each range is configurable,<br>and defaults to 1MB.  The size of data stored for each block is 32 bits.<br>Both parameters may be changed if desired.<br><br>CAUTION: This test must not be deployed in a shipping system.  It<br>         disables TSEG, and its protections, in order to allow the<br>         performance to be at an acceptable level.<br>TODO:    Add the capability of checking DRAM above 4GB.<br><br>TEST=Suspend and resume grunt.  Verify mismatch with induced error.<br>BUG=b:118157730<br><br>Change-Id: I375dd7ea9a3ab8992f1616126bcbd9724e4fc9a0<br>Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com><br>---<br>M src/soc/amd/common/block/pi/amd_resume_final.c<br>M src/soc/amd/stoneyridge/Kconfig<br>M src/soc/amd/stoneyridge/Makefile.inc<br>M src/soc/amd/stoneyridge/finalize.c<br>M src/soc/amd/stoneyridge/include/soc/iomap.h<br>A src/soc/amd/stoneyridge/include/soc/s3test_util.h<br>A src/soc/amd/stoneyridge/s3test_util.c<br>M src/soc/amd/stoneyridge/smihandler.c<br>8 files changed, 431 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/06/29406/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/soc/amd/common/block/pi/amd_resume_final.c b/src/soc/amd/common/block/pi/amd_resume_final.c</span><br><span>index a282665..7ee6470 100644</span><br><span>--- a/src/soc/amd/common/block/pi/amd_resume_final.c</span><br><span>+++ b/src/soc/amd/common/block/pi/amd_resume_final.c</span><br><span>@@ -15,10 +15,22 @@</span><br><span> </span><br><span> #include <bootstate.h></span><br><span> #include <amdblocks/agesawrapper_call.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/s3test_util.h></span><br><span> </span><br><span> static void agesawrapper_s3finalrestore(void *unused)</span><br><span> {</span><br><span>  do_agesawrapper(agesawrapper_amds3finalrestore, "amds3finalrestore");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* todo: wrong place re. stoneyridge, but place here for now to ensure</span><br><span style="color: hsl(120, 100%, 40%);">+         * verification is as late as possible, and after AGESA.</span><br><span style="color: hsl(120, 100%, 40%);">+       *</span><br><span style="color: hsl(120, 100%, 40%);">+     * However, note that the ramstage copy and everything else in TSEG</span><br><span style="color: hsl(120, 100%, 40%);">+    * will be inaccessable if the BS_OS_RESUME, BS_ON_ENTRY soc_finalize()</span><br><span style="color: hsl(120, 100%, 40%);">+        * happens to run before this entry.  That scenario will guarantee a</span><br><span style="color: hsl(120, 100%, 40%);">+   * mismatch if TSEG is tested.</span><br><span style="color: hsl(120, 100%, 40%);">+         */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (IS_ENABLED(CONFIG_DEBUG_CHECKSUM_DRAM_ON_S3))</span><br><span style="color: hsl(120, 100%, 40%);">+             verify_dram_checksums();</span><br><span> }</span><br><span> </span><br><span> BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,</span><br><span>diff --git a/src/soc/amd/stoneyridge/Kconfig b/src/soc/amd/stoneyridge/Kconfig</span><br><span>index 4411984..1344d8b 100644</span><br><span>--- a/src/soc/amd/stoneyridge/Kconfig</span><br><span>+++ b/src/soc/amd/stoneyridge/Kconfig</span><br><span>@@ -385,4 +385,16 @@</span><br><span>          return to S0.  Otherwise the system will remain in S5 once power</span><br><span>     is restored.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+config DEBUG_CHECKSUM_DRAM_ON_S3</span><br><span style="color: hsl(120, 100%, 40%);">+  bool "Store checksums for DRAM during suspend"</span><br><span style="color: hsl(120, 100%, 40%);">+      default y   # todo - y for convenience but change to n</span><br><span style="color: hsl(120, 100%, 40%);">+        help</span><br><span style="color: hsl(120, 100%, 40%);">+    During a suspend cycle, checksum the DRAM and store the results in</span><br><span style="color: hsl(120, 100%, 40%);">+    cbmem.  Compare the values during a resume and dump any discrepancies</span><br><span style="color: hsl(120, 100%, 40%);">+         to the console.  Certain errors may be reasonable, depending on their</span><br><span style="color: hsl(120, 100%, 40%);">+         addresses.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+          This is a test feature and must never be deployed in production</span><br><span style="color: hsl(120, 100%, 40%);">+       systems.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> endif # SOC_AMD_STONEYRIDGE_FP4 || SOC_AMD_STONEYRIDGE_FT4</span><br><span>diff --git a/src/soc/amd/stoneyridge/Makefile.inc b/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>index c54b652..a2d317e 100644</span><br><span>--- a/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>+++ b/src/soc/amd/stoneyridge/Makefile.inc</span><br><span>@@ -117,6 +117,7 @@</span><br><span> ramstage-$(CONFIG_SPI_FLASH) += spi.c</span><br><span> ramstage-y += finalize.c</span><br><span> ramstage-y += nb_util.c</span><br><span style="color: hsl(120, 100%, 40%);">+ramstage-$(CONFIG_DEBUG_CHECKSUM_DRAM_ON_S3) += s3test_util.c</span><br><span> </span><br><span> smm-y += monotonic_timer.c</span><br><span> smm-y += smihandler.c</span><br><span>@@ -127,6 +128,7 @@</span><br><span> smm-$(CONFIG_SPI_FLASH) += spi.c</span><br><span> smm-y += nb_util.c</span><br><span> smm-y += gpio.c</span><br><span style="color: hsl(120, 100%, 40%);">+smm-$(CONFIG_DEBUG_CHECKSUM_DRAM_ON_S3) += s3test_util.c</span><br><span> </span><br><span> CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge</span><br><span> CPPFLAGS_common += -I$(src)/soc/amd/stoneyridge/include</span><br><span>diff --git a/src/soc/amd/stoneyridge/finalize.c b/src/soc/amd/stoneyridge/finalize.c</span><br><span>index 45e6595..dbe06b0 100644</span><br><span>--- a/src/soc/amd/stoneyridge/finalize.c</span><br><span>+++ b/src/soc/amd/stoneyridge/finalize.c</span><br><span>@@ -31,7 +31,12 @@</span><br><span> </span><br><span>         if (IS_ENABLED(CONFIG_SMM_TSEG)) {</span><br><span>           mask = rdmsr(SMM_MASK_MSR);</span><br><span style="color: hsl(0, 100%, 40%);">-             mask.lo |= SMM_TSEG_VALID;</span><br><span style="color: hsl(120, 100%, 40%);">+            /* If TSEG is marked valid, the CPU enforces UC memory type</span><br><span style="color: hsl(120, 100%, 40%);">+            * outside of SMRAM while in the SMI handler.  Skipping this</span><br><span style="color: hsl(120, 100%, 40%);">+           * step allows the test to perform at an acceptable speed.</span><br><span style="color: hsl(120, 100%, 40%);">+             */</span><br><span style="color: hsl(120, 100%, 40%);">+           if (!IS_ENABLED(CONFIG_DEBUG_CHECKSUM_DRAM_ON_S3))</span><br><span style="color: hsl(120, 100%, 40%);">+                    mask.lo |= SMM_TSEG_VALID;</span><br><span>           wrmsr(SMM_MASK_MSR, mask);</span><br><span>   }</span><br><span> </span><br><span>diff --git a/src/soc/amd/stoneyridge/include/soc/iomap.h b/src/soc/amd/stoneyridge/include/soc/iomap.h</span><br><span>index 3e86564..5bcd084 100644</span><br><span>--- a/src/soc/amd/stoneyridge/include/soc/iomap.h</span><br><span>+++ b/src/soc/amd/stoneyridge/include/soc/iomap.h</span><br><span>@@ -72,6 +72,8 @@</span><br><span> #define SYS_RESET                 0xcf9</span><br><span> </span><br><span> /* BiosRam Ranges at 0xfed80500 or I/O 0xcd4/0xcd5 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BIOSRAM_S3DRAM_CHECK_BASE   0xe8 /* 4 bytes */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BIOSRAM_S3DRAM_LBMEM_BASE   0xec /* 4 bytes */</span><br><span> #define BIOSRAM_CBMEM_TOP         0xf0 /* 4 bytes */</span><br><span> #define BIOSRAM_UMA_SIZE          0xf4 /* 4 bytes */</span><br><span> #define BIOSRAM_UMA_BASE          0xf8 /* 8 bytes */</span><br><span>diff --git a/src/soc/amd/stoneyridge/include/soc/s3test_util.h b/src/soc/amd/stoneyridge/include/soc/s3test_util.h</span><br><span>new file mode 100644</span><br><span>index 0000000..a6dcdea</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/amd/stoneyridge/include/soc/s3test_util.h</span><br><span>@@ -0,0 +1,22 @@</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 (C) 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; 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%);">+#ifndef __PI_STONEYRIDGE_S3_TESTUTIL_H__</span><br><span style="color: hsl(120, 100%, 40%);">+#define __PI_STONEYRIDGE_S3_TESTUTIL_H__</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void store_dram_checksums(void);</span><br><span style="color: hsl(120, 100%, 40%);">+void verify_dram_checksums(void);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#endif /* __PI_STONEYRIDGE_S3_TESTUTIL_H__ */</span><br><span>diff --git a/src/soc/amd/stoneyridge/s3test_util.c b/src/soc/amd/stoneyridge/s3test_util.c</span><br><span>new file mode 100644</span><br><span>index 0000000..0aa76de</span><br><span>--- /dev/null</span><br><span>+++ b/src/soc/amd/stoneyridge/s3test_util.c</span><br><span>@@ -0,0 +1,368 @@</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 (C) 2018 Advanced Micro Devices</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; 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 <soc/southbridge.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/s3test_util.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/iomap.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <memrange.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/cache.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/x86/msr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cpu/amd/mtrr.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/console.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <memlayout.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <cbmem.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <bootstate.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <commonlib/coreboot_tables.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define CHECK_TYPE_SAVE 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define CHECK_TYPE_VERIFY 1</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MAX_CHECK_RANGES 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%);">+ * Adjust the block size as necessary to narrow in on the location of a failure.</span><br><span style="color: hsl(120, 100%, 40%);">+ * Normally a DWORD is stored for each 1MB test range, but this can be made</span><br><span style="color: hsl(120, 100%, 40%);">+ * smaller if space is a concern.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+#define TESTBLOCK_SZ (1 * MiB)</span><br><span style="color: hsl(120, 100%, 40%);">+#define USE_SUM_SIZE32</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef USE_SUM_SIZE8</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint8_t sum_t;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef USE_SUM_SIZE16</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint16_t sum_t;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef USE_SUM_SIZE32</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint32_t sum_t;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+#ifdef USE_SUM_SIZE64</span><br><span style="color: hsl(120, 100%, 40%);">+typedef uint64_t sum_t;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* source code shorteners */</span><br><span style="color: hsl(120, 100%, 40%);">+#define FOUR_GB ((uint64_t)4 * GiB)</span><br><span style="color: hsl(120, 100%, 40%);">+#define CL_SIZE ARCH_CACHELINE_ALIGN_SIZE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void write_dram_check_addr(void *base)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  biosram_write32(BIOSRAM_S3DRAM_CHECK_BASE, (uintptr_t)base);</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 *read_dram_check_addr(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return (void *)biosram_read32(BIOSRAM_S3DRAM_CHECK_BASE);</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 write_lbmem_addr(void *base)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   biosram_write32(BIOSRAM_S3DRAM_LBMEM_BASE, (uintptr_t)base);</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 *read_lbmem_addr(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return (void *)biosram_read32(BIOSRAM_S3DRAM_LBMEM_BASE);</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%);">+#define MEM_RANGE_COUNT(_rec) \</span><br><span style="color: hsl(120, 100%, 40%);">+       (((_rec)->size - sizeof(*(_rec))) / sizeof((_rec)->map[0]))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define MEM_RANGE_PTR(_rec, _idx) \</span><br><span style="color: hsl(120, 100%, 40%);">+      (void *)(((u8 *) (_rec)) + sizeof(*(_rec)) \</span><br><span style="color: hsl(120, 100%, 40%);">+          + (sizeof((_rec)->map[0]) * (_idx)))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static inline resource_t lb_unpack64(struct lb_uint64 val)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return (((resource_t) val.hi) << 32) | val.lo;</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%);">+/* These need to be consistent across POST and SMM but since those don't</span><br><span style="color: hsl(120, 100%, 40%);">+ * naturally share data, build the info from scratch.</span><br><span style="color: hsl(120, 100%, 40%);">+ * todo: convert to use devicetree instead?  or maybe coreboot tables'</span><br><span style="color: hsl(120, 100%, 40%);">+ *       knowledge of non-reserved memory?</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static int range_causes_error[MAX_CHECK_RANGES];</span><br><span style="color: hsl(120, 100%, 40%);">+static struct range_entry check_ranges[MAX_CHECK_RANGES];</span><br><span style="color: hsl(120, 100%, 40%);">+static struct memranges ranges = {</span><br><span style="color: hsl(120, 100%, 40%);">+  .entries = check_ranges,</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%);">+ * Parse coreboot's memory ranges to decide what to test and whether a modified</span><br><span style="color: hsl(120, 100%, 40%);">+ * range constitutes a failure.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * todo: This file doesn't do above 4GB so cap the ranges</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void fill_check_ranges(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct lb_memory *mem = (struct lb_memory *)read_lbmem_addr();</span><br><span style="color: hsl(120, 100%, 40%);">+        int count;</span><br><span style="color: hsl(120, 100%, 40%);">+    int lb_rng, chk_rng;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!mem) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "ERROR: Can't find saved pointer to lb tables\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</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%);">+   count = MEM_RANGE_COUNT(mem);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (count > MAX_CHECK_RANGES) {</span><br><span style="color: hsl(120, 100%, 40%);">+            /* maybe not really, as some won't be used... */</span><br><span style="color: hsl(120, 100%, 40%);">+          printk(BIOS_ERR, "ERROR: Need to increase MAX_CHECK_RANGES\n");</span><br><span style="color: hsl(120, 100%, 40%);">+             count = MAX_CHECK_RANGES;</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%);">+   chk_rng = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  for (lb_rng = 0 ; lb_rng < count ; lb_rng++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             struct lb_memory_range *range = MEM_RANGE_PTR(mem, lb_rng);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         if (range->type == LB_MEM_RESERVED</span><br><span style="color: hsl(120, 100%, 40%);">+                         || range->type == LB_MEM_VENDOR_RSVD</span><br><span style="color: hsl(120, 100%, 40%);">+                               || range->type == LB_MEM_UNUSABLE)</span><br><span style="color: hsl(120, 100%, 40%);">+                 continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           /* Still can't do >=4GB */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (lb_unpack64(range->start) >= FOUR_GB)</span><br><span style="color: hsl(120, 100%, 40%);">+                       continue;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (chk_rng)</span><br><span style="color: hsl(120, 100%, 40%);">+                  check_ranges[chk_rng - 1].next = &check_ranges[chk_rng];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                range_entry_init(check_ranges + chk_rng,</span><br><span style="color: hsl(120, 100%, 40%);">+                              lb_unpack64(range->start),</span><br><span style="color: hsl(120, 100%, 40%);">+                         MIN(FOUR_GB, lb_unpack64(range->start)</span><br><span style="color: hsl(120, 100%, 40%);">+                                             + lb_unpack64(range->size)),</span><br><span style="color: hsl(120, 100%, 40%);">+                               chk_rng);</span><br><span style="color: hsl(120, 100%, 40%);">+             range_causes_error[chk_rng] = range->type == LB_MEM_RAM ? 1 : 0;</span><br><span style="color: hsl(120, 100%, 40%);">+           chk_rng++;</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%);">+/* If necessary, fold a 64-bit value enough times to fit into sum_t */</span><br><span style="color: hsl(120, 100%, 40%);">+static sum_t sum_to_sumt(uint64_t sum64)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (sizeof(sum_t) == sizeof(uint64_t))</span><br><span style="color: hsl(120, 100%, 40%);">+                return sum64;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t sum32 = (uint32_t)(sum64 + (sum64 >> 32));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (sizeof(sum_t) == sizeof(uint32_t))</span><br><span style="color: hsl(120, 100%, 40%);">+                return sum32;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t sum16 = (uint16_t)(sum32 + (sum32 >> 16));</span><br><span style="color: hsl(120, 100%, 40%);">+     if (sizeof(sum_t) == sizeof(uint16_t))</span><br><span style="color: hsl(120, 100%, 40%);">+                return sum16;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t sum8 = (uint8_t)(sum16 + (sum16 >> 8));</span><br><span style="color: hsl(120, 100%, 40%);">+ return sum8;</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%);">+ * todo: this function cannot access >4GB</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static sum_t calc_range(resource_t rstart, resource_t rlimit)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint64_t sum;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *start, *end;</span><br><span style="color: hsl(120, 100%, 40%);">+   const uint8_t *aligned_start;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *aligned_end;</span><br><span style="color: hsl(120, 100%, 40%);">+   int pre_aligned_num;</span><br><span style="color: hsl(120, 100%, 40%);">+  int post_aligned_num;</span><br><span style="color: hsl(120, 100%, 40%);">+ int lines;</span><br><span style="color: hsl(120, 100%, 40%);">+    int i;</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *i8;</span><br><span style="color: hsl(120, 100%, 40%);">+    const uint64_t *i64;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        sum = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* since we don't do 4GB yet, help this function be prettier */</span><br><span style="color: hsl(120, 100%, 40%);">+   start = (u8 *)(uintptr_t)rstart;</span><br><span style="color: hsl(120, 100%, 40%);">+      end = (u8 *)(uintptr_t)rlimit + 1; /* treat end like start + size */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        aligned_start = (uint8_t *)ALIGN_UP((uintptr_t)start, CL_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+       aligned_end = (uint8_t *)ALIGN_DOWN((uintptr_t)end, CL_SIZE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       pre_aligned_num = (uintptr_t)aligned_start - (uintptr_t)start;</span><br><span style="color: hsl(120, 100%, 40%);">+        post_aligned_num = (uintptr_t)end - (uintptr_t)aligned_end;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ lines = ((uintptr_t)aligned_end - (uintptr_t)aligned_start) / CL_SIZE;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Do all unaligned as bytes, regardless of how many */</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i8 = start ; i8 < aligned_start ; i8++)</span><br><span style="color: hsl(120, 100%, 40%);">+               sum += *i8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ i64 = (uint64_t *)aligned_start;</span><br><span style="color: hsl(120, 100%, 40%);">+      for (i = 0 ; i < lines ; i++) { /* unroll one cacheline worth */</span><br><span style="color: hsl(120, 100%, 40%);">+           sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</span><br><span style="color: hsl(120, 100%, 40%);">+              sum += *(i64++);</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%);">+   for (i8 = aligned_end ; i8 < end ; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+            sum += *i8;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return sum_to_sumt(sum);</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_fail(resource_t begin, resource_t end, int e)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     printk(BIOS_ERR, "    %s: Mismatch found in 0x%llx-0x%llx\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                       range_causes_error[e] ? "ERROR" : "FYI", begin, end);</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 do_dram_checksums(int type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    printk(BIOS_DEBUG, "Begin calculating DRAM check data...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     sum_t *save_area = read_dram_check_addr();</span><br><span style="color: hsl(120, 100%, 40%);">+    struct range_entry *re;</span><br><span style="color: hsl(120, 100%, 40%);">+       resource_t blk;</span><br><span style="color: hsl(120, 100%, 40%);">+       int err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!save_area) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printk(BIOS_ERR, "Error: no DRAM check save error, exiting test.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</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%);">+   fill_check_ranges();</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%);">+     * Don't rely on this function being called after the SMM handler has</span><br><span style="color: hsl(120, 100%, 40%);">+      * already written back the cache contents.  Resume shouldn't make a</span><br><span style="color: hsl(120, 100%, 40%);">+       * difference worth caring about.</span><br><span style="color: hsl(120, 100%, 40%);">+      */</span><br><span style="color: hsl(120, 100%, 40%);">+   wbinvd();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   err = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      memranges_each_entry(re, &ranges) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk(BIOS_DEBUG, "  Calculate range 0x%llx-0x%llx\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                                                     re->begin, re->end);</span><br><span style="color: hsl(120, 100%, 40%);">+            for (blk = re->begin ; blk < re->end ; blk += TESTBLOCK_SZ) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        resource_t end = MIN(blk + TESTBLOCK_SZ - 1, re->end);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (type == CHECK_TYPE_SAVE)</span><br><span style="color: hsl(120, 100%, 40%);">+                          *(save_area) = calc_range(blk, end);</span><br><span style="color: hsl(120, 100%, 40%);">+                  else</span><br><span style="color: hsl(120, 100%, 40%);">+                          if (*save_area != calc_range(blk, end))</span><br><span style="color: hsl(120, 100%, 40%);">+                                       print_fail(blk, end, err);</span><br><span style="color: hsl(120, 100%, 40%);">+                    save_area++;</span><br><span style="color: hsl(120, 100%, 40%);">+          }</span><br><span style="color: hsl(120, 100%, 40%);">+             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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void highest_performance(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      /* todo: abstract better, especially if it moves out of stoneyridge</span><br><span style="color: hsl(120, 100%, 40%);">+    *</span><br><span style="color: hsl(120, 100%, 40%);">+     * The performance hit probably isn't substantial enough to worry</span><br><span style="color: hsl(120, 100%, 40%);">+  * about as long as we can cache outside of SMRAM.</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%);">+ /* CPU P-State to 0 */</span><br><span style="color: hsl(120, 100%, 40%);">+        msr_t pst = rdmsr(0xc0010062); // no define for this yet!?</span><br><span style="color: hsl(120, 100%, 40%);">+    pst.lo &= ~7;</span><br><span style="color: hsl(120, 100%, 40%);">+     wrmsr(0xc0010062, pst);</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 store_dram_checksums(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      printk(BIOS_DEBUG, "Begin calculating DRAM check data...\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     highest_performance();</span><br><span style="color: hsl(120, 100%, 40%);">+        do_dram_checksums(CHECK_TYPE_SAVE);</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 verify_dram_checksums(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ printk(BIOS_DEBUG, "|| S3 memory check beginning.  Certain miscompares should\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                       "|| be anticipated.  Addresses may be verified against the\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                       "|| coreboot table written at the end of POST.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      do_dram_checksums(CHECK_TYPE_VERIFY);</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%);">+ * During POST, ensure we have adequate cbmem space reserved for storing the</span><br><span style="color: hsl(120, 100%, 40%);">+ * check info.  This function should also be safe to call during a resume.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note that cbmem functions aren't available in SMM, but the file still builds</span><br><span style="color: hsl(120, 100%, 40%);">+ * OK since functions like this aren't referenced.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void setup_s3_dram_debug(int unused)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint64_t installed;</span><br><span style="color: hsl(120, 100%, 40%);">+   size_t size;</span><br><span style="color: hsl(120, 100%, 40%);">+  msr_t tom2 = rdmsr(TOP_MEM2);</span><br><span style="color: hsl(120, 100%, 40%);">+ void *mem;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* simple inference for installed memory, won't work for if <4 GB! */</span><br><span style="color: hsl(120, 100%, 40%);">+  installed = tom2.hi;</span><br><span style="color: hsl(120, 100%, 40%);">+  installed *= 4;</span><br><span style="color: hsl(120, 100%, 40%);">+       installed *= GiB;</span><br><span style="color: hsl(120, 100%, 40%);">+     size = installed / TESTBLOCK_SZ * sizeof(sum_t);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* cheat without making a new ID, currently only used for Family 10h */</span><br><span style="color: hsl(120, 100%, 40%);">+       mem = cbmem_add(CBMEM_ID_AMDMCT_MEMINFO, size);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!mem)</span><br><span style="color: hsl(120, 100%, 40%);">+             printk(BIOS_ERR, "Error, can't allocate cbmem to store DRAM S3 check data\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        write_dram_check_addr(mem);</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%);">+ * Use coreboot's calculations to determine what memory to test.  Right now</span><br><span style="color: hsl(120, 100%, 40%);">+ * save a pointer away and parse the info as needed.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+static void find_lb_tables_in_mem(void *unused)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct lb_header *header;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *ptr = (uint8_t *)cbmem_find(CBMEM_ID_CBTABLE);</span><br><span style="color: hsl(120, 100%, 40%);">+       int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!ptr) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printk(BIOS_ERR, "Error, S3 DRAM test setup: can't find the lb tables\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</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%);">+   header = (struct lb_header *)ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (strncmp((const char *)header->signature, "LBIO", 4)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printk(BIOS_ERR, "Error, S3 DRAM test setup: don't recognize the lb tables @0x%p\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            header);</span><br><span style="color: hsl(120, 100%, 40%);">+              return;</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%);">+   ptr += header->header_bytes;</span><br><span style="color: hsl(120, 100%, 40%);">+       for (i = 0; i < header->table_entries; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+           struct lb_record *rec = (struct lb_record *)ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rec->tag != LB_TAG_MEMORY) {</span><br><span style="color: hsl(120, 100%, 40%);">+                   ptr += rec->size;</span><br><span style="color: hsl(120, 100%, 40%);">+                  continue;</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%);">+           write_lbmem_addr(rec);</span><br><span style="color: hsl(120, 100%, 40%);">+                return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     printk(BIOS_ERR, "Error, S3 DRAM test setup: No LB_TAG_MEMORY found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    write_lbmem_addr(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%);">+RAMSTAGE_CBMEM_INIT_HOOK(setup_s3_dram_debug)</span><br><span style="color: hsl(120, 100%, 40%);">+BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_EXIT, find_lb_tables_in_mem, NULL);</span><br><span>diff --git a/src/soc/amd/stoneyridge/smihandler.c b/src/soc/amd/stoneyridge/smihandler.c</span><br><span>index 8985257..6782d20 100644</span><br><span>--- a/src/soc/amd/stoneyridge/smihandler.c</span><br><span>+++ b/src/soc/amd/stoneyridge/smihandler.c</span><br><span>@@ -24,6 +24,7 @@</span><br><span> #include <device/pci_def.h></span><br><span> #include <soc/smi.h></span><br><span> #include <soc/southbridge.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <soc/s3test_util.h></span><br><span> #include <elog.h></span><br><span> </span><br><span> /* bits in smm_io_trap   */</span><br><span>@@ -153,6 +154,12 @@</span><br><span>     }</span><br><span> </span><br><span>        if (slp_typ >= ACPI_S3) {</span><br><span style="color: hsl(120, 100%, 40%);">+          /*</span><br><span style="color: hsl(120, 100%, 40%);">+             * todo: how can I call this sooner?  This is the earliest</span><br><span style="color: hsl(120, 100%, 40%);">+             * opportunity when we're sure we're on our way to S3.</span><br><span style="color: hsl(120, 100%, 40%);">+                 */</span><br><span style="color: hsl(120, 100%, 40%);">+           store_dram_checksums();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>            /* Sleep Type Elog S3, S4, and S5 entry */</span><br><span>           if (IS_ENABLED(CONFIG_ELOG_GSMI))</span><br><span>                    elog_add_event_byte(ELOG_TYPE_ACPI_ENTER, slp_typ);</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/29406">change 29406</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/29406"/><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: I375dd7ea9a3ab8992f1616126bcbd9724e4fc9a0 </div>
<div style="display:none"> Gerrit-Change-Number: 29406 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Marshall Dawson <marshalldawson3rd@gmail.com> </div>