blob: 5129dc696bd6dc601fbbe72a6819d37edb1d1cac [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#include <vendorcode/google/chromeos/chromeos.h>
22
Arthur Heymans73ac1212019-05-23 14:41:19 +020023static void raminit_common(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -070024{
Subrata Banik0beac812017-07-12 15:13:53 +053025 bool s3wake;
Shelley Chenad9cd682020-07-23 16:10:52 -070026 size_t mrc_size;
Lee Leahy0946ec32015-04-20 15:24:54 -070027
28 post_code(0x32);
29
30 timestamp_add_now(TS_BEFORE_INITRAM);
31
Subrata Banik0beac812017-07-12 15:13:53 +053032 s3wake = params->power_state->prev_sleep_state == ACPI_S3;
Lee Leahy0946ec32015-04-20 15:24:54 -070033
Kyösti Mälkki7f50afb2019-09-11 17:12:26 +030034 elog_boot_notify(s3wake);
Lee Leahy0946ec32015-04-20 15:24:54 -070035
36 /* Perform remaining SOC initialization */
37 soc_pre_ram_init(params);
38 post_code(0x33);
39
40 /* Check recovery and MRC cache */
Nico Huber66318aa2019-05-04 16:59:20 +020041 params->saved_data_size = 0;
42 params->saved_data = NULL;
43 if (!params->disable_saved_data) {
Shelley Chen6615c6e2020-10-27 15:58:31 -070044 /* Assume boot device is memory mapped. */
45 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED));
46
47 params->saved_data = NULL;
48 if (CONFIG(CACHE_MRC_SETTINGS))
49 params->saved_data =
50 mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
51 params->fsp_version,
52 &mrc_size);
53 if (params->saved_data) {
54 /* MRC cache found */
55 params->saved_data_size = mrc_size;
56
57 } else if (s3wake) {
58 /* Waking from S3 and no cache. */
Lee Leahy0946ec32015-04-20 15:24:54 -070059 printk(BIOS_DEBUG,
Shelley Chen6615c6e2020-10-27 15:58:31 -070060 "No MRC cache "
61 "found in S3 resume path.\n");
62 post_code(POST_RESUME_FAILURE);
63 /* FIXME: A "system" reset is likely enough: */
64 full_reset();
Shelley Chenad9cd682020-07-23 16:10:52 -070065 } else {
Shelley Chen6615c6e2020-10-27 15:58:31 -070066 printk(BIOS_DEBUG, "No MRC cache found.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070067 }
68 }
69
70 /* Initialize RAM */
71 raminit(params);
72 timestamp_add_now(TS_AFTER_INITRAM);
73
74 /* Save MRC output */
Julius Wernercd49cce2019-03-05 16:53:33 -080075 if (CONFIG(CACHE_MRC_SETTINGS)) {
Nico Huber66318aa2019-05-04 16:59:20 +020076 printk(BIOS_DEBUG, "MRC data at %p %zu bytes\n",
77 params->data_to_save, params->data_to_save_size);
Nico Huber16895c52019-05-04 16:29:17 +020078 if (!s3wake
Nico Huber66318aa2019-05-04 16:59:20 +020079 && (params->data_to_save_size != 0)
80 && (params->data_to_save != NULL))
Lee Leahy216712a2017-03-17 11:23:32 -070081 mrc_cache_stash_data(MRC_TRAINING_DATA,
82 params->fsp_version,
Nico Huber66318aa2019-05-04 16:59:20 +020083 params->data_to_save,
84 params->data_to_save_size);
Lee Leahy0946ec32015-04-20 15:24:54 -070085 }
86
87 /* Save DIMM information */
Subrata Banik0beac812017-07-12 15:13:53 +053088 if (!s3wake)
89 mainboard_save_dimm_info(params);
Lee Leahy0946ec32015-04-20 15:24:54 -070090
91 /* Create romstage handof information */
Aaron Durbin77e13992016-11-29 17:43:04 -060092 if (romstage_handoff_init(
93 params->power_state->prev_sleep_state == ACPI_S3) < 0)
Patrick Rudolphf677d172018-10-01 19:17:11 +020094 /* FIXME: A "system" reset is likely enough: */
95 full_reset();
Lee Leahy0946ec32015-04-20 15:24:54 -070096}
97
Arthur Heymans73ac1212019-05-23 14:41:19 +020098void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
99{
100 struct romstage_params params = {
101 .chipset_context = fih,
102 };
103
104 post_code(0x30);
105
106 timestamp_add_now(TS_START_ROMSTAGE);
107
108 /* Load microcode before RAM init */
109 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS))
110 intel_update_microcode_from_cbfs();
111
112 /* Display parameters */
113 if (!CONFIG(NO_MMCONF_SUPPORT))
114 printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
115 CONFIG_MMCONF_BASE_ADDRESS);
116 printk(BIOS_INFO, "Using FSP 1.1\n");
117
118 /* Display FSP banner */
119 print_fsp_info(fih);
120
121 /* Stash FSP version. */
122 params.fsp_version = fsp_version(fih);
123
124 /* Get power state */
125 params.power_state = fill_power_state();
126
127 /* Board initialization before and after RAM is enabled */
128 mainboard_pre_raminit(&params);
129
130 post_code(0x31);
131
132 /* Initialize memory */
133 raminit_common(&params);
134
135 soc_after_ram_init(&params);
136 post_code(0x38);
137}
138
Lee Leahy0946ec32015-04-20 15:24:54 -0700139/* Initialize the power state */
Aaron Durbin64031672018-04-21 14:45:32 -0600140__weak struct chipset_power_state *fill_power_state(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700141{
Lee Leahy0946ec32015-04-20 15:24:54 -0700142 return NULL;
143}
144
Lee Leahy0946ec32015-04-20 15:24:54 -0700145/* Board initialization before and after RAM is enabled */
Arthur Heymans73ac1212019-05-23 14:41:19 +0200146__weak void mainboard_pre_raminit(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700147{
Lee Leahy0946ec32015-04-20 15:24:54 -0700148}
149
150/* Save the DIMM information for SMBIOS table 17 */
Aaron Durbin64031672018-04-21 14:45:32 -0600151__weak void mainboard_save_dimm_info(
Lee Leahy0946ec32015-04-20 15:24:54 -0700152 struct romstage_params *params)
153{
154 int channel;
155 CHANNEL_INFO *channel_info;
156 int dimm;
157 DIMM_INFO *dimm_info;
158 int dimm_max;
159 void *hob_list_ptr;
160 EFI_HOB_GUID_TYPE *hob_ptr;
161 int index;
162 struct memory_info *mem_info;
163 FSP_SMBIOS_MEMORY_INFO *memory_info_hob;
164 const EFI_GUID memory_info_hob_guid = FSP_SMBIOS_MEMORY_INFO_GUID;
165
166 /* Locate the memory info HOB, presence validated by raminit */
167 hob_list_ptr = fsp_get_hob_list();
168 hob_ptr = get_next_guid_hob(&memory_info_hob_guid, hob_list_ptr);
169 memory_info_hob = (FSP_SMBIOS_MEMORY_INFO *)(hob_ptr + 1);
170
171 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
Julius Wernercd49cce2019-03-05 16:53:33 -0800172 if (CONFIG(DISPLAY_HOBS)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700173 printk(BIOS_DEBUG, "FSP_SMBIOS_MEMORY_INFO HOB\n");
174 printk(BIOS_DEBUG, " 0x%02x: Revision\n",
175 memory_info_hob->Revision);
176 printk(BIOS_DEBUG, " 0x%02x: MemoryType\n",
177 memory_info_hob->MemoryType);
Lee Leahy0be6d932015-06-26 11:15:42 -0700178 printk(BIOS_DEBUG, " %d: MemoryFrequencyInMHz\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700179 memory_info_hob->MemoryFrequencyInMHz);
Lee Leahy0be6d932015-06-26 11:15:42 -0700180 printk(BIOS_DEBUG, " %d: DataWidth in bits\n",
181 memory_info_hob->DataWidth);
Lee Leahy0946ec32015-04-20 15:24:54 -0700182 printk(BIOS_DEBUG, " 0x%02x: ErrorCorrectionType\n",
183 memory_info_hob->ErrorCorrectionType);
184 printk(BIOS_DEBUG, " 0x%02x: ChannelCount\n",
185 memory_info_hob->ChannelCount);
186 for (channel = 0; channel < memory_info_hob->ChannelCount;
187 channel++) {
188 channel_info = &memory_info_hob->ChannelInfo[channel];
189 printk(BIOS_DEBUG, " Channel %d\n", channel);
190 printk(BIOS_DEBUG, " 0x%02x: ChannelId\n",
191 channel_info->ChannelId);
192 printk(BIOS_DEBUG, " 0x%02x: DimmCount\n",
193 channel_info->DimmCount);
194 for (dimm = 0; dimm < channel_info->DimmCount;
195 dimm++) {
196 dimm_info = &channel_info->DimmInfo[dimm];
197 printk(BIOS_DEBUG, " DIMM %d\n", dimm);
198 printk(BIOS_DEBUG, " 0x%02x: DimmId\n",
199 dimm_info->DimmId);
Lee Leahy0be6d932015-06-26 11:15:42 -0700200 printk(BIOS_DEBUG, " %d: SizeInMb\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700201 dimm_info->SizeInMb);
202 }
203 }
204 }
205
206 /*
207 * Allocate CBMEM area for DIMM information used to populate SMBIOS
208 * table 17
209 */
210 mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(*mem_info));
Julius Werner540a9802019-12-09 13:03:29 -0800211 printk(BIOS_DEBUG, "CBMEM entry for DIMM info: %p\n", mem_info);
Lee Leahy0946ec32015-04-20 15:24:54 -0700212 if (mem_info == NULL)
213 return;
214 memset(mem_info, 0, sizeof(*mem_info));
215
216 /* Describe the first N DIMMs in the system */
217 index = 0;
218 dimm_max = ARRAY_SIZE(mem_info->dimm);
219 for (channel = 0; channel < memory_info_hob->ChannelCount; channel++) {
220 if (index >= dimm_max)
221 break;
222 channel_info = &memory_info_hob->ChannelInfo[channel];
223 for (dimm = 0; dimm < channel_info->DimmCount; dimm++) {
224 if (index >= dimm_max)
225 break;
226 dimm_info = &channel_info->DimmInfo[dimm];
227
228 /* Populate the DIMM information */
229 if (dimm_info->SizeInMb) {
230 mem_info->dimm[index].dimm_size =
231 dimm_info->SizeInMb;
232 mem_info->dimm[index].ddr_type =
233 memory_info_hob->MemoryType;
234 mem_info->dimm[index].ddr_frequency =
235 memory_info_hob->MemoryFrequencyInMHz;
236 mem_info->dimm[index].channel_num =
237 channel_info->ChannelId;
238 mem_info->dimm[index].dimm_num =
239 dimm_info->DimmId;
Lee Leahy0be6d932015-06-26 11:15:42 -0700240 switch (memory_info_hob->DataWidth) {
241 default:
242 case 8:
243 mem_info->dimm[index].bus_width =
244 MEMORY_BUS_WIDTH_8;
245 break;
246
247 case 16:
248 mem_info->dimm[index].bus_width =
249 MEMORY_BUS_WIDTH_16;
250 break;
251
252 case 32:
253 mem_info->dimm[index].bus_width =
254 MEMORY_BUS_WIDTH_32;
255 break;
256
257 case 64:
258 mem_info->dimm[index].bus_width =
259 MEMORY_BUS_WIDTH_64;
260 break;
261
262 case 128:
263 mem_info->dimm[index].bus_width =
264 MEMORY_BUS_WIDTH_128;
265 break;
266 }
Duncan Laurie46a2c772015-07-20 16:48:55 -0700267
268 /* Add any mainboard specific information */
269 mainboard_add_dimm_info(params, mem_info,
270 channel, dimm, index);
Lee Leahy0946ec32015-04-20 15:24:54 -0700271 index++;
272 }
273 }
274 }
275 mem_info->dimm_cnt = index;
276 printk(BIOS_DEBUG, "%d DIMMs found\n", mem_info->dimm_cnt);
277}
Lee Leahy0946ec32015-04-20 15:24:54 -0700278
Duncan Laurie46a2c772015-07-20 16:48:55 -0700279/* Add any mainboard specific information */
Aaron Durbin64031672018-04-21 14:45:32 -0600280__weak void mainboard_add_dimm_info(
Duncan Laurie46a2c772015-07-20 16:48:55 -0700281 struct romstage_params *params,
282 struct memory_info *mem_info,
283 int channel, int dimm, int index)
284{
Duncan Laurie46a2c772015-07-20 16:48:55 -0700285}
286
Lee Leahy0946ec32015-04-20 15:24:54 -0700287/* Save the memory configuration data */
Aaron Durbin64031672018-04-21 14:45:32 -0600288__weak int mrc_cache_stash_data(int type, uint32_t version,
Aaron Durbin31be2c92016-12-03 22:08:20 -0600289 const void *data, size_t size)
Lee Leahy0946ec32015-04-20 15:24:54 -0700290{
Lee Leahy0946ec32015-04-20 15:24:54 -0700291 return -1;
292}
293
Lee Leahy0946ec32015-04-20 15:24:54 -0700294/* Display the memory configuration */
Aaron Durbin64031672018-04-21 14:45:32 -0600295__weak void report_memory_config(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700296{
Lee Leahy0946ec32015-04-20 15:24:54 -0700297}
298
Lee Leahy0946ec32015-04-20 15:24:54 -0700299/* SOC initialization after RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600300__weak void soc_after_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700301{
Lee Leahy0946ec32015-04-20 15:24:54 -0700302}
303
Lee Leahy0946ec32015-04-20 15:24:54 -0700304/* SOC initialization before RAM is enabled */
Aaron Durbin64031672018-04-21 14:45:32 -0600305__weak void soc_pre_ram_init(struct romstage_params *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700306{
Lee Leahy0946ec32015-04-20 15:24:54 -0700307}