blob: c2fc667dfd25af44e9d36ca3fb38969f7b8c40a7 [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>
Duncan Laurie91da91f2015-09-04 13:47:34 -070023#include <boardid.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070024#include <console/console.h>
25#include <cbmem.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>
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 <soc/intel/common/mrc_cache.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070037#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060038#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070039#include <timestamp.h>
40#include <tpm.h>
41#include <vendorcode/google/chromeos/chromeos.h>
42
Aaron Durbine6af4be2015-09-24 12:26:31 -050043asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
Lee Leahy0946ec32015-04-20 15:24:54 -070044{
45 void *top_of_stack;
46 struct pei_data pei_data;
47 struct romstage_params params = {
Lee Leahy0946ec32015-04-20 15:24:54 -070048 .pei_data = &pei_data,
Aaron Durbine6af4be2015-09-24 12:26:31 -050049 .chipset_context = fih,
Lee Leahy0946ec32015-04-20 15:24:54 -070050 };
51
52 post_code(0x30);
53
Lee Leahy0946ec32015-04-20 15:24:54 -070054 timestamp_add_now(TS_START_ROMSTAGE);
55
Elyes HAOUAS77537312016-07-30 15:37:26 +020056 /* Load microcode before RAM init */
robbie zhang13a2e942016-02-10 11:40:11 -080057 if (IS_ENABLED(CONFIG_SUPPORT_CPU_UCODE_IN_CBFS))
58 intel_update_microcode_from_cbfs();
59
Lee Leahy0946ec32015-04-20 15:24:54 -070060 memset(&pei_data, 0, sizeof(pei_data));
61
Lee Leahy0946ec32015-04-20 15:24:54 -070062 /* Display parameters */
Lee Leahyc253a922017-03-13 17:36:39 -070063 if (!IS_ENABLED(CONFIG_NO_MMCONF_SUPPORT))
64 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
65 CONFIG_MMCONF_BASE_ADDRESS);
Aaron Durbin929b6022015-12-09 16:00:18 -060066 printk(BIOS_INFO, "Using FSP 1.1\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070067
68 /* Display FSP banner */
Aaron Durbine6af4be2015-09-24 12:26:31 -050069 print_fsp_info(fih);
Lee Leahy0946ec32015-04-20 15:24:54 -070070
Aaron Durbin929b6022015-12-09 16:00:18 -060071 /* Stash FSP version. */
72 params.fsp_version = fsp_version(fih);
73
Lee Leahy0946ec32015-04-20 15:24:54 -070074 /* Get power state */
75 params.power_state = fill_power_state();
76
Duncan Laurie91da91f2015-09-04 13:47:34 -070077 /*
78 * Read and print board version. Done after SOC romstage
79 * in case PCH needs to be configured to talk to the EC.
80 */
81 if (IS_ENABLED(CONFIG_BOARD_ID_AUTO))
82 printk(BIOS_INFO, "MLB: board version %d\n", board_id());
83
Lee Leahy0946ec32015-04-20 15:24:54 -070084 /* Call into mainboard. */
85 mainboard_romstage_entry(&params);
86 soc_after_ram_init(&params);
87 post_code(0x38);
88
89 top_of_stack = setup_stack_and_mtrrs();
90
Lee Leahy3e5bc1f2015-06-24 11:17:54 -070091 printk(BIOS_DEBUG, "Calling FspTempRamExit API\n");
92 timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START);
Lee Leahy0946ec32015-04-20 15:24:54 -070093 return top_of_stack;
94}
95
Aaron Durbine6af4be2015-09-24 12:26:31 -050096void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
97{
98 return romstage_main(fih);
99}
100
Lee Leahy0946ec32015-04-20 15:24:54 -0700101/* Entry from the mainboard. */
102void romstage_common(struct romstage_params *params)
103{
Aaron Durbin31be2c92016-12-03 22:08:20 -0600104 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -0700105 struct pei_data *pei_data;
106
107 post_code(0x32);
108
109 timestamp_add_now(TS_BEFORE_INITRAM);
110
111 pei_data = params->pei_data;
112 pei_data->boot_mode = params->power_state->prev_sleep_state;
113
114#if IS_ENABLED(CONFIG_ELOG_BOOT_COUNT)
Aaron Durbin932e09d2016-07-13 23:09:52 -0500115 if (params->power_state->prev_sleep_state != ACPI_S3)
Lee Leahy0946ec32015-04-20 15:24:54 -0700116 boot_count_increment();
117#endif
118
119 /* Perform remaining SOC initialization */
120 soc_pre_ram_init(params);
121 post_code(0x33);
122
123 /* Check recovery and MRC cache */
124 params->pei_data->saved_data_size = 0;
125 params->pei_data->saved_data = NULL;
126 if (!params->pei_data->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -0700127 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700128 /* Recovery mode does not use MRC cache */
129 printk(BIOS_DEBUG,
130 "Recovery mode: not using MRC cache.\n");
Lee Leahya6089692016-01-05 16:34:58 -0800131 } else if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -0600132 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
133 params->fsp_version,
134 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700135 /* MRC cache found */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600136 params->pei_data->saved_data_size =
137 region_device_sz(&rdev);
138 params->pei_data->saved_data = rdev_mmap_full(&rdev);
139 /* Assum boot device is memory mapped. */
140 assert(IS_ENABLED(CONFIG_BOOT_DEVICE_MEMORY_MAPPED));
Aaron Durbin932e09d2016-07-13 23:09:52 -0500141 } else if (params->pei_data->boot_mode == ACPI_S3) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700142 /* Waking from S3 and no cache. */
143 printk(BIOS_DEBUG,
144 "No MRC cache found in S3 resume path.\n");
145 post_code(POST_RESUME_FAILURE);
146 hard_reset();
147 } else {
148 printk(BIOS_DEBUG, "No MRC cache found.\n");
149 mainboard_check_ec_image(params);
150 }
151 }
152
153 /* Initialize RAM */
154 raminit(params);
155 timestamp_add_now(TS_AFTER_INITRAM);
156
157 /* Save MRC output */
Lee Leahya6089692016-01-05 16:34:58 -0800158 if (IS_ENABLED(CONFIG_CACHE_MRC_SETTINGS)) {
159 printk(BIOS_DEBUG, "MRC data at %p %d bytes\n",
160 pei_data->data_to_save, pei_data->data_to_save_size);
Aaron Durbin932e09d2016-07-13 23:09:52 -0500161 if ((params->pei_data->boot_mode != ACPI_S3)
Lee Leahya6089692016-01-05 16:34:58 -0800162 && (params->pei_data->data_to_save_size != 0)
163 && (params->pei_data->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -0700164 mrc_cache_stash_data(MRC_TRAINING_DATA,
165 params->fsp_version,
166 params->pei_data->data_to_save,
167 params->pei_data->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -0700168 }
169
170 /* Save DIMM information */
171 mainboard_save_dimm_info(params);
172
173 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -0600174 if (romstage_handoff_init(
175 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Lee Leahy0946ec32015-04-20 15:24:54 -0700176 hard_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700177
Duncan Lauriefe4983e2016-03-14 09:29:09 -0700178 /*
179 * Initialize the TPM, unless the TPM was already initialized
180 * in verstage and used to verify romstage.
181 */
182 if (IS_ENABLED(CONFIG_LPC_TPM) &&
183 !IS_ENABLED(CONFIG_RESUME_PATH_SAME_AS_BOOT) &&
184 !IS_ENABLED(CONFIG_VBOOT_STARTS_IN_BOOTBLOCK))
185 init_tpm(params->power_state->prev_sleep_state ==
Aaron Durbin932e09d2016-07-13 23:09:52 -0500186 ACPI_S3);
Lee Leahy0946ec32015-04-20 15:24:54 -0700187}
188
Aaron Durbine6af4be2015-09-24 12:26:31 -0500189void after_cache_as_ram_stage(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700190{
Lee Leahy0946ec32015-04-20 15:24:54 -0700191 /* Load the ramstage. */
Kyösti Mälkki65e8f642016-06-27 11:27:56 +0300192 run_ramstage();
Lee Leahy0946ec32015-04-20 15:24:54 -0700193 die("ERROR - Failed to load ramstage!");
194}
195
196/* Initialize the power state */
197__attribute__((weak)) struct chipset_power_state *fill_power_state(void)
198{
Lee Leahy0946ec32015-04-20 15:24:54 -0700199 return NULL;
200}
201
202__attribute__((weak)) void mainboard_check_ec_image(
203 struct romstage_params *params)
204{
Lee Leahy0946ec32015-04-20 15:24:54 -0700205#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)
206 struct pei_data *pei_data;
207
208 pei_data = params->pei_data;
Aaron Durbin932e09d2016-07-13 23:09:52 -0500209 if (params->pei_data->boot_mode == ACPI_S0) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700210 /* Ensure EC is running RO firmware. */
211 google_chromeec_check_ec_image(EC_IMAGE_RO);
212 }
213#endif
214}
215
Lee Leahy0946ec32015-04-20 15:24:54 -0700216/* Board initialization before and after RAM is enabled */
217__attribute__((weak)) void mainboard_romstage_entry(
218 struct romstage_params *params)
219{
Lee Leahy0946ec32015-04-20 15:24:54 -0700220 post_code(0x31);
221
222 /* Initliaze memory */
223 romstage_common(params);
224}
225
226/* Save the DIMM information for SMBIOS table 17 */
Lee Leahy0946ec32015-04-20 15:24:54 -0700227__attribute__((weak)) void mainboard_save_dimm_info(
228 struct romstage_params *params)
229{
230 int channel;
231 CHANNEL_INFO *channel_info;
232 int dimm;
233 DIMM_INFO *dimm_info;
234 int dimm_max;
235 void *hob_list_ptr;
236 EFI_HOB_GUID_TYPE *hob_ptr;
237 int index;
238 struct memory_info *mem_info;
239 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
240 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
241
242 /* Locate the memory info HOB, presence validated by raminit */
243 hob_list_ptr = fsp_get_hob_list();
244 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
245 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
246
247 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
248 if (IS_ENABLED(CONFIG_DISPLAY_HOBS)) {
249 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
250 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
251 memory_info_hob->Revision);
252 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
253 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700254 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700255 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700256 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
257 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700258 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
259 memory_info_hob->ErrorCorrectionType);
260 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
261 memory_info_hob->ChannelCount);
262 for (channel = 0; channel < memory_info_hob->ChannelCount;
263 channel++) {
264 channel_info = &memory_info_hob->ChannelInfo[channel];
265 printk(BIOS_DEBUG, " Channel %d\n", channel);
266 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
267 channel_info->ChannelId);
268 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
269 channel_info->DimmCount);
270 for (dimm = 0; dimm < channel_info->DimmCount;
271 dimm++) {
272 dimm_info = &channel_info->DimmInfo[dimm];
273 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
274 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
275 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700276 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700277 dimm_info->SizeInMb);
278 }
279 }
280 }
281
282 /*
283 * Allocate CBMEM area for DIMM information used to populate SMBIOS
284 * table 17
285 */
286 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
287 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
288 if (mem_info == NULL)
289 return;
290 memset(mem_info, 0, sizeof(*mem_info));
291
292 /* Describe the first N DIMMs in the system */
293 index = 0;
294 dimm_max = ARRAY_SIZE(mem_info->dimm);
295 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
296 if (index >= dimm_max)
297 break;
298 channel_info = &memory_info_hob->ChannelInfo[channel];
299 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
300 if (index >= dimm_max)
301 break;
302 dimm_info = &channel_info->DimmInfo[dimm];
303
304 /* Populate the DIMM information */
305 if (dimm_info->SizeInMb) {
306 mem_info->dimm[index].dimm_size =
307 dimm_info->SizeInMb;
308 mem_info->dimm[index].ddr_type =
309 memory_info_hob->MemoryType;
310 mem_info->dimm[index].ddr_frequency =
311 memory_info_hob->MemoryFrequencyInMHz;
312 mem_info->dimm[index].channel_num =
313 channel_info->ChannelId;
314 mem_info->dimm[index].dimm_num =
315 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700316 switch (memory_info_hob->DataWidth) {
317 default:
318 case 8:
319 mem_info->dimm[index].bus_width =
320 MEMORY_BUS_WIDTH_8;
321 break;
322
323 case 16:
324 mem_info->dimm[index].bus_width =
325 MEMORY_BUS_WIDTH_16;
326 break;
327
328 case 32:
329 mem_info->dimm[index].bus_width =
330 MEMORY_BUS_WIDTH_32;
331 break;
332
333 case 64:
334 mem_info->dimm[index].bus_width =
335 MEMORY_BUS_WIDTH_64;
336 break;
337
338 case 128:
339 mem_info->dimm[index].bus_width =
340 MEMORY_BUS_WIDTH_128;
341 break;
342 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700343
344 /* Add any mainboard specific information */
345 mainboard_add_dimm_info(params, mem_info,
346 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700347 index++;
348 }
349 }
350 }
351 mem_info->dimm_cnt = index;
352 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
353}
Lee Leahy0946ec32015-04-20 15:24:54 -0700354
Duncan Laurie46a2c772015-07-20 16:48:55 -0700355/* Add any mainboard specific information */
356__attribute__((weak)) void mainboard_add_dimm_info(
357 struct romstage_params *params,
358 struct memory_info *mem_info,
359 int channel, int dimm, int index)
360{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700361}
362
Lee Leahy0946ec32015-04-20 15:24:54 -0700363/* Get the memory configuration data */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600364__attribute__((weak)) int mrc_cache_get_current(int type, uint32_t version,
365 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700366{
Lee Leahy0946ec32015-04-20 15:24:54 -0700367 return -1;
368}
369
370/* Save the memory configuration data */
Aaron Durbin31be2c92016-12-03 22:08:20 -0600371__attribute__((weak)) int mrc_cache_stash_data(int type, uint32_t version,
372 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700373{
Lee Leahy0946ec32015-04-20 15:24:54 -0700374 return -1;
375}
376
377/* Transition RAM from off or self-refresh to active */
378__attribute__((weak)) void raminit(struct romstage_params *params)
379{
Lee Leahy0946ec32015-04-20 15:24:54 -0700380 post_code(0x34);
381 die("ERROR - No RAM initialization specified!\n");
382}
383
Lee Leahy0946ec32015-04-20 15:24:54 -0700384/* Display the memory configuration */
385__attribute__((weak)) void report_memory_config(void)
386{
Lee Leahy0946ec32015-04-20 15:24:54 -0700387}
388
Lee Leahy0946ec32015-04-20 15:24:54 -0700389/* Choose top of stack and setup MTRRs */
390__attribute__((weak)) void *setup_stack_and_mtrrs(void)
391{
Lee Leahy0946ec32015-04-20 15:24:54 -0700392 die("ERROR - Must specify top of stack!\n");
393 return NULL;
394}
395
Lee Leahy0946ec32015-04-20 15:24:54 -0700396/* SOC initialization after RAM is enabled */
397__attribute__((weak)) void soc_after_ram_init(struct romstage_params *params)
398{
Lee Leahy0946ec32015-04-20 15:24:54 -0700399}
400
Lee Leahy0946ec32015-04-20 15:24:54 -0700401/* SOC initialization before RAM is enabled */
402__attribute__((weak)) void soc_pre_ram_init(struct romstage_params *params)
403{
Lee Leahy0946ec32015-04-20 15:24:54 -0700404}