1 /* SPDX-License-Identifier: GPL-2.0-only */
6 #include <console/console.h>
9 #include <cpu/intel/microcode.h>
10 #include <ec/google/chromeec/ec.h>
11 #include <ec/google/chromeec/ec_commands.h>
13 #include <fsp/romstage.h>
14 #include <mrc_cache.h>
15 #include <program_loading.h>
16 #include <romstage_handoff.h>
18 #include <stage_cache.h>
20 #include <timestamp.h>
21 #include <vendorcode/google/chromeos/chromeos.h>
23 static void raminit_common(struct romstage_params
*params
)
30 timestamp_add_now(TS_BEFORE_INITRAM
);
32 s3wake
= params
->power_state
->prev_sleep_state
== ACPI_S3
;
34 elog_boot_notify(s3wake
);
38 /* Check recovery and MRC cache */
39 params
->saved_data_size
= 0;
40 params
->saved_data
= NULL
;
41 if (!params
->disable_saved_data
) {
42 /* Assume boot device is memory mapped. */
43 assert(CONFIG(BOOT_DEVICE_MEMORY_MAPPED
));
45 params
->saved_data
= NULL
;
46 if (CONFIG(CACHE_MRC_SETTINGS
))
48 mrc_cache_current_mmap_leak(MRC_TRAINING_DATA
,
51 if (params
->saved_data
) {
53 params
->saved_data_size
= mrc_size
;
56 /* Waking from S3 and no cache. */
59 "found in S3 resume path.\n");
60 post_code(POST_RESUME_FAILURE
);
61 /* FIXME: A "system" reset is likely enough: */
64 printk(BIOS_DEBUG
, "No MRC cache found.\n");
70 timestamp_add_now(TS_AFTER_INITRAM
);
73 if (CONFIG(CACHE_MRC_SETTINGS
)) {
74 printk(BIOS_DEBUG
, "MRC data at %p %zu bytes\n",
75 params
->data_to_save
, params
->data_to_save_size
);
77 && (params
->data_to_save_size
!= 0)
78 && (params
->data_to_save
!= NULL
))
79 mrc_cache_stash_data(MRC_TRAINING_DATA
,
82 params
->data_to_save_size
);
85 /* Save DIMM information */
87 mainboard_save_dimm_info(params
);
89 /* Create romstage handof information */
90 if (romstage_handoff_init(
91 params
->power_state
->prev_sleep_state
== ACPI_S3
) < 0)
92 /* FIXME: A "system" reset is likely enough: */
96 void cache_as_ram_stage_main(FSP_INFO_HEADER
*fih
)
98 struct romstage_params params
= {
99 .chipset_context
= fih
,
104 timestamp_add_now(TS_START_ROMSTAGE
);
106 /* Load microcode before RAM init */
107 if (CONFIG(SUPPORT_CPU_UCODE_IN_CBFS
))
108 intel_update_microcode_from_cbfs();
110 /* Display parameters */
111 if (!CONFIG(NO_MMCONF_SUPPORT
))
112 printk(BIOS_SPEW
, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
113 CONFIG_MMCONF_BASE_ADDRESS
);
114 printk(BIOS_INFO
, "Using FSP 1.1\n");
116 /* Display FSP banner */
119 /* Stash FSP version. */
120 params
.fsp_version
= fsp_version(fih
);
122 /* Get power state */
123 params
.power_state
= fill_power_state();
125 /* Board initialization before and after RAM is enabled */
126 mainboard_pre_raminit(¶ms
);
130 /* Initialize memory */
131 raminit_common(¶ms
);
133 soc_after_ram_init(¶ms
);
137 /* Board initialization before and after RAM is enabled */
138 __weak
void mainboard_pre_raminit(struct romstage_params
*params
)
142 /* Save the DIMM information for SMBIOS table 17 */
143 __weak
void mainboard_save_dimm_info(
144 struct romstage_params
*params
)
147 CHANNEL_INFO
*channel_info
;
149 DIMM_INFO
*dimm_info
;
152 EFI_HOB_GUID_TYPE
*hob_ptr
;
154 struct memory_info
*mem_info
;
155 FSP_SMBIOS_MEMORY_INFO
*memory_info_hob
;
156 const EFI_GUID memory_info_hob_guid
= FSP_SMBIOS_MEMORY_INFO_GUID
;
158 /* Locate the memory info HOB, presence validated by raminit */
159 hob_list_ptr
= fsp_get_hob_list();
160 hob_ptr
= get_next_guid_hob(&memory_info_hob_guid
, hob_list_ptr
);
161 memory_info_hob
= (FSP_SMBIOS_MEMORY_INFO
*)(hob_ptr
+ 1);
163 /* Display the data in the FSP_SMBIOS_MEMORY_INFO HOB */
164 if (CONFIG(DISPLAY_HOBS
)) {
165 printk(BIOS_DEBUG
, "FSP_SMBIOS_MEMORY_INFO HOB\n");
166 printk(BIOS_DEBUG
, " 0x%02x: Revision\n",
167 memory_info_hob
->Revision
);
168 printk(BIOS_DEBUG
, " 0x%02x: MemoryType\n",
169 memory_info_hob
->MemoryType
);
170 printk(BIOS_DEBUG
, " %d: MemoryFrequencyInMHz\n",
171 memory_info_hob
->MemoryFrequencyInMHz
);
172 printk(BIOS_DEBUG
, " %d: DataWidth in bits\n",
173 memory_info_hob
->DataWidth
);
174 printk(BIOS_DEBUG
, " 0x%02x: ErrorCorrectionType\n",
175 memory_info_hob
->ErrorCorrectionType
);
176 printk(BIOS_DEBUG
, " 0x%02x: ChannelCount\n",
177 memory_info_hob
->ChannelCount
);
178 for (channel
= 0; channel
< memory_info_hob
->ChannelCount
;
180 channel_info
= &memory_info_hob
->ChannelInfo
[channel
];
181 printk(BIOS_DEBUG
, " Channel %d\n", channel
);
182 printk(BIOS_DEBUG
, " 0x%02x: ChannelId\n",
183 channel_info
->ChannelId
);
184 printk(BIOS_DEBUG
, " 0x%02x: DimmCount\n",
185 channel_info
->DimmCount
);
186 for (dimm
= 0; dimm
< channel_info
->DimmCount
;
188 dimm_info
= &channel_info
->DimmInfo
[dimm
];
189 printk(BIOS_DEBUG
, " DIMM %d\n", dimm
);
190 printk(BIOS_DEBUG
, " 0x%02x: DimmId\n",
192 printk(BIOS_DEBUG
, " %d: SizeInMb\n",
193 dimm_info
->SizeInMb
);
199 * Allocate CBMEM area for DIMM information used to populate SMBIOS
202 mem_info
= cbmem_add(CBMEM_ID_MEMINFO
, sizeof(*mem_info
));
203 printk(BIOS_DEBUG
, "CBMEM entry for DIMM info: %p\n", mem_info
);
204 if (mem_info
== NULL
)
206 memset(mem_info
, 0, sizeof(*mem_info
));
208 /* Describe the first N DIMMs in the system */
210 dimm_max
= ARRAY_SIZE(mem_info
->dimm
);
211 for (channel
= 0; channel
< memory_info_hob
->ChannelCount
; channel
++) {
212 if (index
>= dimm_max
)
214 channel_info
= &memory_info_hob
->ChannelInfo
[channel
];
215 for (dimm
= 0; dimm
< channel_info
->DimmCount
; dimm
++) {
216 if (index
>= dimm_max
)
218 dimm_info
= &channel_info
->DimmInfo
[dimm
];
220 /* Populate the DIMM information */
221 if (dimm_info
->SizeInMb
) {
222 mem_info
->dimm
[index
].dimm_size
=
224 mem_info
->dimm
[index
].ddr_type
=
225 memory_info_hob
->MemoryType
;
226 mem_info
->dimm
[index
].ddr_frequency
=
227 memory_info_hob
->MemoryFrequencyInMHz
;
228 mem_info
->dimm
[index
].channel_num
=
229 channel_info
->ChannelId
;
230 mem_info
->dimm
[index
].dimm_num
=
232 switch (memory_info_hob
->DataWidth
) {
235 mem_info
->dimm
[index
].bus_width
=
240 mem_info
->dimm
[index
].bus_width
=
245 mem_info
->dimm
[index
].bus_width
=
250 mem_info
->dimm
[index
].bus_width
=
255 mem_info
->dimm
[index
].bus_width
=
256 MEMORY_BUS_WIDTH_128
;
263 mem_info
->dimm_cnt
= index
;
264 printk(BIOS_DEBUG
, "%d DIMMs found\n", mem_info
->dimm_cnt
);