blob: dc890642a2576ed8696870efc6314932ffd9b87a [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy0946ec32015-04-20 15:24:54 -07002
3#include <stddef.h>
Furquan Shaikh76cedd22020-05-02 10:24:23 -07004#include <acpi/acpi.h>
Aaron Durbin31be2c92016-12-03 22:08:20 -06005#include <assert.h>
Lee Leahy0946ec32015-04-20 15:24:54 -07006#include <console/console.h>
7#include <cbmem.h>
Patrick Rudolphf677d172018-10-01 19:17:11 +02008#include <cf9_reset.h>
robbie zhang13a2e942016-02-10 11:40:11 -08009#include <cpu/intel/microcode.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070010#include <ec/google/chromeec/ec.h>
11#include <ec/google/chromeec/ec_commands.h>
12#include <elog.h>
Lee Leahyb092c9e2016-01-01 18:09:50 -080013#include <fsp/romstage.h>
Aaron Durbindecd0622017-12-15 12:26:40 -070014#include <mrc_cache.h>
Kyösti Mälkki65e8f642016-06-27 11:27:56 +030015#include <program_loading.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070016#include <romstage_handoff.h>
Lee Leahy0be6d932015-06-26 11:15:42 -070017#include <smbios.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070018#include <stage_cache.h>
Aaron Durbinafe8aee2016-11-29 21:37:42 -060019#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070020#include <timestamp.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070021
Arthur Heymans73ac1212019-05-23 14:41:19 +020022static void raminit_common(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -070023{
Subrata Banik0beac812017-07-12 15:13:53 +053024 bool s3wake;
Shelley Chenad9cd682020-07-23 16:10:52 -070025 size_t mrc_size;
Lee Leahy0946ec32015-04-20 15:24:54 -070026
27 post_code(0x32);
28
Jakub Czapigaad6157e2022-02-15 11:50:31 +010029 timestamp_add_now(TS_INITRAM_START);
Lee Leahy0946ec32015-04-20 15:24:54 -070030
Subrata Banik0beac812017-07-12 15:13:53 +053031 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -070032
Kyösti Mälkki7f50afb2019-09-11 17:12:26 +030033 elog_boot_notify(s3wake);
Lee Leahy0946ec32015-04-20 15:24:54 -070034
Lee Leahy0946ec32015-04-20 15:24:54 -070035 post_code(0x33);
36
37 /* Check recovery and MRC cache */
Nico Huber66318aa2019-05-04 16:59:20 +020038 params->saved_data_size = 0;
39 params->saved_data = NULL;
40 if (!params->disable_saved_data) {
Shelley Chen6615c6e2020-10-27 15:58:31 -070041 /* Assume boot device is memory mapped. */
42 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
43
44 params->saved_data = NULL;
45 if (CONFIG(CACHE_MRC_SETTINGS))
46 params->saved_data =
47 mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
48 params->fsp_version,
49 &mrc_size);
50 if (params->saved_data) {
51 /* MRC cache found */
52 params->saved_data_size = mrc_size;
53
54 } else if (s3wake) {
55 /* Waking from S3 and no cache. */
Lee Leahy0946ec32015-04-20 15:24:54 -070056 printk(BIOS_DEBUG,
Shelley Chen6615c6e2020-10-27 15:58:31 -070057 "No MRC cache "
58 "found in S3 resume path.\n");
lilacious40cb3fe2023-06-21 23:24:14 +020059 post_code(POSTCODE_RESUME_FAILURE);
Shelley Chen6615c6e2020-10-27 15:58:31 -070060 /* FIXME: A "system" reset is likely enough: */
61 full_reset();
Shelley Chenad9cd682020-07-23 16:10:52 -070062 } else {
Shelley Chen6615c6e2020-10-27 15:58:31 -070063 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070064 }
65 }
66
67 /* Initialize RAM */
68 raminit(params);
Jakub Czapigaad6157e2022-02-15 11:50:31 +010069 timestamp_add_now(TS_INITRAM_END);
Lee Leahy0946ec32015-04-20 15:24:54 -070070
71 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -080072 if (CONFIG(CACHE_MRC_SETTINGS)) {
Nico Huber66318aa2019-05-04 16:59:20 +020073 printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n",
74 params->data_to_save, params->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +020075 if (!s3wake
Nico Huber66318aa2019-05-04 16:59:20 +020076 && (params->data_to_save_size != 0)
77 && (params->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -070078 mrc_cache_stash_data(MRC_TRAINING_DATA,
79 params->fsp_version,
Nico Huber66318aa2019-05-04 16:59:20 +020080 params->data_to_save,
81 params->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -070082 }
83
84 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +053085 if (!s3wake)
86 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -070087
88 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -060089 if (romstage_handoff_init(
90 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +020091 /* FIXME: A "system" reset is likely enough: */
92 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -070093}
94
Arthur Heymans73ac1212019-05-23 14:41:19 +020095void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
96{
97 struct romstage_params params = {
98 .chipset_context = fih,
99 };
100
101 post_code(0x30);
102
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100103 timestamp_add_now(TS_ROMSTAGE_START);
Arthur Heymans73ac1212019-05-23 14:41:19 +0200104
Arthur Heymans73ac1212019-05-23 14:41:19 +0200105 /* Display parameters */
Shelley Chen4e9bb332021-10-20 15:43:45 -0700106 if (!CONFIG(NO_ECAM_MMCONF_SUPPORT))
107 printk(BIOS_SPEW, "CONFIG_ECAM_MMCONF_BASE_ADDRESS: 0x%08x\n",
108 CONFIG_ECAM_MMCONF_BASE_ADDRESS);
Arthur Heymans73ac1212019-05-23 14:41:19 +0200109 printk(BIOS_INFO, "Using FSP 1.1\n");
110
111 /* Display FSP banner */
112 print_fsp_info(fih);
113
114 /* Stash FSP version. */
115 params.fsp_version = fsp_version(fih);
116
117 /* Get power state */
118 params.power_state = fill_power_state();
119
120 /* Board initialization before and after RAM is enabled */
121 mainboard_pre_raminit(&params);
122
123 post_code(0x31);
124
125 /* Initialize memory */
126 raminit_common(&params);
127
128 soc_after_ram_init(&params);
129 post_code(0x38);
130}
131
Lee Leahy0946ec32015-04-20 15:24:54 -0700132/* Board initialization before and after RAM is enabled */
Arthur Heymans73ac1212019-05-23 14:41:19 +0200133__weak void mainboard_pre_raminit(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700134{
Lee Leahy0946ec32015-04-20 15:24:54 -0700135}
136
137/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600138__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700139 struct romstage_params *params)
140{
141 int channel;
142 CHANNEL_INFO *channel_info;
143 int dimm;
144 DIMM_INFO *dimm_info;
145 int dimm_max;
146 void *hob_list_ptr;
147 EFI_HOB_GUID_TYPE *hob_ptr;
148 int index;
149 struct memory_info *mem_info;
150 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
151 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
152
153 /* Locate the memory info HOB, presence validated by raminit */
154 hob_list_ptr = fsp_get_hob_list();
Arthur Heymansca74d7e2022-03-30 14:41:16 +0200155 hob_ptr = get_guid_hob(&memory_info_hob_guid, hob_list_ptr);
Lee Leahy0946ec32015-04-20 15:24:54 -0700156 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
157
158 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800159 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700160 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
161 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
162 memory_info_hob->Revision);
163 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
164 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700165 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700166 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700167 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
168 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700169 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
170 memory_info_hob->ErrorCorrectionType);
171 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
172 memory_info_hob->ChannelCount);
173 for (channel = 0; channel < memory_info_hob->ChannelCount;
174 channel++) {
175 channel_info = &memory_info_hob->ChannelInfo[channel];
176 printk(BIOS_DEBUG, " Channel %d\n", channel);
177 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
178 channel_info->ChannelId);
179 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
180 channel_info->DimmCount);
181 for (dimm = 0; dimm < channel_info->DimmCount;
182 dimm++) {
183 dimm_info = &channel_info->DimmInfo[dimm];
184 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
185 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
186 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700187 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700188 dimm_info->SizeInMb);
189 }
190 }
191 }
192
193 /*
194 * Allocate CBMEM area for DIMM information used to populate SMBIOS
195 * table 17
196 */
197 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
Julius Werner540a9802019-12-09 13:03:29 -0800198 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: %p\n", mem_info);
Lee Leahy0946ec32015-04-20 15:24:54 -0700199 if (mem_info == NULL)
200 return;
201 memset(mem_info, 0, sizeof(*mem_info));
202
203 /* Describe the first N DIMMs in the system */
204 index = 0;
205 dimm_max = ARRAY_SIZE(mem_info->dimm);
206 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
207 if (index >= dimm_max)
208 break;
209 channel_info = &memory_info_hob->ChannelInfo[channel];
210 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
211 if (index >= dimm_max)
212 break;
213 dimm_info = &channel_info->DimmInfo[dimm];
214
215 /* Populate the DIMM information */
216 if (dimm_info->SizeInMb) {
217 mem_info->dimm[index].dimm_size =
218 dimm_info->SizeInMb;
219 mem_info->dimm[index].ddr_type =
220 memory_info_hob->MemoryType;
221 mem_info->dimm[index].ddr_frequency =
222 memory_info_hob->MemoryFrequencyInMHz;
223 mem_info->dimm[index].channel_num =
224 channel_info->ChannelId;
225 mem_info->dimm[index].dimm_num =
226 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700227 switch (memory_info_hob->DataWidth) {
228 default:
229 case 8:
230 mem_info->dimm[index].bus_width =
231 MEMORY_BUS_WIDTH_8;
232 break;
233
234 case 16:
235 mem_info->dimm[index].bus_width =
236 MEMORY_BUS_WIDTH_16;
237 break;
238
239 case 32:
240 mem_info->dimm[index].bus_width =
241 MEMORY_BUS_WIDTH_32;
242 break;
243
244 case 64:
245 mem_info->dimm[index].bus_width =
246 MEMORY_BUS_WIDTH_64;
247 break;
248
249 case 128:
250 mem_info->dimm[index].bus_width =
251 MEMORY_BUS_WIDTH_128;
252 break;
253 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700254 index++;
255 }
256 }
257 }
258 mem_info->dimm_cnt = index;
259 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
260}