coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
raminit.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <acpi/acpi.h>
4 #include <cbmem.h>
5 #include <cf9_reset.h>
6 #include <commonlib/helpers.h>
7 #include <console/console.h>
8 #include <cpu/x86/smm.h>
9 #include <fsp/romstage.h>
10 #include <fsp/util.h>
11 #include <lib.h>
12 #include <string.h>
13 #include <timestamp.h>
14 
16 {
17  const bool s3wake = params->power_state->prev_sleep_state == ACPI_S3;
18  const EFI_GUID bootldr_tolum_guid = FSP_BOOTLOADER_TOLUM_HOB_GUID;
19  EFI_HOB_RESOURCE_DESCRIPTOR *cbmem_root;
20  FSP_INFO_HEADER *fsp_header;
21  EFI_HOB_RESOURCE_DESCRIPTOR *fsp_memory;
22  FSP_MEMORY_INIT fsp_memory_init;
23  FSP_MEMORY_INIT_PARAMS fsp_memory_init_params;
24  const EFI_GUID fsp_reserved_guid =
25  FSP_RESERVED_MEMORY_RESOURCE_HOB_GUID;
26  void *fsp_reserved_memory_area;
27  FSP_INIT_RT_COMMON_BUFFER fsp_rt_common_buffer;
28  void *hob_list_ptr;
29  FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
30  const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
31  MEMORY_INIT_UPD memory_init_params;
32  const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
33  u32 *mrc_hob;
34  u32 fsp_reserved_bytes;
35  MEMORY_INIT_UPD *original_params;
36  EFI_STATUS status;
37  VPD_DATA_REGION *vpd_ptr;
38  UPD_DATA_REGION *upd_ptr;
39  int fsp_verification_failure = 0;
40  EFI_PEI_HOB_POINTERS hob_ptr;
41  uintptr_t smm_base;
42  size_t smm_size;
43 
44  /*
45  * Find and copy the UPD region to the stack so the platform can modify
46  * the settings if needed. Modifications to the UPD buffer are done in
47  * the platform callback code. The platform callback code is also
48  * responsible for assigning the UpdDataRngPtr to this buffer if any
49  * updates are made. The default state is to leave the UpdDataRngPtr
50  * set to NULL. This indicates that the FSP code will use the UPD
51  * region in the FSP binary.
52  */
54  fsp_header = params->chipset_context;
55  vpd_ptr = (VPD_DATA_REGION *)(fsp_header->CfgRegionOffset +
56  fsp_header->ImageBase);
57  printk(BIOS_DEBUG, "VPD Data: %p\n", vpd_ptr);
58  upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
59  fsp_header->ImageBase);
60  printk(BIOS_DEBUG, "UPD Data: %p\n", upd_ptr);
61  original_params = (void *)((u8 *)upd_ptr +
62  upd_ptr->MemoryInitUpdOffset);
63  memcpy(&memory_init_params, original_params,
64  sizeof(memory_init_params));
65 
66  /* Zero fill RT Buffer data and start populating fields. */
67  memset(&fsp_rt_common_buffer, 0, sizeof(fsp_rt_common_buffer));
68  if (s3wake) {
69  fsp_rt_common_buffer.BootMode = BOOT_ON_S3_RESUME;
70  } else if (params->saved_data != NULL) {
71  fsp_rt_common_buffer.BootMode =
72  BOOT_ASSUMING_NO_CONFIGURATION_CHANGES;
73  } else {
74  fsp_rt_common_buffer.BootMode = BOOT_WITH_FULL_CONFIGURATION;
75  }
76  fsp_rt_common_buffer.UpdDataRgnPtr = &memory_init_params;
77  fsp_rt_common_buffer.BootLoaderTolumSize = cbmem_overhead_size();
78 
79  /* Get any board specific changes */
80  fsp_memory_init_params.NvsBufferPtr = (void *)params->saved_data;
81  fsp_memory_init_params.RtBufferPtr = &fsp_rt_common_buffer;
82  fsp_memory_init_params.HobListPtr = &hob_list_ptr;
83 
84  /* Update the UPD data */
85  soc_memory_init_params(params, &memory_init_params);
86  mainboard_memory_init_params(params, &memory_init_params);
87 
88  if (CONFIG(MMA))
89  setup_mma(&memory_init_params);
90 
92 
93  /* Display the UPD data */
94  if (CONFIG(DISPLAY_UPD_DATA))
95  soc_display_memory_init_params(original_params,
96  &memory_init_params);
97 
98  /* Call FspMemoryInit to initialize RAM */
99  fsp_memory_init = (FSP_MEMORY_INIT)(fsp_header->ImageBase
100  + fsp_header->FspMemoryInitEntryOffset);
101  printk(BIOS_DEBUG, "Calling FspMemoryInit: %p\n", fsp_memory_init);
102  printk(BIOS_SPEW, " %p: NvsBufferPtr\n",
103  fsp_memory_init_params.NvsBufferPtr);
104  printk(BIOS_SPEW, " %p: RtBufferPtr\n",
105  fsp_memory_init_params.RtBufferPtr);
106  printk(BIOS_SPEW, " %p: HobListPtr\n",
107  fsp_memory_init_params.HobListPtr);
108 
111  status = fsp_memory_init(&fsp_memory_init_params);
113  post_code(0x37);
115 
116  printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status);
117  if (status != EFI_SUCCESS)
119  "ERROR - FspMemoryInit failed to initialize memory!\n");
120 
121  /* Locate the FSP reserved memory area */
122  fsp_reserved_bytes = 0;
123  fsp_memory = get_resource_hob(&fsp_reserved_guid, hob_list_ptr);
124  if (fsp_memory == NULL) {
125  fsp_verification_failure = 1;
127  "7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB missing!\n");
128  } else {
129  fsp_reserved_bytes = fsp_memory->ResourceLength;
130  printk(BIOS_DEBUG, "Reserving 0x%016lx bytes for FSP\n",
131  (unsigned long int)fsp_reserved_bytes);
132  }
133 
134  /* Display SMM area */
135  if (CONFIG(HAVE_SMI_HANDLER)) {
136  smm_region(&smm_base, &smm_size);
137  printk(BIOS_DEBUG, "0x%08x: smm_size\n", (unsigned int)smm_size);
138  printk(BIOS_DEBUG, "0x%08x: smm_base\n", (unsigned int)smm_base);
139  }
140 
141  /* Migrate CAR data */
142  printk(BIOS_DEBUG, "%p: cbmem_top\n", cbmem_top());
143  if (!s3wake) {
145  fsp_reserved_bytes);
147  fsp_reserved_bytes)) {
148  printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
149  /* Failed S3 resume, reset to come up cleanly */
150  /* FIXME: A "system" reset is likely enough: */
151  full_reset();
152  }
153 
154  /* Save the FSP runtime parameters. */
155  fsp_set_runtime(fsp_header, hob_list_ptr);
156 
157  /* Lookup the FSP_BOOTLOADER_TOLUM_HOB */
158  cbmem_root = get_resource_hob(&bootldr_tolum_guid, hob_list_ptr);
159  if (cbmem_root == NULL) {
160  fsp_verification_failure = 1;
161  printk(BIOS_ERR, "7.4: FSP_BOOTLOADER_TOLUM_HOB missing!\n");
162  printk(BIOS_ERR, "BootLoaderTolumSize: 0x%08x bytes\n",
163  fsp_rt_common_buffer.BootLoaderTolumSize);
164  }
165 
166  /* Locate the FSP_SMBIOS_MEMORY_INFO HOB */
167  memory_info_hob = get_guid_hob(&memory_info_hob_guid,
168  hob_list_ptr);
169  if (memory_info_hob == NULL) {
170  printk(BIOS_ERR, "FSP_SMBIOS_MEMORY_INFO HOB missing!\n");
171  fsp_verification_failure = 1;
172  }
173 
174  if (hob_list_ptr == NULL)
176  "ERROR - HOB pointer is NULL!\n");
177 
178  /*
179  * Verify that FSP is generating the required HOBs:
180  * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
181  * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified above
182  * 7.3: FSP_NON_VOLATILE_STORAGE_HOB only produced when
183  * new NVS data is generated, verified below
184  * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified above
185  * 7.5: EFI_PEI_GRAPHICS_INFO_HOB produced by SiliconInit
186  * FSP_SMBIOS_MEMORY_INFO HOB verified above
187  */
188  hob_ptr.Raw = get_guid_hob(&mrc_guid, hob_list_ptr);
189  if ((hob_ptr.Raw == NULL) && (params->saved_data == NULL)) {
190  printk(BIOS_ERR, "7.3: FSP_NON_VOLATILE_STORAGE_HOB missing!\n");
191  fsp_verification_failure = 1;
192  }
193 
194  /* Verify all the HOBs are present */
195  if (fsp_verification_failure)
196  printk(BIOS_ERR, "Missing one or more required FSP HOBs!\n");
197 
198  /* Display the HOBs */
199  if (CONFIG(DISPLAY_HOBS))
200  print_hob_type_structure(0, hob_list_ptr);
201 
202  /* Get the address of the CBMEM region for the FSP reserved memory */
203  fsp_reserved_memory_area = cbmem_find(CBMEM_ID_FSP_RESERVED_MEMORY);
204  printk(BIOS_DEBUG, "%p: fsp_reserved_memory_area\n",
205  fsp_reserved_memory_area);
206 
207  /* Verify the order of CBMEM root and FSP memory */
208  if ((fsp_memory != NULL) && (cbmem_root != NULL) &&
209  (cbmem_root->PhysicalStart <= fsp_memory->PhysicalStart)) {
210  fsp_verification_failure = 1;
211  printk(BIOS_ERR, "FSP reserved memory above CBMEM root!\n");
212  }
213 
214  /* Verify that the FSP memory was properly reserved */
215  if ((fsp_memory != NULL) && ((fsp_reserved_memory_area == NULL) ||
216  (fsp_memory->PhysicalStart !=
217  (unsigned int)fsp_reserved_memory_area))) {
218  fsp_verification_failure = 1;
219  printk(BIOS_ERR, "Reserving FSP memory area!\n");
220 
221  if (CONFIG(HAVE_SMI_HANDLER) && cbmem_root != NULL) {
222  size_t delta_bytes = smm_base
223  - cbmem_root->PhysicalStart
224  - cbmem_root->ResourceLength;
226  "0x%08x: Chipset reserved bytes reported by FSP\n",
227  (unsigned int)delta_bytes);
229  "Please verify the chipset reserved size\n");
230  }
231  }
232 
233  /* Verify the FSP 1.1 HOB interface */
234  if (fsp_verification_failure)
236  "ERROR - coreboot's requirements not met by FSP binary!\n");
237 
238  /* Locate the memory configuration data to speed up the next reboot */
239  mrc_hob = get_guid_hob(&mrc_guid, hob_list_ptr);
240  if (mrc_hob == NULL) {
242  "Memory Configuration Data Hob not present\n");
243  } else {
244  params->data_to_save = GET_GUID_HOB_DATA(mrc_hob);
245  params->data_to_save_size = ALIGN_UP(
246  ((u32)GET_HOB_LENGTH(mrc_hob)), 16);
247  }
248 }
249 
250 /* Initialize the SoC after MemoryInit */
252 {
253  printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
254 }
void * memcpy(void *dest, const void *src, size_t n)
Definition: memcpy.c:7
void * memset(void *dstpp, int c, size_t len)
Definition: memset.c:12
static struct sdram_info params
Definition: sdram_configs.c:83
#define ALIGN_UP(x, a)
Definition: helpers.h:17
int cbmem_initialize_id_size(u32 id, u64 size)
Definition: imd_cbmem.c:93
void * cbmem_top(void)
Definition: imd_cbmem.c:18
static size_t cbmem_overhead_size(void)
Definition: cbmem.h:38
void cbmem_initialize_empty_id_size(u32 id, u64 size)
Definition: imd_cbmem.c:62
void * cbmem_find(u32 id)
Definition: imd_cbmem.c:166
#define CBMEM_ID_FSP_RESERVED_MEMORY
Definition: cbmem_id.h:25
void full_reset(void)
Definition: cf9_reset.c:45
#define printk(level,...)
Definition: stdlib.h:16
#define die_with_post_code(value, fmt,...)
Definition: console.h:21
void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, MEMORY_INIT_UPD *new)
Definition: romstage.c:128
void mainboard_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *memory_params)
Definition: romstage.c:18
void soc_memory_init_params(struct romstage_params *params, MEMORY_INIT_UPD *upd)
Definition: romstage.c:99
void setup_mma(MEMORY_INIT_UPD *memory_upd)
__weak void mainboard_after_memory_init(void)
Definition: raminit.c:251
void raminit(struct romstage_params *params)
Definition: raminit.c:15
@ CONFIG
Definition: dsi_common.h:201
void fsp_memory_init(bool s3wake)
Definition: memory_init.c:350
void fsp_set_runtime(FSP_INFO_HEADER *fih, void *hob_list)
Definition: fsp_util.c:177
void print_hob_type_structure(u16 hob_type, void *hob_list_ptr)
Definition: hob.c:235
void * get_resource_hob(const EFI_GUID *guid, const void *hob_start)
Definition: hob.c:65
void * get_guid_hob(const EFI_GUID *guid, const void *hob_start)
Definition: hob.c:48
@ ACPI_S3
Definition: acpi.h:1383
void smm_region(uintptr_t *start, size_t *size)
Definition: memmap.c:50
void timestamp_add_now(enum timestamp_id id)
Definition: timestamp.c:141
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#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
#define post_code(value)
Definition: post_code.h:12
#define POST_MEM_PREINIT_PREP_END
Pre-memory init preparation end.
Definition: post_codes.h:83
#define POST_RAM_FAILURE
RAM failure.
Definition: post_codes.h:346
#define POST_INVALID_VENDOR_BINARY
Vendor binary error.
Definition: post_codes.h:338
#define POST_FSP_MEMORY_INIT
Before calling FSP MemoryInit.
Definition: post_codes.h:239
#define POST_MEM_PREINIT_PREP_START
Pre-memory init preparation start.
Definition: post_codes.h:75
const struct smm_save_state_ops *legacy_ops __weak
Definition: save_state.c:8
#define FSP_SMBIOS_MEMORY_INFO_GUID
Definition: romstage.c:23
#define NULL
Definition: stddef.h:19
uint32_t u32
Definition: stdint.h:51
unsigned long uintptr_t
Definition: stdint.h:21
uint8_t u8
Definition: stdint.h:45
@ TS_FSP_MEMORY_INIT_START
@ TS_FSP_MEMORY_INIT_END