coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
s3_resume.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <stage_cache.h>
5 #include <mrc_cache.h>
6 #include <reset.h>
7 #include <console/console.h>
8 #include <soc/southbridge.h>
9 #include <amdblocks/s3_resume.h>
10 #include <amdblocks/acpi.h>
11 
12 /* Training data versioning is not supported or tracked. */
13 #define DEFAULT_MRC_VERSION 0
14 
15 static void __noreturn reboot_from_resume(const char *message)
16 {
17  printk(BIOS_ERR, "%s", message);
18  set_pm1cnt_s5();
19  board_reset();
20 }
21 
22 AGESA_STATUS OemInitResume(S3_DATA_BLOCK *dataBlock)
23 {
24  void *base;
25  size_t size;
26  int i;
27  uint32_t erased = 0xffffffff;
28 
31  &size);
32  if (!base || !size)
33  reboot_from_resume("Error: S3 NV data not found, rebooting.\n");
34 
35  /* Read 16 bytes to infer if the NV has been erased from flash. */
36  for (i = 0; i < 4; i++)
37  erased &= read32((uint32_t *)base + i);
38  if (erased == 0xffffffff)
39  reboot_from_resume("Error: S3 NV data invalid, rebooting.\n");
40 
41  dataBlock->NvStorage = base;
42  dataBlock->NvStorageSize = size;
43  printk(BIOS_SPEW, "S3 NV data @%p, 0x%0zx bytes\n",
44  dataBlock->NvStorage, (size_t)dataBlock->NvStorageSize);
45 
46  return AGESA_SUCCESS;
47 }
48 
49 AGESA_STATUS OemS3LateRestore(S3_DATA_BLOCK *dataBlock)
50 {
51  void *base = NULL;
52  size_t size = 0;
53 
55  if (!base || !size) {
56  printk(BIOS_ERR, "S3 volatile data not found\n");
57  return AGESA_FATAL;
58  }
59 
60  dataBlock->VolatileStorage = base;
61  dataBlock->VolatileStorageSize = size;
62  printk(BIOS_SPEW, "S3 volatile data @%p, 0x%0zx bytes\n",
63  dataBlock->VolatileStorage, (size_t)dataBlock->VolatileStorageSize);
64 
65  return AGESA_SUCCESS;
66 }
67 
68 AGESA_STATUS OemS3Save(S3_DATA_BLOCK *dataBlock)
69 {
71  dataBlock->NvStorage, dataBlock->NvStorageSize) < 0) {
72  printk(BIOS_ERR, "Failed to stash MRC data\n");
73  return AGESA_CRITICAL;
74  }
75 
76  stage_cache_add_raw(STAGE_S3_DATA, dataBlock->VolatileStorage,
77  dataBlock->VolatileStorageSize);
78 
79  return AGESA_SUCCESS;
80 }
#define AGESA_SUCCESS
Definition: Amd.h:38
#define AGESA_FATAL
Definition: Amd.h:44
unsigned int AGESA_STATUS
Definition: Amd.h:36
#define AGESA_CRITICAL
Definition: Amd.h:43
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define printk(level,...)
Definition: stdlib.h:16
#define __noreturn
Definition: compiler.h:31
__noreturn void board_reset(void)
Definition: reset.c:8
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
int mrc_cache_stash_data(int type, uint32_t version, const void *data, size_t size)
Returns < 0 on error, 0 on success.
Definition: mrc_cache.c:687
void * mrc_cache_current_mmap_leak(int type, uint32_t version, size_t *data_size)
mrc_cache_mmap_leak
Definition: mrc_cache.c:342
@ MRC_TRAINING_DATA
Definition: mrc_cache.h:11
#define DEFAULT_MRC_VERSION
Definition: s3_resume.c:13
static void __noreturn reboot_from_resume(const char *message)
Definition: s3_resume.c:15
AGESA_STATUS OemS3Save(S3_DATA_BLOCK *dataBlock)
Definition: s3_resume.c:68
AGESA_STATUS OemS3LateRestore(S3_DATA_BLOCK *dataBlock)
Definition: s3_resume.c:49
AGESA_STATUS OemInitResume(S3_DATA_BLOCK *dataBlock)
Definition: s3_resume.c:22
uintptr_t base
Definition: uart.c:17
void set_pm1cnt_s5(void)
Definition: acpi.c:111
static void stage_cache_add_raw(int stage_id, const void *base, const size_t size)
Definition: stage_cache.h:37
@ STAGE_S3_DATA
Definition: stage_cache.h:20
static void stage_cache_get_raw(int stage_id, void **base, size_t *size)
Definition: stage_cache.h:38
#define NULL
Definition: stddef.h:19
unsigned int uint32_t
Definition: stdint.h:14