blob: 0d5faa8d3d8719f32e9f624b432540d135615b71 [file] [log] [blame]
Angel Pons8a3453f2020-04-02 23:48:19 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lee Leahy3dad4892015-05-05 11:14:02 -07002
Lee Leahy3dad4892015-05-05 11:14:02 -07003#include <bootstate.h>
4#include <cbmem.h>
Elyes HAOUAS2195f7a2019-06-21 07:20:12 +02005#include <commonlib/helpers.h>
Lee Leahyb5ad8272015-04-20 15:29:16 -07006#include <console/console.h>
Lee Leahyc52a4f72016-08-09 09:02:13 -07007#include <console/streams.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -05008#include <fsp/util.h>
Lee Leahy3dad4892015-05-05 11:14:02 -07009#include <timestamp.h>
10
Lee Leahyb5ad8272015-04-20 15:29:16 -070011/* Locate the FSP binary in the coreboot filesystem */
Lee Leahya8874922015-08-26 14:58:29 -070012FSP_INFO_HEADER *find_fsp(uintptr_t fsp_base_address)
Lee Leahy3dad4892015-05-05 11:14:02 -070013{
Lee Leahyb5ad8272015-04-20 15:29:16 -070014 union {
15 EFI_FFS_FILE_HEADER *ffh;
16 FSP_INFO_HEADER *fih;
17 EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh;
18 EFI_FIRMWARE_VOLUME_HEADER *fvh;
19 EFI_RAW_SECTION *rs;
Lee Leahyb5ad8272015-04-20 15:29:16 -070020 u32 u32;
21 } fsp_ptr;
Alexandru Gagniuc5c261222015-08-29 18:53:43 -070022
Nico Hubere7947df2017-05-09 16:03:24 +020023 u64 *image_id;
Lee Leahy3dad4892015-05-05 11:14:02 -070024
Lee Leahy00c35c12016-05-17 08:57:42 -070025 /* Get the FSP binary base address in CBFS */
26 fsp_ptr.u32 = fsp_base_address;
Lee Leahy3dad4892015-05-05 11:14:02 -070027
Lee Leahy00c35c12016-05-17 08:57:42 -070028 /* Check the FV signature, _FVH */
Lee Leahy216712a2017-03-17 11:23:32 -070029 if (fsp_ptr.fvh->Signature != 0x4856465F)
Lee Leahy00c35c12016-05-17 08:57:42 -070030 return (FSP_INFO_HEADER *)ERROR_NO_FV_SIG;
Lee Leahy3dad4892015-05-05 11:14:02 -070031
Lee Leahy00c35c12016-05-17 08:57:42 -070032 /* Locate the file header which follows the FV header. */
Lee Leahyd3989a22016-05-17 09:29:09 -070033 fsp_ptr.u32 += fsp_ptr.fvh->ExtHeaderOffset;
34 fsp_ptr.u32 += fsp_ptr.fveh->ExtHeaderSize;
35 fsp_ptr.u32 = ALIGN_UP(fsp_ptr.u32, 8);
Lee Leahy00c35c12016-05-17 08:57:42 -070036
37 /* Check the FFS GUID */
38 if ((((u32 *)&fsp_ptr.ffh->Name)[0] != 0x912740BE)
39 || (((u32 *)&fsp_ptr.ffh->Name)[1] != 0x47342284)
40 || (((u32 *)&fsp_ptr.ffh->Name)[2] != 0xB08471B9)
41 || (((u32 *)&fsp_ptr.ffh->Name)[3] != 0x0C3F3527)) {
42 return (FSP_INFO_HEADER *)ERROR_NO_FFS_GUID;
43 }
44
45 /* Locate the Raw Section Header */
Lee Leahyd3989a22016-05-17 09:29:09 -070046 fsp_ptr.u32 += sizeof(EFI_FFS_FILE_HEADER);
Lee Leahy00c35c12016-05-17 08:57:42 -070047
Lee Leahy216712a2017-03-17 11:23:32 -070048 if (fsp_ptr.rs->Type != EFI_SECTION_RAW)
Lee Leahy00c35c12016-05-17 08:57:42 -070049 return (FSP_INFO_HEADER *)ERROR_NO_INFO_HEADER;
Lee Leahy00c35c12016-05-17 08:57:42 -070050
51 /* Locate the FSP INFO Header which follows the Raw Header. */
Lee Leahyd3989a22016-05-17 09:29:09 -070052 fsp_ptr.u32 += sizeof(EFI_RAW_SECTION);
Lee Leahy00c35c12016-05-17 08:57:42 -070053
54 /* Verify that the FSP base address.*/
Lee Leahy216712a2017-03-17 11:23:32 -070055 if (fsp_ptr.fih->ImageBase != fsp_base_address)
Lee Leahy00c35c12016-05-17 08:57:42 -070056 return (FSP_INFO_HEADER *)ERROR_IMAGEBASE_MISMATCH;
Lee Leahy00c35c12016-05-17 08:57:42 -070057
58 /* Verify the FSP Signature */
Lee Leahy216712a2017-03-17 11:23:32 -070059 if (fsp_ptr.fih->Signature != FSP_SIG)
Lee Leahy00c35c12016-05-17 08:57:42 -070060 return (FSP_INFO_HEADER *)ERROR_INFO_HEAD_SIG_MISMATCH;
Lee Leahy00c35c12016-05-17 08:57:42 -070061
62 /* Verify the FSP ID */
Nico Hubere7947df2017-05-09 16:03:24 +020063 image_id = (u64 *)&fsp_ptr.fih->ImageId[0];
64 if (*image_id != FSP_IMAGE_ID)
Lee Leahy00c35c12016-05-17 08:57:42 -070065 return (FSP_INFO_HEADER *)ERROR_FSP_SIG_MISMATCH;
66
Nico Hubere7947df2017-05-09 16:03:24 +020067 /* Verify the FSP Revision */
Matt DeVillier77c01e12017-09-07 11:28:53 -050068 if (fsp_ptr.fih->ImageRevision > FSP_IMAGE_REV)
Nico Hubere7947df2017-05-09 16:03:24 +020069 return (FSP_INFO_HEADER *)ERROR_FSP_REV_MISMATCH;
70
Lee Leahyb5ad8272015-04-20 15:29:16 -070071 return fsp_ptr.fih;
Lee Leahy3dad4892015-05-05 11:14:02 -070072}
73
Lee Leahyb5ad8272015-04-20 15:29:16 -070074void print_fsp_info(FSP_INFO_HEADER *fsp_header)
Lee Leahy3dad4892015-05-05 11:14:02 -070075{
Lee Leahyb5ad8272015-04-20 15:29:16 -070076 u8 *fsp_base;
Lee Leahy3dad4892015-05-05 11:14:02 -070077
Lee Leahyb5ad8272015-04-20 15:29:16 -070078 fsp_base = (u8 *)fsp_header->ImageBase;
79 printk(BIOS_SPEW, "FSP_INFO_HEADER: %p\n", fsp_header);
80 printk(BIOS_INFO, "FSP Signature: %c%c%c%c%c%c%c%c\n",
81 fsp_header->ImageId[0], fsp_header->ImageId[1],
82 fsp_header->ImageId[2], fsp_header->ImageId[3],
83 fsp_header->ImageId[4], fsp_header->ImageId[5],
84 fsp_header->ImageId[6], fsp_header->ImageId[7]);
85 printk(BIOS_INFO, "FSP Header Version: %d\n",
86 fsp_header->HeaderRevision);
Dhaval Sharma590ac642015-11-02 17:12:10 +053087 printk(BIOS_INFO, "FSP Revision: %d.%d.%d.%d\n",
88 (u8)((fsp_header->ImageRevision >> 24) & 0xff),
89 (u8)((fsp_header->ImageRevision >> 16) & 0xff),
Lee Leahyb5ad8272015-04-20 15:29:16 -070090 (u8)((fsp_header->ImageRevision >> 8) & 0xff),
91 (u8)(fsp_header->ImageRevision & 0xff));
Arthur Heymans3473d162022-03-24 00:26:57 +010092 if (CONFIG(DISPLAY_FSP_ENTRY_POINTS)) {
93 printk(BIOS_SPEW, "FSP Entry Points:\n");
94 printk(BIOS_SPEW, " %p: Image Base\n", fsp_base);
95 printk(BIOS_SPEW, " %p: TempRamInit\n",
96 &fsp_base[fsp_header->TempRamInitEntryOffset]);
97 printk(BIOS_SPEW, " %p: FspInit\n",
98 &fsp_base[fsp_header->FspInitEntryOffset]);
99 if (fsp_header->HeaderRevision >= FSP_HEADER_REVISION_2) {
100 printk(BIOS_SPEW, " %p: MemoryInit\n",
101 &fsp_base[fsp_header->FspMemoryInitEntryOffset]);
102 printk(BIOS_SPEW, " %p: TempRamExit\n",
103 &fsp_base[fsp_header->TempRamExitEntryOffset]);
104 printk(BIOS_SPEW, " %p: SiliconInit\n",
105 &fsp_base[fsp_header->FspSiliconInitEntryOffset]);
106 }
107 printk(BIOS_SPEW, " %p: NotifyPhase\n",
108 &fsp_base[fsp_header->NotifyPhaseEntryOffset]);
109 printk(BIOS_SPEW, " %p: Image End\n",
110 &fsp_base[fsp_header->ImageSize]);
Lee Leahyb5ad8272015-04-20 15:29:16 -0700111 }
Lee Leahyb5ad8272015-04-20 15:29:16 -0700112}
113
Lee Leahyb5ad8272015-04-20 15:29:16 -0700114void fsp_notify(u32 phase)
115{
116 FSP_NOTIFY_PHASE notify_phase_proc;
117 NOTIFY_PHASE_PARAMS notify_phase_params;
118 EFI_STATUS status;
119 FSP_INFO_HEADER *fsp_header_ptr;
120
121 fsp_header_ptr = fsp_get_fih();
122 if (fsp_header_ptr == NULL) {
Lee Leahya8874922015-08-26 14:58:29 -0700123 fsp_header_ptr = (void *)find_fsp(CONFIG_FSP_LOC);
Lee Leahyb5ad8272015-04-20 15:29:16 -0700124 if ((u32)fsp_header_ptr < 0xff) {
125 /* output something in case there is no serial */
126 post_code(0x4F);
127 die("Can't find the FSP!\n");
128 }
Lee Leahy3dad4892015-05-05 11:14:02 -0700129 }
130
Lee Leahyb5ad8272015-04-20 15:29:16 -0700131 /* call FSP PEI to Notify PostPciEnumeration */
132 notify_phase_proc = (FSP_NOTIFY_PHASE)(fsp_header_ptr->ImageBase +
133 fsp_header_ptr->NotifyPhaseEntryOffset);
134 notify_phase_params.Phase = phase;
Lee Leahy3dad4892015-05-05 11:14:02 -0700135
Duncan Lauriefb509832015-11-22 14:53:57 -0800136 if (phase == EnumInitPhaseReadyToBoot) {
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100137 timestamp_add_now(TS_FSP_FINALIZE_START);
lilacious40cb3fe2023-06-21 23:24:14 +0200138 post_code(POSTCODE_FSP_NOTIFY_BEFORE_FINALIZE);
Lee Leahya5244c32015-12-17 11:13:01 -0800139 } else {
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100140 timestamp_add_now(TS_FSP_ENUMERATE_START);
lilacious40cb3fe2023-06-21 23:24:14 +0200141 post_code(POSTCODE_FSP_NOTIFY_BEFORE_ENUMERATE);
Duncan Lauriefb509832015-11-22 14:53:57 -0800142 }
Lee Leahy3dad4892015-05-05 11:14:02 -0700143
Lee Leahyb5ad8272015-04-20 15:29:16 -0700144 status = notify_phase_proc(&notify_phase_params);
Lee Leahy3dad4892015-05-05 11:14:02 -0700145
Lee Leahyb5ad8272015-04-20 15:29:16 -0700146 timestamp_add_now(phase == EnumInitPhaseReadyToBoot ?
Jakub Czapigaad6157e2022-02-15 11:50:31 +0100147 TS_FSP_FINALIZE_END : TS_FSP_ENUMERATE_END);
Lee Leahy3dad4892015-05-05 11:14:02 -0700148
Lee Leahyb5ad8272015-04-20 15:29:16 -0700149 if (status != 0)
150 printk(BIOS_ERR, "FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n",
151 phase, status);
Lee Leahy3dad4892015-05-05 11:14:02 -0700152}
Lee Leahy3dad4892015-05-05 11:14:02 -0700153
Lee Leahyb5ad8272015-04-20 15:29:16 -0700154static void fsp_notify_boot_state_callback(void *arg)
Lee Leahy3dad4892015-05-05 11:14:02 -0700155{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700156 u32 phase = (u32)arg;
Lee Leahy3dad4892015-05-05 11:14:02 -0700157
Lee Leahyb5ad8272015-04-20 15:29:16 -0700158 printk(BIOS_SPEW, "Calling FspNotify(0x%08x)\n", phase);
159 fsp_notify(phase);
Lee Leahy3dad4892015-05-05 11:14:02 -0700160}
161
Lee Leahyb5ad8272015-04-20 15:29:16 -0700162BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT,
163 fsp_notify_boot_state_callback,
164 (void *)EnumInitPhaseAfterPciEnumeration);
165BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT,
166 fsp_notify_boot_state_callback,
167 (void *)EnumInitPhaseReadyToBoot);
168BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,
169 fsp_notify_boot_state_callback,
170 (void *)EnumInitPhaseReadyToBoot);
171
Lee Leahyb5ad8272015-04-20 15:29:16 -0700172struct fsp_runtime {
173 uint32_t fih;
174 uint32_t hob_list;
Stefan Reinauer6a001132017-07-13 02:20:27 +0200175} __packed;
Lee Leahyb5ad8272015-04-20 15:29:16 -0700176
Lee Leahyb5ad8272015-04-20 15:29:16 -0700177void fsp_set_runtime(FSP_INFO_HEADER *fih, void *hob_list)
Lee Leahy3dad4892015-05-05 11:14:02 -0700178{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700179 struct fsp_runtime *fspr;
180
181 fspr = cbmem_add(CBMEM_ID_FSP_RUNTIME, sizeof(*fspr));
182
183 if (fspr == NULL)
184 die("Can't save FSP runtime information.\n");
185
186 fspr->fih = (uintptr_t)fih;
187 fspr->hob_list = (uintptr_t)hob_list;
Lee Leahy3dad4892015-05-05 11:14:02 -0700188}
189
Lee Leahyb5ad8272015-04-20 15:29:16 -0700190FSP_INFO_HEADER *fsp_get_fih(void)
Lee Leahy3dad4892015-05-05 11:14:02 -0700191{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700192 struct fsp_runtime *fspr;
193
194 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
195
196 if (fspr == NULL)
197 return NULL;
198
199 return (void *)(uintptr_t)fspr->fih;
Lee Leahy3dad4892015-05-05 11:14:02 -0700200}
201
Lee Leahyb5ad8272015-04-20 15:29:16 -0700202void *fsp_get_hob_list(void)
203{
204 struct fsp_runtime *fspr;
Lee Leahy3dad4892015-05-05 11:14:02 -0700205
Lee Leahyb5ad8272015-04-20 15:29:16 -0700206 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
207
208 if (fspr == NULL)
209 return NULL;
210
211 return (void *)(uintptr_t)fspr->hob_list;
212}
213
214void fsp_update_fih(FSP_INFO_HEADER *fih)
215{
216 struct fsp_runtime *fspr;
217
218 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
219
220 if (fspr == NULL)
221 die("Can't update FSP runtime information.\n");
222
223 fspr->fih = (uintptr_t)fih;
224}
Lee Leahy94b856e2015-10-15 12:07:03 -0700225
Lee Leahy66208bd2015-10-15 16:17:58 -0700226void fsp_display_upd_value(const char *name, uint32_t size, uint64_t old,
Lee Leahy94b856e2015-10-15 12:07:03 -0700227 uint64_t new)
228{
229 if (old == new) {
230 switch (size) {
231 case 1:
232 printk(BIOS_SPEW, " 0x%02llx: %s\n", new, name);
233 break;
234
235 case 2:
236 printk(BIOS_SPEW, " 0x%04llx: %s\n", new, name);
237 break;
238
239 case 4:
240 printk(BIOS_SPEW, " 0x%08llx: %s\n", new, name);
241 break;
242
243 case 8:
244 printk(BIOS_SPEW, " 0x%016llx: %s\n", new, name);
245 break;
246 }
247 } else {
248 switch (size) {
249 case 1:
250 printk(BIOS_SPEW, " 0x%02llx --> 0x%02llx: %s\n", old,
251 new, name);
252 break;
253
254 case 2:
255 printk(BIOS_SPEW, " 0x%04llx --> 0x%04llx: %s\n", old,
256 new, name);
257 break;
258
259 case 4:
260 printk(BIOS_SPEW, " 0x%08llx --> 0x%08llx: %s\n", old,
261 new, name);
262 break;
263
264 case 8:
265 printk(BIOS_SPEW, " 0x%016llx --> 0x%016llx: %s\n",
266 old, new, name);
267 break;
268 }
269 }
270}