blob: 5ce753f4d435b46ec18d1e85ec6f5ad48f9e9048 [file] [log] [blame]
Lee Leahy3dad4892015-05-05 11:14:02 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
Lee Leahyb5ad8272015-04-20 15:29:16 -07005 * Copyright (C) 2015 Intel Corp.
Lee Leahy3dad4892015-05-05 11:14:02 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Lee Leahy3dad4892015-05-05 11:14:02 -070015 */
16
Lee Leahy3dad4892015-05-05 11:14:02 -070017#include <bootstate.h>
18#include <cbmem.h>
Lee Leahyb5ad8272015-04-20 15:29:16 -070019#include <console/console.h>
Lee Leahyc52a4f72016-08-09 09:02:13 -070020#include <console/streams.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050021#include <fsp/util.h>
Lee Leahy3dad4892015-05-05 11:14:02 -070022#include <timestamp.h>
23
Lee Leahyb5ad8272015-04-20 15:29:16 -070024/* Locate the FSP binary in the coreboot filesystem */
Lee Leahya8874922015-08-26 14:58:29 -070025FSP_INFO_HEADER *find_fsp(uintptr_t fsp_base_address)
Lee Leahy3dad4892015-05-05 11:14:02 -070026{
Lee Leahyb5ad8272015-04-20 15:29:16 -070027 union {
28 EFI_FFS_FILE_HEADER *ffh;
29 FSP_INFO_HEADER *fih;
30 EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh;
31 EFI_FIRMWARE_VOLUME_HEADER *fvh;
32 EFI_RAW_SECTION *rs;
Lee Leahyb5ad8272015-04-20 15:29:16 -070033 u32 u32;
34 } fsp_ptr;
Alexandru Gagniuc5c261222015-08-29 18:53:43 -070035 static const union {
36 char str_id[8];
37 u32 int_id[2];
38 } fsp_id = {
39 .str_id = CONFIG_FSP_IMAGE_ID_STRING
40 };
41
Lee Leahyb5ad8272015-04-20 15:29:16 -070042 u32 *image_id;
Lee Leahy3dad4892015-05-05 11:14:02 -070043
Lee Leahy00c35c12016-05-17 08:57:42 -070044 /* Get the FSP binary base address in CBFS */
45 fsp_ptr.u32 = fsp_base_address;
Lee Leahy3dad4892015-05-05 11:14:02 -070046
Lee Leahy00c35c12016-05-17 08:57:42 -070047 /* Check the FV signature, _FVH */
48 if (fsp_ptr.fvh->Signature != 0x4856465F) {
49 return (FSP_INFO_HEADER *)ERROR_NO_FV_SIG;
Lee Leahy3dad4892015-05-05 11:14:02 -070050 }
51
Lee Leahy00c35c12016-05-17 08:57:42 -070052 /* Locate the file header which follows the FV header. */
Lee Leahyd3989a22016-05-17 09:29:09 -070053 fsp_ptr.u32 += fsp_ptr.fvh->ExtHeaderOffset;
54 fsp_ptr.u32 += fsp_ptr.fveh->ExtHeaderSize;
55 fsp_ptr.u32 = ALIGN_UP(fsp_ptr.u32, 8);
Lee Leahy00c35c12016-05-17 08:57:42 -070056
57 /* Check the FFS GUID */
58 if ((((u32 *)&fsp_ptr.ffh->Name)[0] != 0x912740BE)
59 || (((u32 *)&fsp_ptr.ffh->Name)[1] != 0x47342284)
60 || (((u32 *)&fsp_ptr.ffh->Name)[2] != 0xB08471B9)
61 || (((u32 *)&fsp_ptr.ffh->Name)[3] != 0x0C3F3527)) {
62 return (FSP_INFO_HEADER *)ERROR_NO_FFS_GUID;
63 }
64
65 /* Locate the Raw Section Header */
Lee Leahyd3989a22016-05-17 09:29:09 -070066 fsp_ptr.u32 += sizeof(EFI_FFS_FILE_HEADER);
Lee Leahy00c35c12016-05-17 08:57:42 -070067
68 if (fsp_ptr.rs->Type != EFI_SECTION_RAW) {
69 return (FSP_INFO_HEADER *)ERROR_NO_INFO_HEADER;
70 }
71
72 /* Locate the FSP INFO Header which follows the Raw Header. */
Lee Leahyd3989a22016-05-17 09:29:09 -070073 fsp_ptr.u32 += sizeof(EFI_RAW_SECTION);
Lee Leahy00c35c12016-05-17 08:57:42 -070074
75 /* Verify that the FSP base address.*/
76 if (fsp_ptr.fih->ImageBase != fsp_base_address) {
77 return (FSP_INFO_HEADER *)ERROR_IMAGEBASE_MISMATCH;
78 }
79
80 /* Verify the FSP Signature */
81 if (fsp_ptr.fih->Signature != FSP_SIG) {
82 return (FSP_INFO_HEADER *)ERROR_INFO_HEAD_SIG_MISMATCH;
83 }
84
85 /* Verify the FSP ID */
86 image_id = (u32 *)&fsp_ptr.fih->ImageId[0];
87 if ((image_id[0] != fsp_id.int_id[0])
88 || (image_id[1] != fsp_id.int_id[1]))
89 return (FSP_INFO_HEADER *)ERROR_FSP_SIG_MISMATCH;
90
Lee Leahyb5ad8272015-04-20 15:29:16 -070091 return fsp_ptr.fih;
Lee Leahy3dad4892015-05-05 11:14:02 -070092}
93
Lee Leahyb5ad8272015-04-20 15:29:16 -070094void print_fsp_info(FSP_INFO_HEADER *fsp_header)
Lee Leahy3dad4892015-05-05 11:14:02 -070095{
Lee Leahyb5ad8272015-04-20 15:29:16 -070096 u8 *fsp_base;
Lee Leahy3dad4892015-05-05 11:14:02 -070097
Lee Leahyb5ad8272015-04-20 15:29:16 -070098 fsp_base = (u8 *)fsp_header->ImageBase;
99 printk(BIOS_SPEW, "FSP_INFO_HEADER: %p\n", fsp_header);
100 printk(BIOS_INFO, "FSP Signature: %c%c%c%c%c%c%c%c\n",
101 fsp_header->ImageId[0], fsp_header->ImageId[1],
102 fsp_header->ImageId[2], fsp_header->ImageId[3],
103 fsp_header->ImageId[4], fsp_header->ImageId[5],
104 fsp_header->ImageId[6], fsp_header->ImageId[7]);
105 printk(BIOS_INFO, "FSP Header Version: %d\n",
106 fsp_header->HeaderRevision);
Dhaval Sharma590ac642015-11-02 17:12:10 +0530107 printk(BIOS_INFO, "FSP Revision: %d.%d.%d.%d\n",
108 (u8)((fsp_header->ImageRevision >> 24) & 0xff),
109 (u8)((fsp_header->ImageRevision >> 16) & 0xff),
Lee Leahyb5ad8272015-04-20 15:29:16 -0700110 (u8)((fsp_header->ImageRevision >> 8) & 0xff),
111 (u8)(fsp_header->ImageRevision & 0xff));
112#if IS_ENABLED(CONFIG_DISPLAY_FSP_ENTRY_POINTS)
113 printk(BIOS_SPEW, "FSP Entry Points:\n");
114 printk(BIOS_SPEW, " 0x%p: Image Base\n", fsp_base);
115 printk(BIOS_SPEW, " 0x%p: TempRamInit\n",
116 &fsp_base[fsp_header->TempRamInitEntryOffset]);
117 printk(BIOS_SPEW, " 0x%p: FspInit\n",
118 &fsp_base[fsp_header->FspInitEntryOffset]);
119 if (fsp_header->HeaderRevision >= FSP_HEADER_REVISION_2) {
120 printk(BIOS_SPEW, " 0x%p: MemoryInit\n",
121 &fsp_base[fsp_header->FspMemoryInitEntryOffset]);
122 printk(BIOS_SPEW, " 0x%p: TempRamExit\n",
123 &fsp_base[fsp_header->TempRamExitEntryOffset]);
124 printk(BIOS_SPEW, " 0x%p: SiliconInit\n",
125 &fsp_base[fsp_header->FspSiliconInitEntryOffset]);
126 }
127 printk(BIOS_SPEW, " 0x%p: NotifyPhase\n",
128 &fsp_base[fsp_header->NotifyPhaseEntryOffset]);
129 printk(BIOS_SPEW, " 0x%p: Image End\n",
130 &fsp_base[fsp_header->ImageSize]);
131#endif
132}
133
Lee Leahyb5ad8272015-04-20 15:29:16 -0700134void fsp_notify(u32 phase)
135{
136 FSP_NOTIFY_PHASE notify_phase_proc;
137 NOTIFY_PHASE_PARAMS notify_phase_params;
138 EFI_STATUS status;
139 FSP_INFO_HEADER *fsp_header_ptr;
140
141 fsp_header_ptr = fsp_get_fih();
142 if (fsp_header_ptr == NULL) {
Lee Leahya8874922015-08-26 14:58:29 -0700143 fsp_header_ptr = (void *)find_fsp(CONFIG_FSP_LOC);
Lee Leahyb5ad8272015-04-20 15:29:16 -0700144 if ((u32)fsp_header_ptr < 0xff) {
145 /* output something in case there is no serial */
146 post_code(0x4F);
147 die("Can't find the FSP!\n");
148 }
Lee Leahy3dad4892015-05-05 11:14:02 -0700149 }
150
Lee Leahyb5ad8272015-04-20 15:29:16 -0700151 /* call FSP PEI to Notify PostPciEnumeration */
152 notify_phase_proc = (FSP_NOTIFY_PHASE)(fsp_header_ptr->ImageBase +
153 fsp_header_ptr->NotifyPhaseEntryOffset);
154 notify_phase_params.Phase = phase;
Lee Leahy3dad4892015-05-05 11:14:02 -0700155
Duncan Lauriefb509832015-11-22 14:53:57 -0800156 if (phase == EnumInitPhaseReadyToBoot) {
Duncan Lauriefb509832015-11-22 14:53:57 -0800157 timestamp_add_now(TS_FSP_BEFORE_FINALIZE);
158 post_code(POST_FSP_NOTIFY_BEFORE_FINALIZE);
Lee Leahya5244c32015-12-17 11:13:01 -0800159 } else {
160 timestamp_add_now(TS_FSP_BEFORE_ENUMERATE);
161 post_code(POST_FSP_NOTIFY_BEFORE_ENUMERATE);
Duncan Lauriefb509832015-11-22 14:53:57 -0800162 }
Lee Leahy3dad4892015-05-05 11:14:02 -0700163
Lee Leahyb5ad8272015-04-20 15:29:16 -0700164 status = notify_phase_proc(&notify_phase_params);
Lee Leahy3dad4892015-05-05 11:14:02 -0700165
Lee Leahyb5ad8272015-04-20 15:29:16 -0700166 timestamp_add_now(phase == EnumInitPhaseReadyToBoot ?
167 TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
Lee Leahy3dad4892015-05-05 11:14:02 -0700168
Lee Leahyb5ad8272015-04-20 15:29:16 -0700169 if (status != 0)
170 printk(BIOS_ERR, "FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n",
171 phase, status);
Lee Leahy3dad4892015-05-05 11:14:02 -0700172}
Lee Leahy3dad4892015-05-05 11:14:02 -0700173
Lee Leahyb5ad8272015-04-20 15:29:16 -0700174static void fsp_notify_boot_state_callback(void *arg)
Lee Leahy3dad4892015-05-05 11:14:02 -0700175{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700176 u32 phase = (u32)arg;
Lee Leahy3dad4892015-05-05 11:14:02 -0700177
Lee Leahyb5ad8272015-04-20 15:29:16 -0700178 printk(BIOS_SPEW, "Calling FspNotify(0x%08x)\n", phase);
179 fsp_notify(phase);
Lee Leahy3dad4892015-05-05 11:14:02 -0700180}
181
Lee Leahyb5ad8272015-04-20 15:29:16 -0700182BOOT_STATE_INIT_ENTRY(BS_DEV_RESOURCES, BS_ON_EXIT,
183 fsp_notify_boot_state_callback,
184 (void *)EnumInitPhaseAfterPciEnumeration);
185BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_EXIT,
186 fsp_notify_boot_state_callback,
187 (void *)EnumInitPhaseReadyToBoot);
188BOOT_STATE_INIT_ENTRY(BS_OS_RESUME, BS_ON_ENTRY,
189 fsp_notify_boot_state_callback,
190 (void *)EnumInitPhaseReadyToBoot);
191
Lee Leahyb5ad8272015-04-20 15:29:16 -0700192struct fsp_runtime {
193 uint32_t fih;
194 uint32_t hob_list;
195} __attribute__((packed));
196
197
198void fsp_set_runtime(FSP_INFO_HEADER *fih, void *hob_list)
Lee Leahy3dad4892015-05-05 11:14:02 -0700199{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700200 struct fsp_runtime *fspr;
201
202 fspr = cbmem_add(CBMEM_ID_FSP_RUNTIME, sizeof(*fspr));
203
204 if (fspr == NULL)
205 die("Can't save FSP runtime information.\n");
206
207 fspr->fih = (uintptr_t)fih;
208 fspr->hob_list = (uintptr_t)hob_list;
Lee Leahy3dad4892015-05-05 11:14:02 -0700209}
210
Lee Leahyb5ad8272015-04-20 15:29:16 -0700211FSP_INFO_HEADER *fsp_get_fih(void)
Lee Leahy3dad4892015-05-05 11:14:02 -0700212{
Lee Leahyb5ad8272015-04-20 15:29:16 -0700213 struct fsp_runtime *fspr;
214
215 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
216
217 if (fspr == NULL)
218 return NULL;
219
220 return (void *)(uintptr_t)fspr->fih;
Lee Leahy3dad4892015-05-05 11:14:02 -0700221}
222
Lee Leahyb5ad8272015-04-20 15:29:16 -0700223void *fsp_get_hob_list(void)
224{
225 struct fsp_runtime *fspr;
Lee Leahy3dad4892015-05-05 11:14:02 -0700226
Lee Leahyb5ad8272015-04-20 15:29:16 -0700227 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
228
229 if (fspr == NULL)
230 return NULL;
231
232 return (void *)(uintptr_t)fspr->hob_list;
233}
234
235void fsp_update_fih(FSP_INFO_HEADER *fih)
236{
237 struct fsp_runtime *fspr;
238
239 fspr = cbmem_find(CBMEM_ID_FSP_RUNTIME);
240
241 if (fspr == NULL)
242 die("Can't update FSP runtime information.\n");
243
244 fspr->fih = (uintptr_t)fih;
245}
Lee Leahy94b856e2015-10-15 12:07:03 -0700246
Lee Leahy66208bd2015-10-15 16:17:58 -0700247void fsp_display_upd_value(const char *name, uint32_t size, uint64_t old,
Lee Leahy94b856e2015-10-15 12:07:03 -0700248 uint64_t new)
249{
250 if (old == new) {
251 switch (size) {
252 case 1:
253 printk(BIOS_SPEW, " 0x%02llx: %s\n", new, name);
254 break;
255
256 case 2:
257 printk(BIOS_SPEW, " 0x%04llx: %s\n", new, name);
258 break;
259
260 case 4:
261 printk(BIOS_SPEW, " 0x%08llx: %s\n", new, name);
262 break;
263
264 case 8:
265 printk(BIOS_SPEW, " 0x%016llx: %s\n", new, name);
266 break;
267 }
268 } else {
269 switch (size) {
270 case 1:
271 printk(BIOS_SPEW, " 0x%02llx --> 0x%02llx: %s\n", old,
272 new, name);
273 break;
274
275 case 2:
276 printk(BIOS_SPEW, " 0x%04llx --> 0x%04llx: %s\n", old,
277 new, name);
278 break;
279
280 case 4:
281 printk(BIOS_SPEW, " 0x%08llx --> 0x%08llx: %s\n", old,
282 new, name);
283 break;
284
285 case 8:
286 printk(BIOS_SPEW, " 0x%016llx --> 0x%016llx: %s\n",
287 old, new, name);
288 break;
289 }
290 }
291}
Lee Leahyc52a4f72016-08-09 09:02:13 -0700292
293size_t EFIAPI fsp_write_line(uint8_t *buffer, size_t number_of_bytes)
294{
295 console_write_line(buffer, number_of_bytes);
296 return number_of_bytes;
297}