blob: 45ca87aac8d1e3f779573246acf535e8b4a2b09f [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>
Aaron Durbin31be2c92016-12-03 22:08:20 -060021#include <assert.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070022#include <console/console.h>
23#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +020024#include <cf9_reset.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>
Kyösti Mälkki65e8f642016-06-27 11:27:56 +030032#include <program_loading.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070033#include <romstage_handoff.h>
Lee Leahy0be6d932015-06-26 11:15:42 -070034#include <smbios.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070035#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060036#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070037#include <timestamp.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070038#include <vendorcode/google/chromeos/chromeos.h>
39
Arthur Heymansbe291e82019-01-06 07:35:11 +010040asmlinkage void romstage_main(FSP_INFO_HEADER *fih)
Lee Leahy0946ec32015-04-20 15:24:54 -070041{
Lee Leahy0946ec32015-04-20 15:24:54 -070042 struct romstage_params params = {
Aaron Durbine6af4be2015-09-24 12:26:31 -050043 .chipset_context = fih,
Lee Leahy0946ec32015-04-20 15:24:54 -070044 };
45
46 post_code(0x30);
47
Lee Leahy0946ec32015-04-20 15:24:54 -070048 timestamp_add_now(TS_START_ROMSTAGE);
49
Elyes HAOUAS77537312016-07-30 15:37:26 +020050 /* Load microcode before RAM init */
Julius Wernercd49cce2019-03-05 16:53:33 -080051 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS))
robbie zhang13a2e942016-02-10 11:40:11 -080052 intel_update_microcode_from_cbfs();
53
Lee Leahy0946ec32015-04-20 15:24:54 -070054 /* Display parameters */
Julius Wernercd49cce2019-03-05 16:53:33 -080055 if (!CONFIG(NO_MMCONF_SUPPORT))
Lee Leahyc253a922017-03-13 17:36:39 -070056 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
57 CONFIG_MMCONF_BASE_ADDRESS);
Aaron Durbin929b6022015-12-09 16:00:18 -060058 printk(BIOS_INFO, "Using FSP 1.1\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070059
60 /* Display FSP banner */
Aaron Durbine6af4be2015-09-24 12:26:31 -050061 print_fsp_info(fih);
Lee Leahy0946ec32015-04-20 15:24:54 -070062
Aaron Durbin929b6022015-12-09 16:00:18 -060063 /* Stash FSP version. */
64 params.fsp_version = fsp_version(fih);
65
Lee Leahy0946ec32015-04-20 15:24:54 -070066 /* Get power state */
67 params.power_state = fill_power_state();
68
Lee Leahy0946ec32015-04-20 15:24:54 -070069 /* Call into mainboard. */
70 mainboard_romstage_entry(&params);
71 soc_after_ram_init(&params);
72 post_code(0x38);
Lee Leahy0946ec32015-04-20 15:24:54 -070073}
74
Arthur Heymansbe291e82019-01-06 07:35:11 +010075void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
Aaron Durbine6af4be2015-09-24 12:26:31 -050076{
Arthur Heymansbe291e82019-01-06 07:35:11 +010077 romstage_main(fih);
Aaron Durbine6af4be2015-09-24 12:26:31 -050078}
79
Lee Leahy0946ec32015-04-20 15:24:54 -070080/* Entry from the mainboard. */
81void romstage_common(struct romstage_params *params)
82{
Subrata Banik0beac812017-07-12 15:13:53 +053083 bool s3wake;
Aaron Durbin31be2c92016-12-03 22:08:20 -060084 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -070085
86 post_code(0x32);
87
88 timestamp_add_now(TS_BEFORE_INITRAM);
89
Subrata Banik0beac812017-07-12 15:13:53 +053090 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -070091
Julius Wernercd49cce2019-03-05 16:53:33 -080092 if (CONFIG(ELOG_BOOT_COUNT) && !s3wake)
Lee Leahy0946ec32015-04-20 15:24:54 -070093 boot_count_increment();
Lee Leahy0946ec32015-04-20 15:24:54 -070094
95 /* Perform remaining SOC initialization */
96 soc_pre_ram_init(params);
97 post_code(0x33);
98
99 /* Check recovery and MRC cache */
Nico Huber66318aa2019-05-04 16:59:20 +0200100 params->saved_data_size = 0;
101 params->saved_data = NULL;
102 if (!params->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -0700103 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700104 /* Recovery mode does not use MRC cache */
105 printk(BIOS_DEBUG,
106 "Recovery mode: not using MRC cache.\n");
Julius Wernercd49cce2019-03-05 16:53:33 -0800107 } else if (CONFIG(CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -0600108 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
109 params->fsp_version,
110 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700111 /* MRC cache found */
Nico Huber66318aa2019-05-04 16:59:20 +0200112 params->saved_data_size = region_device_sz(&rdev);
113 params->saved_data = rdev_mmap_full(&rdev);
Elyes HAOUAS18958382018-08-07 12:23:16 +0200114 /* Assume boot device is memory mapped. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800115 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
Nico Huber16895c52019-05-04 16:29:17 +0200116 } else if (s3wake) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700117 /* Waking from S3 and no cache. */
118 printk(BIOS_DEBUG,
119 "No MRC cache found in S3 resume path.\n");
120 post_code(POST_RESUME_FAILURE);
Patrick Rudolphf677d172018-10-01 19:17:11 +0200121 /* FIXME: A "system" reset is likely enough: */
122 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700123 } else {
124 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700125 }
126 }
127
128 /* Initialize RAM */
129 raminit(params);
130 timestamp_add_now(TS_AFTER_INITRAM);
131
132 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -0800133 if (CONFIG(CACHE_MRC_SETTINGS)) {
Nico Huber66318aa2019-05-04 16:59:20 +0200134 printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n",
135 params->data_to_save, params->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +0200136 if (!s3wake
Nico Huber66318aa2019-05-04 16:59:20 +0200137 && (params->data_to_save_size != 0)
138 && (params->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -0700139 mrc_cache_stash_data(MRC_TRAINING_DATA,
140 params->fsp_version,
Nico Huber66318aa2019-05-04 16:59:20 +0200141 params->data_to_save,
142 params->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -0700143 }
144
145 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +0530146 if (!s3wake)
147 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700148
149 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -0600150 if (romstage_handoff_init(
151 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +0200152 /* FIXME: A "system" reset is likely enough: */
153 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700154}
155
Lee Leahy0946ec32015-04-20 15:24:54 -0700156/* Initialize the power state */
Aaron Durbin64031672018-04-21 14:45:32 -0600157__weak struct chipset_power_state *fill_power_state(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700158{
Lee Leahy0946ec32015-04-20 15:24:54 -0700159 return NULL;
160}
161
Lee Leahy0946ec32015-04-20 15:24:54 -0700162/* Board initialization before and after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600163__weak void mainboard_romstage_entry(
Lee Leahy0946ec32015-04-20 15:24:54 -0700164 struct romstage_params *params)
165{
Lee Leahy0946ec32015-04-20 15:24:54 -0700166 post_code(0x31);
167
Frans Hendriks44d2c852018-12-03 10:40:06 +0100168 /* Initialize memory */
Lee Leahy0946ec32015-04-20 15:24:54 -0700169 romstage_common(params);
170}
171
172/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600173__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700174 struct romstage_params *params)
175{
176 int channel;
177 CHANNEL_INFO *channel_info;
178 int dimm;
179 DIMM_INFO *dimm_info;
180 int dimm_max;
181 void *hob_list_ptr;
182 EFI_HOB_GUID_TYPE *hob_ptr;
183 int index;
184 struct memory_info *mem_info;
185 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
186 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
187
188 /* Locate the memory info HOB, presence validated by raminit */
189 hob_list_ptr = fsp_get_hob_list();
190 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
191 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
192
193 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800194 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700195 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
196 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
197 memory_info_hob->Revision);
198 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
199 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700200 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700201 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700202 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
203 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700204 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
205 memory_info_hob->ErrorCorrectionType);
206 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
207 memory_info_hob->ChannelCount);
208 for (channel = 0; channel < memory_info_hob->ChannelCount;
209 channel++) {
210 channel_info = &memory_info_hob->ChannelInfo[channel];
211 printk(BIOS_DEBUG, " Channel %d\n", channel);
212 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
213 channel_info->ChannelId);
214 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
215 channel_info->DimmCount);
216 for (dimm = 0; dimm < channel_info->DimmCount;
217 dimm++) {
218 dimm_info = &channel_info->DimmInfo[dimm];
219 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
220 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
221 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700222 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700223 dimm_info->SizeInMb);
224 }
225 }
226 }
227
228 /*
229 * Allocate CBMEM area for DIMM information used to populate SMBIOS
230 * table 17
231 */
232 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
233 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: 0x%p\n", mem_info);
234 if (mem_info == NULL)
235 return;
236 memset(mem_info, 0, sizeof(*mem_info));
237
238 /* Describe the first N DIMMs in the system */
239 index = 0;
240 dimm_max = ARRAY_SIZE(mem_info->dimm);
241 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
242 if (index >= dimm_max)
243 break;
244 channel_info = &memory_info_hob->ChannelInfo[channel];
245 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
246 if (index >= dimm_max)
247 break;
248 dimm_info = &channel_info->DimmInfo[dimm];
249
250 /* Populate the DIMM information */
251 if (dimm_info->SizeInMb) {
252 mem_info->dimm[index].dimm_size =
253 dimm_info->SizeInMb;
254 mem_info->dimm[index].ddr_type =
255 memory_info_hob->MemoryType;
256 mem_info->dimm[index].ddr_frequency =
257 memory_info_hob->MemoryFrequencyInMHz;
258 mem_info->dimm[index].channel_num =
259 channel_info->ChannelId;
260 mem_info->dimm[index].dimm_num =
261 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700262 switch (memory_info_hob->DataWidth) {
263 default:
264 case 8:
265 mem_info->dimm[index].bus_width =
266 MEMORY_BUS_WIDTH_8;
267 break;
268
269 case 16:
270 mem_info->dimm[index].bus_width =
271 MEMORY_BUS_WIDTH_16;
272 break;
273
274 case 32:
275 mem_info->dimm[index].bus_width =
276 MEMORY_BUS_WIDTH_32;
277 break;
278
279 case 64:
280 mem_info->dimm[index].bus_width =
281 MEMORY_BUS_WIDTH_64;
282 break;
283
284 case 128:
285 mem_info->dimm[index].bus_width =
286 MEMORY_BUS_WIDTH_128;
287 break;
288 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700289
290 /* Add any mainboard specific information */
291 mainboard_add_dimm_info(params, mem_info,
292 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700293 index++;
294 }
295 }
296 }
297 mem_info->dimm_cnt = index;
298 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
299}
Lee Leahy0946ec32015-04-20 15:24:54 -0700300
Duncan Laurie46a2c772015-07-20 16:48:55 -0700301/* Add any mainboard specific information */
Aaron Durbin64031672018-04-21 14:45:32 -0600302__weak void mainboard_add_dimm_info(
Duncan Laurie46a2c772015-07-20 16:48:55 -0700303 struct romstage_params *params,
304 struct memory_info *mem_info,
305 int channel, int dimm, int index)
306{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700307}
308
Lee Leahy0946ec32015-04-20 15:24:54 -0700309/* Get the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600310__weak int mrc_cache_get_current(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600311 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700312{
Lee Leahy0946ec32015-04-20 15:24:54 -0700313 return -1;
314}
315
316/* Save the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600317__weak int mrc_cache_stash_data(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600318 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700319{
Lee Leahy0946ec32015-04-20 15:24:54 -0700320 return -1;
321}
322
Lee Leahy0946ec32015-04-20 15:24:54 -0700323/* Display the memory configuration */
Aaron Durbin64031672018-04-21 14:45:32 -0600324__weak void report_memory_config(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700325{
Lee Leahy0946ec32015-04-20 15:24:54 -0700326}
327
Lee Leahy0946ec32015-04-20 15:24:54 -0700328/* SOC initialization after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600329__weak void soc_after_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700330{
Lee Leahy0946ec32015-04-20 15:24:54 -0700331}
332
Lee Leahy0946ec32015-04-20 15:24:54 -0700333/* SOC initialization before RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600334__weak void soc_pre_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700335{
Lee Leahy0946ec32015-04-20 15:24:54 -0700336}