blob: 95148f744b2789b90c37d6723206c9d87f62bfa0 [file] [log] [blame]
Lee Leahy0946ec32015-04-20 15:24:54 -07001/*
2 * This file is part of the coreboot project.
3 *
Lee Leahy0946ec32015-04-20 15:24:54 -07004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
Lee Leahy0946ec32015-04-20 15:24:54 -070012 */
13
14#include <stddef.h>
Aaron Durbin932e09d2016-07-13 23:09:52 -050015#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070016#include <arch/cbfs.h>
Aaron Durbin31be2c92016-12-03 22:08:20 -060017#include <assert.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070018#include <console/console.h>
19#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +020020#include <cf9_reset.h>
robbie zhang13a2e942016-02-10 11:40:11 -080021#include <cpu/intel/microcode.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070022#include <cpu/x86/mtrr.h>
23#include <ec/google/chromeec/ec.h>
24#include <ec/google/chromeec/ec_commands.h>
25#include <elog.h>
Lee Leahyb092c9e2016-01-01 18:09:50 -080026#include <fsp/romstage.h>
Aaron Durbindecd0622017-12-15 12:26:40 -070027#include <mrc_cache.h>
Kyösti Mälkki65e8f642016-06-27 11:27:56 +030028#include <program_loading.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070029#include <romstage_handoff.h>
Lee Leahy0be6d932015-06-26 11:15:42 -070030#include <smbios.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070031#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060032#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070033#include <timestamp.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070034#include <vendorcode/google/chromeos/chromeos.h>
35
Arthur Heymans73ac1212019-05-23 14:41:19 +020036static void raminit_common(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -070037{
Subrata Banik0beac812017-07-12 15:13:53 +053038 bool s3wake;
Aaron Durbin31be2c92016-12-03 22:08:20 -060039 struct region_device rdev;
Lee Leahy0946ec32015-04-20 15:24:54 -070040
41 post_code(0x32);
42
43 timestamp_add_now(TS_BEFORE_INITRAM);
44
Subrata Banik0beac812017-07-12 15:13:53 +053045 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -070046
Kyösti Mälkki7f50afb2019-09-11 17:12:26 +030047 elog_boot_notify(s3wake);
Lee Leahy0946ec32015-04-20 15:24:54 -070048
49 /* Perform remaining SOC initialization */
50 soc_pre_ram_init(params);
51 post_code(0x33);
52
53 /* Check recovery and MRC cache */
Nico Huber66318aa2019-05-04 16:59:20 +020054 params->saved_data_size = 0;
55 params->saved_data = NULL;
56 if (!params->disable_saved_data) {
Furquan Shaikh0325dc62016-07-25 13:02:36 -070057 if (vboot_recovery_mode_enabled()) {
Lee Leahy0946ec32015-04-20 15:24:54 -070058 /* Recovery mode does not use MRC cache */
59 printk(BIOS_DEBUG,
60 "Recovery mode: not using MRC cache.\n");
Julius Wernercd49cce2019-03-05 16:53:33 -080061 } else if (CONFIG(CACHE_MRC_SETTINGS)
Aaron Durbin31be2c92016-12-03 22:08:20 -060062 && (!mrc_cache_get_current(MRC_TRAINING_DATA,
63 params->fsp_version,
64 &rdev))) {
Lee Leahy0946ec32015-04-20 15:24:54 -070065 /* MRC cache found */
Nico Huber66318aa2019-05-04 16:59:20 +020066 params->saved_data_size = region_device_sz(&rdev);
67 params->saved_data = rdev_mmap_full(&rdev);
Elyes HAOUAS18958382018-08-07 12:23:16 +020068 /* Assume boot device is memory mapped. */
Julius Wernercd49cce2019-03-05 16:53:33 -080069 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
Nico Huber16895c52019-05-04 16:29:17 +020070 } else if (s3wake) {
Lee Leahy0946ec32015-04-20 15:24:54 -070071 /* Waking from S3 and no cache. */
72 printk(BIOS_DEBUG,
73 "No MRC cache found in S3 resume path.\n");
74 post_code(POST_RESUME_FAILURE);
Patrick Rudolphf677d172018-10-01 19:17:11 +020075 /* FIXME: A "system" reset is likely enough: */
76 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -070077 } else {
78 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070079 }
80 }
81
82 /* Initialize RAM */
83 raminit(params);
84 timestamp_add_now(TS_AFTER_INITRAM);
85
86 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -080087 if (CONFIG(CACHE_MRC_SETTINGS)) {
Nico Huber66318aa2019-05-04 16:59:20 +020088 printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n",
89 params->data_to_save, params->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +020090 if (!s3wake
Nico Huber66318aa2019-05-04 16:59:20 +020091 && (params->data_to_save_size != 0)
92 && (params->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -070093 mrc_cache_stash_data(MRC_TRAINING_DATA,
94 params->fsp_version,
Nico Huber66318aa2019-05-04 16:59:20 +020095 params->data_to_save,
96 params->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -070097 }
98
99 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +0530100 if (!s3wake)
101 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700102
103 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -0600104 if (romstage_handoff_init(
105 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +0200106 /* FIXME: A "system" reset is likely enough: */
107 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -0700108}
109
Arthur Heymans73ac1212019-05-23 14:41:19 +0200110void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
111{
112 struct romstage_params params = {
113 .chipset_context = fih,
114 };
115
116 post_code(0x30);
117
118 timestamp_add_now(TS_START_ROMSTAGE);
119
120 /* Load microcode before RAM init */
121 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS))
122 intel_update_microcode_from_cbfs();
123
124 /* Display parameters */
125 if (!CONFIG(NO_MMCONF_SUPPORT))
126 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
127 CONFIG_MMCONF_BASE_ADDRESS);
128 printk(BIOS_INFO, "Using FSP 1.1\n");
129
130 /* Display FSP banner */
131 print_fsp_info(fih);
132
133 /* Stash FSP version. */
134 params.fsp_version = fsp_version(fih);
135
136 /* Get power state */
137 params.power_state = fill_power_state();
138
139 /* Board initialization before and after RAM is enabled */
140 mainboard_pre_raminit(&params);
141
142 post_code(0x31);
143
144 /* Initialize memory */
145 raminit_common(&params);
146
147 soc_after_ram_init(&params);
148 post_code(0x38);
149}
150
Lee Leahy0946ec32015-04-20 15:24:54 -0700151/* Initialize the power state */
Aaron Durbin64031672018-04-21 14:45:32 -0600152__weak struct chipset_power_state *fill_power_state(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700153{
Lee Leahy0946ec32015-04-20 15:24:54 -0700154 return NULL;
155}
156
Lee Leahy0946ec32015-04-20 15:24:54 -0700157/* Board initialization before and after RAM is enabled */
Arthur Heymans73ac1212019-05-23 14:41:19 +0200158__weak void mainboard_pre_raminit(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700159{
Lee Leahy0946ec32015-04-20 15:24:54 -0700160}
161
162/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600163__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700164 struct romstage_params *params)
165{
166 int channel;
167 CHANNEL_INFO *channel_info;
168 int dimm;
169 DIMM_INFO *dimm_info;
170 int dimm_max;
171 void *hob_list_ptr;
172 EFI_HOB_GUID_TYPE *hob_ptr;
173 int index;
174 struct memory_info *mem_info;
175 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
176 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
177
178 /* Locate the memory info HOB, presence validated by raminit */
179 hob_list_ptr = fsp_get_hob_list();
180 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
181 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
182
183 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800184 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700185 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
186 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
187 memory_info_hob->Revision);
188 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
189 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700190 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700191 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700192 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
193 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700194 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
195 memory_info_hob->ErrorCorrectionType);
196 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
197 memory_info_hob->ChannelCount);
198 for (channel = 0; channel < memory_info_hob->ChannelCount;
199 channel++) {
200 channel_info = &memory_info_hob->ChannelInfo[channel];
201 printk(BIOS_DEBUG, " Channel %d\n", channel);
202 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
203 channel_info->ChannelId);
204 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
205 channel_info->DimmCount);
206 for (dimm = 0; dimm < channel_info->DimmCount;
207 dimm++) {
208 dimm_info = &channel_info->DimmInfo[dimm];
209 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
210 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
211 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700212 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700213 dimm_info->SizeInMb);
214 }
215 }
216 }
217
218 /*
219 * Allocate CBMEM area for DIMM information used to populate SMBIOS
220 * table 17
221 */
222 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
Julius Werner540a9802019-12-09 13:03:29 -0800223 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: %p\n", mem_info);
Lee Leahy0946ec32015-04-20 15:24:54 -0700224 if (mem_info == NULL)
225 return;
226 memset(mem_info, 0, sizeof(*mem_info));
227
228 /* Describe the first N DIMMs in the system */
229 index = 0;
230 dimm_max = ARRAY_SIZE(mem_info->dimm);
231 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
232 if (index >= dimm_max)
233 break;
234 channel_info = &memory_info_hob->ChannelInfo[channel];
235 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
236 if (index >= dimm_max)
237 break;
238 dimm_info = &channel_info->DimmInfo[dimm];
239
240 /* Populate the DIMM information */
241 if (dimm_info->SizeInMb) {
242 mem_info->dimm[index].dimm_size =
243 dimm_info->SizeInMb;
244 mem_info->dimm[index].ddr_type =
245 memory_info_hob->MemoryType;
246 mem_info->dimm[index].ddr_frequency =
247 memory_info_hob->MemoryFrequencyInMHz;
248 mem_info->dimm[index].channel_num =
249 channel_info->ChannelId;
250 mem_info->dimm[index].dimm_num =
251 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700252 switch (memory_info_hob->DataWidth) {
253 default:
254 case 8:
255 mem_info->dimm[index].bus_width =
256 MEMORY_BUS_WIDTH_8;
257 break;
258
259 case 16:
260 mem_info->dimm[index].bus_width =
261 MEMORY_BUS_WIDTH_16;
262 break;
263
264 case 32:
265 mem_info->dimm[index].bus_width =
266 MEMORY_BUS_WIDTH_32;
267 break;
268
269 case 64:
270 mem_info->dimm[index].bus_width =
271 MEMORY_BUS_WIDTH_64;
272 break;
273
274 case 128:
275 mem_info->dimm[index].bus_width =
276 MEMORY_BUS_WIDTH_128;
277 break;
278 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700279
280 /* Add any mainboard specific information */
281 mainboard_add_dimm_info(params, mem_info,
282 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700283 index++;
284 }
285 }
286 }
287 mem_info->dimm_cnt = index;
288 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
289}
Lee Leahy0946ec32015-04-20 15:24:54 -0700290
Duncan Laurie46a2c772015-07-20 16:48:55 -0700291/* Add any mainboard specific information */
Aaron Durbin64031672018-04-21 14:45:32 -0600292__weak void mainboard_add_dimm_info(
Duncan Laurie46a2c772015-07-20 16:48:55 -0700293 struct romstage_params *params,
294 struct memory_info *mem_info,
295 int channel, int dimm, int index)
296{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700297}
298
Lee Leahy0946ec32015-04-20 15:24:54 -0700299/* Get the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600300__weak int mrc_cache_get_current(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600301 struct region_device *rdev)
Lee Leahy0946ec32015-04-20 15:24:54 -0700302{
Lee Leahy0946ec32015-04-20 15:24:54 -0700303 return -1;
304}
305
306/* Save the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600307__weak int mrc_cache_stash_data(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600308 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700309{
Lee Leahy0946ec32015-04-20 15:24:54 -0700310 return -1;
311}
312
Lee Leahy0946ec32015-04-20 15:24:54 -0700313/* Display the memory configuration */
Aaron Durbin64031672018-04-21 14:45:32 -0600314__weak void report_memory_config(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700315{
Lee Leahy0946ec32015-04-20 15:24:54 -0700316}
317
Lee Leahy0946ec32015-04-20 15:24:54 -0700318/* SOC initialization after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600319__weak void soc_after_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700320{
Lee Leahy0946ec32015-04-20 15:24:54 -0700321}
322
Lee Leahy0946ec32015-04-20 15:24:54 -0700323/* SOC initialization before RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600324__weak void soc_pre_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700325{
Lee Leahy0946ec32015-04-20 15:24:54 -0700326}