blob: 90760970a5d0b9ee8de7f3f2bba12ee47b1546a2 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Lee Leahy0946ec32015-04-20 15:24:54 -07003
4#include <stddef.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07005#include <acpi/acpi.h>
Aaron Durbin31be2c92016-12-03 22:08:20 -06006#include <assert.h>
Lee Leahy0946ec32015-04-20 15:24:54 -07007#include <console/console.h>
8#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +02009#include <cf9_reset.h>
robbie zhang13a2e942016-02-10 11:40:11 -080010#include <cpu/intel/microcode.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070011#include <cpu/x86/mtrr.h>
12#include <ec/google/chromeec/ec.h>
13#include <ec/google/chromeec/ec_commands.h>
14#include <elog.h>
Lee Leahyb092c9e2016-01-01 18:09:50 -080015#include <fsp/romstage.h>
Aaron Durbindecd0622017-12-15 12:26:40 -070016#include <mrc_cache.h>
Kyösti Mälkki65e8f642016-06-27 11:27:56 +030017#include <program_loading.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070018#include <romstage_handoff.h>
Lee Leahy0be6d932015-06-26 11:15:42 -070019#include <smbios.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070020#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060021#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070022#include <timestamp.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070023#include <vendorcode/google/chromeos/chromeos.h>
24
Arthur Heymans73ac1212019-05-23 14:41:19 +020025static void raminit_common(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -070026{
Subrata Banik0beac812017-07-12 15:13:53 +053027 bool s3wake;
Aaron Durbin31be2c92016-12-03 22:08:20 -060028 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -070029
30 post_code(0x32);
31
32 timestamp_add_now(TS_BEFORE_INITRAM);
33
Subrata Banik0beac812017-07-12 15:13:53 +053034 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -070035
Kyösti Mälkki7f50afb2019-09-11 17:12:26 +030036 elog_boot_notify(s3wake);
Lee Leahy0946ec32015-04-20 15:24:54 -070037
38 /* Perform remaining SOC initialization */
39 soc_pre_ram_init(params);
40 post_code(0x33);
41
42 /* Check recovery and MRC cache */
Nico Huber66318aa2019-05-04 16:59:20 +020043 params->saved_data_size = 0;
44 params->saved_data = NULL;
45 if (!params->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -070046 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -070047 /* Recovery mode does not use MRC cache */
48 printk(BIOS_DEBUG,
49 "Recovery mode: not using MRC cache.\n");
Julius Wernercd49cce2019-03-05 16:53:33 -080050 } else if (CONFIG(CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -060051 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
52 params->fsp_version,
53 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -070054 /* MRC cache found */
Nico Huber66318aa2019-05-04 16:59:20 +020055 params->saved_data_size = region_device_sz(&rdev);
56 params->saved_data = rdev_mmap_full(&rdev);
Elyes HAOUAS18958382018-08-07 12:23:16 +020057 /* Assume boot device is memory mapped. */
Julius Wernercd49cce2019-03-05 16:53:33 -080058 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
Nico Huber16895c52019-05-04 16:29:17 +020059 } else if (s3wake) {
Lee Leahy0946ec32015-04-20 15:24:54 -070060 /* Waking from S3 and no cache. */
61 printk(BIOS_DEBUG,
62 "No MRC cache found in S3 resume path.\n");
63 post_code(POST_RESUME_FAILURE);
Patrick Rudolphf677d172018-10-01 19:17:11 +020064 /* FIXME: A "system" reset is likely enough: */
65 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -070066 } else {
67 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070068 }
69 }
70
71 /* Initialize RAM */
72 raminit(params);
73 timestamp_add_now(TS_AFTER_INITRAM);
74
75 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -080076 if (CONFIG(CACHE_MRC_SETTINGS)) {
Nico Huber66318aa2019-05-04 16:59:20 +020077 printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n",
78 params->data_to_save, params->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +020079 if (!s3wake
Nico Huber66318aa2019-05-04 16:59:20 +020080 && (params->data_to_save_size != 0)
81 && (params->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -070082 mrc_cache_stash_data(MRC_TRAINING_DATA,
83 params->fsp_version,
Nico Huber66318aa2019-05-04 16:59:20 +020084 params->data_to_save,
85 params->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -070086 }
87
88 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +053089 if (!s3wake)
90 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -070091
92 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -060093 if (romstage_handoff_init(
94 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +020095 /* FIXME: A "system" reset is likely enough: */
96 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -070097}
98
Arthur Heymans73ac1212019-05-23 14:41:19 +020099void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
100{
101 struct romstage_params params = {
102 .chipset_context = fih,
103 };
104
105 post_code(0x30);
106
107 timestamp_add_now(TS_START_ROMSTAGE);
108
109 /* Load microcode before RAM init */
110 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS))
111 intel_update_microcode_from_cbfs();
112
113 /* Display parameters */
114 if (!CONFIG(NO_MMCONF_SUPPORT))
115 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
116 CONFIG_MMCONF_BASE_ADDRESS);
117 printk(BIOS_INFO, "Using FSP 1.1\n");
118
119 /* Display FSP banner */
120 print_fsp_info(fih);
121
122 /* Stash FSP version. */
123 params.fsp_version = fsp_version(fih);
124
125 /* Get power state */
126 params.power_state = fill_power_state();
127
128 /* Board initialization before and after RAM is enabled */
129 mainboard_pre_raminit(&params);
130
131 post_code(0x31);
132
133 /* Initialize memory */
134 raminit_common(&params);
135
136 soc_after_ram_init(&params);
137 post_code(0x38);
138}
139
Lee Leahy0946ec32015-04-20 15:24:54 -0700140/* Initialize the power state */
Aaron Durbin64031672018-04-21 14:45:32 -0600141__weak struct chipset_power_state *fill_power_state(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700142{
Lee Leahy0946ec32015-04-20 15:24:54 -0700143 return NULL;
144}
145
Lee Leahy0946ec32015-04-20 15:24:54 -0700146/* Board initialization before and after RAM is enabled */
Arthur Heymans73ac1212019-05-23 14:41:19 +0200147__weak void mainboard_pre_raminit(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700148{
Lee Leahy0946ec32015-04-20 15:24:54 -0700149}
150
151/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600152__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700153 struct romstage_params *params)
154{
155 int channel;
156 CHANNEL_INFO *channel_info;
157 int dimm;
158 DIMM_INFO *dimm_info;
159 int dimm_max;
160 void *hob_list_ptr;
161 EFI_HOB_GUID_TYPE *hob_ptr;
162 int index;
163 struct memory_info *mem_info;
164 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
165 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
166
167 /* Locate the memory info HOB, presence validated by raminit */
168 hob_list_ptr = fsp_get_hob_list();
169 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
170 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
171
172 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800173 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700174 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
175 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
176 memory_info_hob->Revision);
177 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
178 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700179 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700180 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700181 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
182 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700183 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
184 memory_info_hob->ErrorCorrectionType);
185 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
186 memory_info_hob->ChannelCount);
187 for (channel = 0; channel < memory_info_hob->ChannelCount;
188 channel++) {
189 channel_info = &memory_info_hob->ChannelInfo[channel];
190 printk(BIOS_DEBUG, " Channel %d\n", channel);
191 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
192 channel_info->ChannelId);
193 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
194 channel_info->DimmCount);
195 for (dimm = 0; dimm < channel_info->DimmCount;
196 dimm++) {
197 dimm_info = &channel_info->DimmInfo[dimm];
198 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
199 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
200 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700201 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700202 dimm_info->SizeInMb);
203 }
204 }
205 }
206
207 /*
208 * Allocate CBMEM area for DIMM information used to populate SMBIOS
209 * table 17
210 */
211 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
Julius Werner540a9802019-12-09 13:03:29 -0800212 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: %p\n", mem_info);
Lee Leahy0946ec32015-04-20 15:24:54 -0700213 if (mem_info == NULL)
214 return;
215 memset(mem_info, 0, sizeof(*mem_info));
216
217 /* Describe the first N DIMMs in the system */
218 index = 0;
219 dimm_max = ARRAY_SIZE(mem_info->dimm);
220 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
221 if (index >= dimm_max)
222 break;
223 channel_info = &memory_info_hob->ChannelInfo[channel];
224 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
225 if (index >= dimm_max)
226 break;
227 dimm_info = &channel_info->DimmInfo[dimm];
228
229 /* Populate the DIMM information */
230 if (dimm_info->SizeInMb) {
231 mem_info->dimm[index].dimm_size =
232 dimm_info->SizeInMb;
233 mem_info->dimm[index].ddr_type =
234 memory_info_hob->MemoryType;
235 mem_info->dimm[index].ddr_frequency =
236 memory_info_hob->MemoryFrequencyInMHz;
237 mem_info->dimm[index].channel_num =
238 channel_info->ChannelId;
239 mem_info->dimm[index].dimm_num =
240 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700241 switch (memory_info_hob->DataWidth) {
242 default:
243 case 8:
244 mem_info->dimm[index].bus_width =
245 MEMORY_BUS_WIDTH_8;
246 break;
247
248 case 16:
249 mem_info->dimm[index].bus_width =
250 MEMORY_BUS_WIDTH_16;
251 break;
252
253 case 32:
254 mem_info->dimm[index].bus_width =
255 MEMORY_BUS_WIDTH_32;
256 break;
257
258 case 64:
259 mem_info->dimm[index].bus_width =
260 MEMORY_BUS_WIDTH_64;
261 break;
262
263 case 128:
264 mem_info->dimm[index].bus_width =
265 MEMORY_BUS_WIDTH_128;
266 break;
267 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700268
269 /* Add any mainboard specific information */
270 mainboard_add_dimm_info(params, mem_info,
271 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700272 index++;
273 }
274 }
275 }
276 mem_info->dimm_cnt = index;
277 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
278}
Lee Leahy0946ec32015-04-20 15:24:54 -0700279
Duncan Laurie46a2c772015-07-20 16:48:55 -0700280/* Add any mainboard specific information */
Aaron Durbin64031672018-04-21 14:45:32 -0600281__weak void mainboard_add_dimm_info(
Duncan Laurie46a2c772015-07-20 16:48:55 -0700282 struct romstage_params *params,
283 struct memory_info *mem_info,
284 int channel, int dimm, int index)
285{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700286}
287
Lee Leahy0946ec32015-04-20 15:24:54 -0700288/* Get the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600289__weak int mrc_cache_get_current(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600290 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700291{
Lee Leahy0946ec32015-04-20 15:24:54 -0700292 return -1;
293}
294
295/* Save the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600296__weak int mrc_cache_stash_data(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600297 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700298{
Lee Leahy0946ec32015-04-20 15:24:54 -0700299 return -1;
300}
301
Lee Leahy0946ec32015-04-20 15:24:54 -0700302/* Display the memory configuration */
Aaron Durbin64031672018-04-21 14:45:32 -0600303__weak void report_memory_config(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700304{
Lee Leahy0946ec32015-04-20 15:24:54 -0700305}
306
Lee Leahy0946ec32015-04-20 15:24:54 -0700307/* SOC initialization after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600308__weak void soc_after_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700309{
Lee Leahy0946ec32015-04-20 15:24:54 -0700310}
311
Lee Leahy0946ec32015-04-20 15:24:54 -0700312/* SOC initialization before RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600313__weak void soc_pre_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700314{
Lee Leahy0946ec32015-04-20 15:24:54 -0700315}