blob: 88401f0b4b6f990b7ea75d0deeee4046f5eb1c89 [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.
Lee Leahy0946ec32015-04-20 15:24:54 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Lee Leahy0946ec32015-04-20 15:24:54 -070015 */
16
17#include <stddef.h>
Aaron Durbin932e09d2016-07-13 23:09:52 -050018#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070019#include <arch/io.h>
20#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>
robbie zhang13a2e942016-02-10 11:40:11 -080025#include <cpu/intel/microcode.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070026#include <cpu/x86/mtrr.h>
27#include <ec/google/chromeec/ec.h>
28#include <ec/google/chromeec/ec_commands.h>
29#include <elog.h>
Lee Leahyb092c9e2016-01-01 18:09:50 -080030#include <fsp/romstage.h>
Aaron Durbindecd0622017-12-15 12:26:40 -070031#include <mrc_cache.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070032#include <reset.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>
Philipp Deppenwiesed88fb362017-10-18 20:26:18 +020039#include <security/tpm/tis.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070040#include <vendorcode/google/chromeos/chromeos.h>
41
Aaron Durbine6af4be2015-09-24 12:26:31 -050042asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
Lee Leahy0946ec32015-04-20 15:24:54 -070043{
44 void *top_of_stack;
45 struct pei_data pei_data;
46 struct romstage_params params = {
Lee Leahy0946ec32015-04-20 15:24:54 -070047 .pei_data = &pei_data,
Aaron Durbine6af4be2015-09-24 12:26:31 -050048 .chipset_context = fih,
Lee Leahy0946ec32015-04-20 15:24:54 -070049 };
50
51 post_code(0x30);
52
Lee Leahy0946ec32015-04-20 15:24:54 -070053 timestamp_add_now(TS_START_ROMSTAGE);
54
Elyes HAOUAS77537312016-07-30 15:37:26 +020055 /* Load microcode before RAM init */
robbie zhang13a2e942016-02-10 11:40:11 -080056 if (IS_ENABLED(CONFIG_SUPPORT_CPU_UCODE_IN_CBFS))
57 intel_update_microcode_from_cbfs();
58
Lee Leahy0946ec32015-04-20 15:24:54 -070059 memset(&pei_data, 0, sizeof(pei_data));
60
Lee Leahy0946ec32015-04-20 15:24:54 -070061 /* Display parameters */
Lee Leahyc253a922017-03-13 17:36:39 -070062 if (!IS_ENABLED(CONFIG_NO_MMCONF_SUPPORT))
63 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
64 CONFIG_MMCONF_BASE_ADDRESS);
Aaron Durbin929b6022015-12-09 16:00:18 -060065 printk(BIOS_INFO, "Using FSP 1.1\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070066
67 /* Display FSP banner */
Aaron Durbine6af4be2015-09-24 12:26:31 -050068 print_fsp_info(fih);
Lee Leahy0946ec32015-04-20 15:24:54 -070069
Aaron Durbin929b6022015-12-09 16:00:18 -060070 /* Stash FSP version. */
71 params.fsp_version = fsp_version(fih);
72
Lee Leahy0946ec32015-04-20 15:24:54 -070073 /* Get power state */
74 params.power_state = fill_power_state();
75
Lee Leahy0946ec32015-04-20 15:24:54 -070076 /* Call into mainboard. */
77 mainboard_romstage_entry(&params);
78 soc_after_ram_init(&params);
79 post_code(0x38);
80
81 top_of_stack = setup_stack_and_mtrrs();
82
Lee Leahy3e5bc1f2015-06-24 11:17:54 -070083 printk(BIOS_DEBUG, "Calling FspTempRamExit API\n");
84 timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START);
Lee Leahy0946ec32015-04-20 15:24:54 -070085 return top_of_stack;
86}
87
Aaron Durbine6af4be2015-09-24 12:26:31 -050088void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
89{
90 return romstage_main(fih);
91}
92
Lee Leahy0946ec32015-04-20 15:24:54 -070093/* Entry from the mainboard. */
94void romstage_common(struct romstage_params *params)
95{
Subrata Banik0beac812017-07-12 15:13:53 +053096 bool s3wake;
Aaron Durbin31be2c92016-12-03 22:08:20 -060097 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -070098 struct pei_data *pei_data;
99
100 post_code(0x32);
101
102 timestamp_add_now(TS_BEFORE_INITRAM);
103
104 pei_data = params->pei_data;
105 pei_data->boot_mode = params->power_state->prev_sleep_state;
Subrata Banik0beac812017-07-12 15:13:53 +0530106 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -0700107
Subrata Banik0beac812017-07-12 15:13:53 +0530108 if (IS_ENABLED(CONFIG_ELOG_BOOT_COUNT) && !s3wake)
Lee Leahy0946ec32015-04-20 15:24:54 -0700109 boot_count_increment();
Lee Leahy0946ec32015-04-20 15:24:54 -0700110
111 /* Perform remaining SOC initialization */
112 soc_pre_ram_init(params);
113 post_code(0x33);
114
115 /* Check recovery and MRC cache */
116 params->pei_data->saved_data_size = 0;
117 params->pei_data->saved_data = NULL;
118 if (!params->pei_data->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -0700119 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700120 /* Recovery mode does not use MRC cache */
121 printk(BIOS_DEBUG,
122 "Recovery mode: not using MRC cache.\n");
Lee Leahya6089692016-01-05 16:34:58 -0800123 } else if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -0600124 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
125 params->fsp_version,
126 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700127 /* MRC cache found */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600128 params->pei_data->saved_data_size =
129 region_device_sz(&rdev);
130 params->pei_data->saved_data = rdev_mmap_full(&rdev);
131 /* Assum boot device is memory mapped. */
132 assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED));
Aaron Durbin932e09d2016-07-13 23:09:52 -0500133 } else if (params->pei_data->boot_mode == ACPI_S3) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700134 /* Waking from S3 and no cache. */
135 printk(BIOS_DEBUG,
136 "No MRC cache found in S3 resume path.\n");
137 post_code(POST_RESUME_FAILURE);
138 hard_reset();
139 } else {
140 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700141 }
142 }
143
144 /* Initialize RAM */
145 raminit(params);
146 timestamp_add_now(TS_AFTER_INITRAM);
147
148 /* Save MRC output */
Lee Leahya6089692016-01-05 16:34:58 -0800149 if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) {
150 printk(BIOS_DEBUG, "MRC data at %p %d bytes\n",
151 pei_data->data_to_save, pei_data->data_to_save_size);
Aaron Durbin932e09d2016-07-13 23:09:52 -0500152 if ((params->pei_data->boot_mode != ACPI_S3)
Lee Leahya6089692016-01-05 16:34:58 -0800153 && (params->pei_data->data_to_save_size != 0)
154 && (params->pei_data->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -0700155 mrc_cache_stash_data(MRC_TRAINING_DATA,
156 params->fsp_version,
157 params->pei_data->data_to_save,
158 params->pei_data->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -0700159 }
160
161 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +0530162 if (!s3wake)
163 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700164
165 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -0600166 if (romstage_handoff_init(
167 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Lee Leahy0946ec32015-04-20 15:24:54 -0700168 hard_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700169
Duncan Lauriefe4983e2016-03-14 09:29:09 -0700170 /*
171 * Initialize the TPM, unless the TPM was already initialized
172 * in verstage and used to verify romstage.
173 */
174 if (IS_ENABLED(CONFIG_LPC_TPM) &&
Duncan Lauriefe4983e2016-03-14 09:29:09 -0700175 !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
176 init_tpm(params->power_state->prev_sleep_state ==
Aaron Durbin932e09d2016-07-13 23:09:52 -0500177 ACPI_S3);
Lee Leahy0946ec32015-04-20 15:24:54 -0700178}
179
Aaron Durbine6af4be2015-09-24 12:26:31 -0500180void after_cache_as_ram_stage(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700181{
Lee Leahy0946ec32015-04-20 15:24:54 -0700182 /* Load the ramstage. */
Kyösti Mälkki65e8f642016-06-27 11:27:56 +0300183 run_ramstage();
Lee Leahy0946ec32015-04-20 15:24:54 -0700184 die("ERROR - Failed to load ramstage!");
185}
186
187/* Initialize the power state */
188__attribute__((weak)) struct chipset_power_state *fill_power_state(void)
189{
Lee Leahy0946ec32015-04-20 15:24:54 -0700190 return NULL;
191}
192
Lee Leahy0946ec32015-04-20 15:24:54 -0700193/* Board initialization before and after RAM is enabled */
194__attribute__((weak)) void mainboard_romstage_entry(
195 struct romstage_params *params)
196{
Lee Leahy0946ec32015-04-20 15:24:54 -0700197 post_code(0x31);
198
199 /* Initliaze memory */
200 romstage_common(params);
201}
202
203/* Save the DIMM information for SMBIOS table 17 */
Lee Leahy0946ec32015-04-20 15:24:54 -0700204__attribute__((weak)) void mainboard_save_dimm_info(
205 struct romstage_params *params)
206{
207 int channel;
208 CHANNEL_INFO *channel_info;
209 int dimm;
210 DIMM_INFO *dimm_info;
211 int dimm_max;
212 void *hob_list_ptr;
213 EFI_HOB_GUID_TYPE *hob_ptr;
214 int index;
215 struct memory_info *mem_info;
216 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
217 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
218
219 /* Locate the memory info HOB, presence validated by raminit */
220 hob_list_ptr = fsp_get_hob_list();
221 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
222 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
223
224 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
225 if (IS_ENABLED(CONFIG_DISPLAY_HOBS)) {
226 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
227 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
228 memory_info_hob->Revision);
229 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
230 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700231 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700232 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700233 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
234 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700235 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
236 memory_info_hob->ErrorCorrectionType);
237 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
238 memory_info_hob->ChannelCount);
239 for (channel = 0; channel < memory_info_hob->ChannelCount;
240 channel++) {
241 channel_info = &memory_info_hob->ChannelInfo[channel];
242 printk(BIOS_DEBUG, " Channel %d\n", channel);
243 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
244 channel_info->ChannelId);
245 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
246 channel_info->DimmCount);
247 for (dimm = 0; dimm < channel_info->DimmCount;
248 dimm++) {
249 dimm_info = &channel_info->DimmInfo[dimm];
250 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
251 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
252 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700253 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700254 dimm_info->SizeInMb);
255 }
256 }
257 }
258
259 /*
260 * Allocate CBMEM area for DIMM information used to populate SMBIOS
261 * table 17
262 */
263 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
264 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
265 if (mem_info == NULL)
266 return;
267 memset(mem_info, 0, sizeof(*mem_info));
268
269 /* Describe the first N DIMMs in the system */
270 index = 0;
271 dimm_max = ARRAY_SIZE(mem_info->dimm);
272 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
273 if (index >= dimm_max)
274 break;
275 channel_info = &memory_info_hob->ChannelInfo[channel];
276 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
277 if (index >= dimm_max)
278 break;
279 dimm_info = &channel_info->DimmInfo[dimm];
280
281 /* Populate the DIMM information */
282 if (dimm_info->SizeInMb) {
283 mem_info->dimm[index].dimm_size =
284 dimm_info->SizeInMb;
285 mem_info->dimm[index].ddr_type =
286 memory_info_hob->MemoryType;
287 mem_info->dimm[index].ddr_frequency =
288 memory_info_hob->MemoryFrequencyInMHz;
289 mem_info->dimm[index].channel_num =
290 channel_info->ChannelId;
291 mem_info->dimm[index].dimm_num =
292 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700293 switch (memory_info_hob->DataWidth) {
294 default:
295 case 8:
296 mem_info->dimm[index].bus_width =
297 MEMORY_BUS_WIDTH_8;
298 break;
299
300 case 16:
301 mem_info->dimm[index].bus_width =
302 MEMORY_BUS_WIDTH_16;
303 break;
304
305 case 32:
306 mem_info->dimm[index].bus_width =
307 MEMORY_BUS_WIDTH_32;
308 break;
309
310 case 64:
311 mem_info->dimm[index].bus_width =
312 MEMORY_BUS_WIDTH_64;
313 break;
314
315 case 128:
316 mem_info->dimm[index].bus_width =
317 MEMORY_BUS_WIDTH_128;
318 break;
319 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700320
321 /* Add any mainboard specific information */
322 mainboard_add_dimm_info(params, mem_info,
323 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700324 index++;
325 }
326 }
327 }
328 mem_info->dimm_cnt = index;
329 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
330}
Lee Leahy0946ec32015-04-20 15:24:54 -0700331
Duncan Laurie46a2c772015-07-20 16:48:55 -0700332/* Add any mainboard specific information */
333__attribute__((weak)) void mainboard_add_dimm_info(
334 struct romstage_params *params,
335 struct memory_info *mem_info,
336 int channel, int dimm, int index)
337{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700338}
339
Lee Leahy0946ec32015-04-20 15:24:54 -0700340/* Get the memory configuration data */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600341__attribute__((weak)) int mrc_cache_get_current(int type, uint32_t version,
342 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700343{
Lee Leahy0946ec32015-04-20 15:24:54 -0700344 return -1;
345}
346
347/* Save the memory configuration data */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600348__attribute__((weak)) int mrc_cache_stash_data(int type, uint32_t version,
349 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700350{
Lee Leahy0946ec32015-04-20 15:24:54 -0700351 return -1;
352}
353
354/* Transition RAM from off or self-refresh to active */
355__attribute__((weak)) void raminit(struct romstage_params *params)
356{
Lee Leahy0946ec32015-04-20 15:24:54 -0700357 post_code(0x34);
358 die("ERROR - No RAM initialization specified!\n");
359}
360
Lee Leahy0946ec32015-04-20 15:24:54 -0700361/* Display the memory configuration */
362__attribute__((weak)) void report_memory_config(void)
363{
Lee Leahy0946ec32015-04-20 15:24:54 -0700364}
365
Lee Leahy0946ec32015-04-20 15:24:54 -0700366/* Choose top of stack and setup MTRRs */
367__attribute__((weak)) void *setup_stack_and_mtrrs(void)
368{
Lee Leahy0946ec32015-04-20 15:24:54 -0700369 die("ERROR - Must specify top of stack!\n");
370 return NULL;
371}
372
Lee Leahy0946ec32015-04-20 15:24:54 -0700373/* SOC initialization after RAM is enabled */
374__attribute__((weak)) void soc_after_ram_init(struct romstage_params *params)
375{
Lee Leahy0946ec32015-04-20 15:24:54 -0700376}
377
Lee Leahy0946ec32015-04-20 15:24:54 -0700378/* SOC initialization before RAM is enabled */
379__attribute__((weak)) void soc_pre_ram_init(struct romstage_params *params)
380{
Lee Leahy0946ec32015-04-20 15:24:54 -0700381}