summaryrefslogtreecommitdiffstats
path: root/src/soc
diff options
context:
space:
mode:
authorMarshall Dawson <marshalldawson3rd@gmail.com>2019-01-30 11:56:52 -0700
committerMartin Roth <martinroth@google.com>2019-02-04 21:17:57 +0000
commitf56249ba0b1cf4bf83d93f3d717d3eb8a0624ff2 (patch)
tree6a80ae02764c4d85422846c83a52c07709bdf79b /src/soc
parentaaac678e800dd9a6c0b2ca63d3cebfb3005628f8 (diff)
downloadcoreboot-f56249ba0b1cf4bf83d93f3d717d3eb8a0624ff2.tar.gz
coreboot-f56249ba0b1cf4bf83d93f3d717d3eb8a0624ff2.tar.bz2
coreboot-f56249ba0b1cf4bf83d93f3d717d3eb8a0624ff2.zip
soc/amd/stoneyridge: Reboot if missing MRC cache info
AGESA doesn't detect invalid NV data during AmdInitResume(). In cases where the data has been erased, or cannot be found, reboot the system. Otherwise the user will experience a hang when cbmem isn't recovered and the postcar frame cannot be initialized. BUG=b:122725586 TEST=Write S3 NV save data with 0xff and force reboot Change-Id: Ib3cf2515f300decd3de198f7741660d95ee4c744 Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com> Reviewed-on: https://review.coreboot.org/c/31160 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin Roth <martinroth@google.com>
Diffstat (limited to 'src/soc')
-rw-r--r--src/soc/amd/common/block/s3/s3_resume.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/src/soc/amd/common/block/s3/s3_resume.c b/src/soc/amd/common/block/s3/s3_resume.c
index 04414e8a2e6c..eb0148f964ac 100644
--- a/src/soc/amd/common/block/s3/s3_resume.c
+++ b/src/soc/amd/common/block/s3/s3_resume.c
@@ -16,28 +16,44 @@
#include <stage_cache.h>
#include <mrc_cache.h>
+#include <reset.h>
#include <console/console.h>
+#include <soc/southbridge.h>
#include <amdblocks/s3_resume.h>
/* Training data versioning is not supported or tracked. */
#define DEFAULT_MRC_VERSION 0
+static void reboot_from_resume(const char *message) /* Does not return */
+{
+ printk(BIOS_ERR, "%s", message);
+ set_pm1cnt_s5();
+ board_reset();
+}
+
void get_s3nv_info(void **base, size_t *size)
{
struct region_device rdev;
if (mrc_cache_get_current(MRC_TRAINING_DATA, DEFAULT_MRC_VERSION,
- &rdev)) {
- printk(BIOS_ERR, "mrc_cache_get_current returned error\n");
- return;
- }
+ &rdev))
+ reboot_from_resume("mrc_cache_get_current error, rebooting.\n");
+
*base = rdev_mmap_full(&rdev);
*size = region_device_sz(&rdev);
if (!*base || !*size)
- printk(BIOS_ERR, "Error: S3 NV data not found\n");
- else
- printk(BIOS_SPEW, "S3 NV data @0x%p 0x%0zx total bytes\n",
- *base, *size);
+ reboot_from_resume("Error: S3 NV data not found, rebooting.\n");
+
+ /* Read 16 bytes to infer if the NV has been erased from flash. */
+ int i;
+ uint32_t erased = 0xffffffff;
+ for (i = 0; i < 4; i++)
+ erased &= read32((uint32_t *)*base + i);
+
+ if (erased == 0xffffffff)
+ reboot_from_resume("Error: S3 NV data invalid, rebooting.\n");
+
+ printk(BIOS_SPEW, "S3 NV data @0x%p, 0x%0zx bytes\n", *base, *size);
}
void get_s3vol_info(void **base, size_t *size)