blob: 17bd638290e91670766d64ffffa5682ac1fe4d83 [file] [log] [blame]
Lee Leahy0946ec32015-04-20 15:24:54 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2014 Google Inc.
Lee Leahya6089692016-01-05 16:34:58 -08005 * Copyright (C) 2015-2016 Intel Corporation.
Frans Hendriks44d2c852018-12-03 10:40:06 +01006 * Copyright (C) 2018 Eltan B.V.
Lee Leahy0946ec32015-04-20 15:24:54 -07007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
Lee Leahy0946ec32015-04-20 15:24:54 -070016 */
17
18#include <stddef.h>
Aaron Durbin932e09d2016-07-13 23:09:52 -050019#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070020#include <arch/cbfs.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070021#include <arch/early_variables.h>
Aaron Durbin31be2c92016-12-03 22:08:20 -060022#include <assert.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070023#include <console/console.h>
24#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +020025#include <cf9_reset.h>
robbie zhang13a2e942016-02-10 11:40:11 -080026#include <cpu/intel/microcode.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070027#include <cpu/x86/mtrr.h>
28#include <ec/google/chromeec/ec.h>
29#include <ec/google/chromeec/ec_commands.h>
30#include <elog.h>
Lee Leahyb092c9e2016-01-01 18:09:50 -080031#include <fsp/romstage.h>
Aaron Durbindecd0622017-12-15 12:26:40 -070032#include <mrc_cache.h>
Kyösti Mälkki65e8f642016-06-27 11:27:56 +030033#include <program_loading.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070034#include <romstage_handoff.h>
Lee Leahy0be6d932015-06-26 11:15:42 -070035#include <smbios.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070036#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060037#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070038#include <timestamp.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070039#include <vendorcode/google/chromeos/chromeos.h>
40
Aaron Durbine6af4be2015-09-24 12:26:31 -050041asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
Lee Leahy0946ec32015-04-20 15:24:54 -070042{
43 void *top_of_stack;
44 struct pei_data pei_data;
45 struct romstage_params params = {
Lee Leahy0946ec32015-04-20 15:24:54 -070046 .pei_data = &pei_data,
Aaron Durbine6af4be2015-09-24 12:26:31 -050047 .chipset_context = fih,
Lee Leahy0946ec32015-04-20 15:24:54 -070048 };
49
50 post_code(0x30);
51
Lee Leahy0946ec32015-04-20 15:24:54 -070052 timestamp_add_now(TS_START_ROMSTAGE);
53
Elyes HAOUAS77537312016-07-30 15:37:26 +020054 /* Load microcode before RAM init */
Julius Wernercd49cce2019-03-05 16:53:33 -080055 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS))
robbie zhang13a2e942016-02-10 11:40:11 -080056 intel_update_microcode_from_cbfs();
57
Lee Leahy0946ec32015-04-20 15:24:54 -070058 memset(&pei_data, 0, sizeof(pei_data));
59
Lee Leahy0946ec32015-04-20 15:24:54 -070060 /* Display parameters */
Julius Wernercd49cce2019-03-05 16:53:33 -080061 if (!CONFIG(NO_MMCONF_SUPPORT))
Lee Leahyc253a922017-03-13 17:36:39 -070062 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
63 CONFIG_MMCONF_BASE_ADDRESS);
Aaron Durbin929b6022015-12-09 16:00:18 -060064 printk(BIOS_INFO, "Using FSP 1.1\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070065
66 /* Display FSP banner */
Aaron Durbine6af4be2015-09-24 12:26:31 -050067 print_fsp_info(fih);
Lee Leahy0946ec32015-04-20 15:24:54 -070068
Aaron Durbin929b6022015-12-09 16:00:18 -060069 /* Stash FSP version. */
70 params.fsp_version = fsp_version(fih);
71
Lee Leahy0946ec32015-04-20 15:24:54 -070072 /* Get power state */
73 params.power_state = fill_power_state();
74
Lee Leahy0946ec32015-04-20 15:24:54 -070075 /* Call into mainboard. */
76 mainboard_romstage_entry(&params);
77 soc_after_ram_init(&params);
78 post_code(0x38);
79
80 top_of_stack = setup_stack_and_mtrrs();
81
Lee Leahy3e5bc1f2015-06-24 11:17:54 -070082 printk(BIOS_DEBUG, "Calling FspTempRamExit API\n");
83 timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START);
Lee Leahy0946ec32015-04-20 15:24:54 -070084 return top_of_stack;
85}
86
Aaron Durbine6af4be2015-09-24 12:26:31 -050087void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
88{
89 return romstage_main(fih);
90}
91
Lee Leahy0946ec32015-04-20 15:24:54 -070092/* Entry from the mainboard. */
93void romstage_common(struct romstage_params *params)
94{
Subrata Banik0beac812017-07-12 15:13:53 +053095 bool s3wake;
Aaron Durbin31be2c92016-12-03 22:08:20 -060096 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -070097 struct pei_data *pei_data;
98
99 post_code(0x32);
100
101 timestamp_add_now(TS_BEFORE_INITRAM);
102
103 pei_data = params->pei_data;
Subrata Banik0beac812017-07-12 15:13:53 +0530104 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -0700105
Julius Wernercd49cce2019-03-05 16:53:33 -0800106 if (CONFIG(ELOG_BOOT_COUNT) && !s3wake)
Lee Leahy0946ec32015-04-20 15:24:54 -0700107 boot_count_increment();
Lee Leahy0946ec32015-04-20 15:24:54 -0700108
109 /* Perform remaining SOC initialization */
110 soc_pre_ram_init(params);
111 post_code(0x33);
112
113 /* Check recovery and MRC cache */
114 params->pei_data->saved_data_size = 0;
115 params->pei_data->saved_data = NULL;
116 if (!params->pei_data->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -0700117 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700118 /* Recovery mode does not use MRC cache */
119 printk(BIOS_DEBUG,
120 "Recovery mode: not using MRC cache.\n");
Julius Wernercd49cce2019-03-05 16:53:33 -0800121 } else if (CONFIG(CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -0600122 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
123 params->fsp_version,
124 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700125 /* MRC cache found */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600126 params->pei_data->saved_data_size =
127 region_device_sz(&rdev);
128 params->pei_data->saved_data = rdev_mmap_full(&rdev);
Elyes HAOUAS18958382018-08-07 12:23:16 +0200129 /* Assume boot device is memory mapped. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800130 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
Nico Huber16895c52019-05-04 16:29:17 +0200131 } else if (s3wake) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700132 /* Waking from S3 and no cache. */
133 printk(BIOS_DEBUG,
134 "No MRC cache found in S3 resume path.\n");
135 post_code(POST_RESUME_FAILURE);
Patrick Rudolphf677d172018-10-01 19:17:11 +0200136 /* FIXME: A "system" reset is likely enough: */
137 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700138 } else {
139 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700140 }
141 }
142
143 /* Initialize RAM */
144 raminit(params);
145 timestamp_add_now(TS_AFTER_INITRAM);
146
147 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -0800148 if (CONFIG(CACHE_MRC_SETTINGS)) {
Lee Leahya6089692016-01-05 16:34:58 -0800149 printk(BIOS_DEBUG, "MRC data at %p %d bytes\n",
150 pei_data->data_to_save, pei_data->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +0200151 if (!s3wake
Lee Leahya6089692016-01-05 16:34:58 -0800152 && (params->pei_data->data_to_save_size != 0)
153 && (params->pei_data->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -0700154 mrc_cache_stash_data(MRC_TRAINING_DATA,
155 params->fsp_version,
156 params->pei_data->data_to_save,
157 params->pei_data->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -0700158 }
159
160 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +0530161 if (!s3wake)
162 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700163
164 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -0600165 if (romstage_handoff_init(
166 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +0200167 /* FIXME: A "system" reset is likely enough: */
168 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700169}
170
Aaron Durbine6af4be2015-09-24 12:26:31 -0500171void after_cache_as_ram_stage(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700172{
Lee Leahy0946ec32015-04-20 15:24:54 -0700173 /* Load the ramstage. */
Kyösti Mälkki65e8f642016-06-27 11:27:56 +0300174 run_ramstage();
Lee Leahy0946ec32015-04-20 15:24:54 -0700175 die("ERROR - Failed to load ramstage!");
176}
177
178/* Initialize the power state */
Aaron Durbin64031672018-04-21 14:45:32 -0600179__weak struct chipset_power_state *fill_power_state(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700180{
Lee Leahy0946ec32015-04-20 15:24:54 -0700181 return NULL;
182}
183
Lee Leahy0946ec32015-04-20 15:24:54 -0700184/* Board initialization before and after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600185__weak void mainboard_romstage_entry(
Lee Leahy0946ec32015-04-20 15:24:54 -0700186 struct romstage_params *params)
187{
Lee Leahy0946ec32015-04-20 15:24:54 -0700188 post_code(0x31);
189
Frans Hendriks44d2c852018-12-03 10:40:06 +0100190 /* Initialize memory */
Lee Leahy0946ec32015-04-20 15:24:54 -0700191 romstage_common(params);
192}
193
194/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600195__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700196 struct romstage_params *params)
197{
198 int channel;
199 CHANNEL_INFO *channel_info;
200 int dimm;
201 DIMM_INFO *dimm_info;
202 int dimm_max;
203 void *hob_list_ptr;
204 EFI_HOB_GUID_TYPE *hob_ptr;
205 int index;
206 struct memory_info *mem_info;
207 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
208 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
209
210 /* Locate the memory info HOB, presence validated by raminit */
211 hob_list_ptr = fsp_get_hob_list();
212 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
213 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
214
215 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800216 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700217 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
218 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
219 memory_info_hob->Revision);
220 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
221 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700222 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700223 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700224 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
225 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700226 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
227 memory_info_hob->ErrorCorrectionType);
228 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
229 memory_info_hob->ChannelCount);
230 for (channel = 0; channel < memory_info_hob->ChannelCount;
231 channel++) {
232 channel_info = &memory_info_hob->ChannelInfo[channel];
233 printk(BIOS_DEBUG, " Channel %d\n", channel);
234 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
235 channel_info->ChannelId);
236 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
237 channel_info->DimmCount);
238 for (dimm = 0; dimm < channel_info->DimmCount;
239 dimm++) {
240 dimm_info = &channel_info->DimmInfo[dimm];
241 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
242 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
243 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700244 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700245 dimm_info->SizeInMb);
246 }
247 }
248 }
249
250 /*
251 * Allocate CBMEM area for DIMM information used to populate SMBIOS
252 * table 17
253 */
254 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
255 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
256 if (mem_info == NULL)
257 return;
258 memset(mem_info, 0, sizeof(*mem_info));
259
260 /* Describe the first N DIMMs in the system */
261 index = 0;
262 dimm_max = ARRAY_SIZE(mem_info->dimm);
263 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
264 if (index >= dimm_max)
265 break;
266 channel_info = &memory_info_hob->ChannelInfo[channel];
267 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
268 if (index >= dimm_max)
269 break;
270 dimm_info = &channel_info->DimmInfo[dimm];
271
272 /* Populate the DIMM information */
273 if (dimm_info->SizeInMb) {
274 mem_info->dimm[index].dimm_size =
275 dimm_info->SizeInMb;
276 mem_info->dimm[index].ddr_type =
277 memory_info_hob->MemoryType;
278 mem_info->dimm[index].ddr_frequency =
279 memory_info_hob->MemoryFrequencyInMHz;
280 mem_info->dimm[index].channel_num =
281 channel_info->ChannelId;
282 mem_info->dimm[index].dimm_num =
283 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700284 switch (memory_info_hob->DataWidth) {
285 default:
286 case 8:
287 mem_info->dimm[index].bus_width =
288 MEMORY_BUS_WIDTH_8;
289 break;
290
291 case 16:
292 mem_info->dimm[index].bus_width =
293 MEMORY_BUS_WIDTH_16;
294 break;
295
296 case 32:
297 mem_info->dimm[index].bus_width =
298 MEMORY_BUS_WIDTH_32;
299 break;
300
301 case 64:
302 mem_info->dimm[index].bus_width =
303 MEMORY_BUS_WIDTH_64;
304 break;
305
306 case 128:
307 mem_info->dimm[index].bus_width =
308 MEMORY_BUS_WIDTH_128;
309 break;
310 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700311
312 /* Add any mainboard specific information */
313 mainboard_add_dimm_info(params, mem_info,
314 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700315 index++;
316 }
317 }
318 }
319 mem_info->dimm_cnt = index;
320 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
321}
Lee Leahy0946ec32015-04-20 15:24:54 -0700322
Duncan Laurie46a2c772015-07-20 16:48:55 -0700323/* Add any mainboard specific information */
Aaron Durbin64031672018-04-21 14:45:32 -0600324__weak void mainboard_add_dimm_info(
Duncan Laurie46a2c772015-07-20 16:48:55 -0700325 struct romstage_params *params,
326 struct memory_info *mem_info,
327 int channel, int dimm, int index)
328{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700329}
330
Lee Leahy0946ec32015-04-20 15:24:54 -0700331/* Get the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600332__weak int mrc_cache_get_current(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600333 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700334{
Lee Leahy0946ec32015-04-20 15:24:54 -0700335 return -1;
336}
337
338/* Save the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600339__weak int mrc_cache_stash_data(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600340 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700341{
Lee Leahy0946ec32015-04-20 15:24:54 -0700342 return -1;
343}
344
Lee Leahy0946ec32015-04-20 15:24:54 -0700345/* Display the memory configuration */
Aaron Durbin64031672018-04-21 14:45:32 -0600346__weak void report_memory_config(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700347{
Lee Leahy0946ec32015-04-20 15:24:54 -0700348}
349
Lee Leahy0946ec32015-04-20 15:24:54 -0700350/* Choose top of stack and setup MTRRs */
Aaron Durbin64031672018-04-21 14:45:32 -0600351__weak void *setup_stack_and_mtrrs(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700352{
Lee Leahy0946ec32015-04-20 15:24:54 -0700353 die("ERROR - Must specify top of stack!\n");
354 return NULL;
355}
356
Lee Leahy0946ec32015-04-20 15:24:54 -0700357/* SOC initialization after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600358__weak void soc_after_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700359{
Lee Leahy0946ec32015-04-20 15:24:54 -0700360}
361
Lee Leahy0946ec32015-04-20 15:24:54 -0700362/* SOC initialization before RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600363__weak void soc_pre_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700364{
Lee Leahy0946ec32015-04-20 15:24:54 -0700365}