blob: 9ecdfd658a6305212dc9fed447899fb9f4941c14 [file] [log] [blame]
Lee Leahy0946ec32015-04-20 15:24:54 -07001/*
2 * This file is part of the coreboot project.
3 *
Lee Leahy0946ec32015-04-20 15:24:54 -07004 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
Lee Leahy0946ec32015-04-20 15:24:54 -070012 */
13
Duncan Laurie59be6242016-03-07 13:21:56 -080014#include <bootmode.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050015#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070016#include <console/console.h>
Kyösti Mälkkib2a5f0b2019-08-04 19:54:32 +030017#include <cpu/x86/smm.h>
Lee Leahy94b856e2015-10-15 12:07:03 -070018#include <fsp/ramstage.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050019#include <fsp/util.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070020#include <lib.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070021#include <stage_cache.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050022#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070023#include <timestamp.h>
Frans Hendriks50b999f2019-11-08 13:55:45 +010024#include <cbmem.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070025
26/* SOC initialization after FSP silicon init */
Aaron Durbin64031672018-04-21 14:45:32 -060027__weak void soc_after_silicon_init(void)
Lee Leahy0946ec32015-04-20 15:24:54 -070028{
Lee Leahy0946ec32015-04-20 15:24:54 -070029}
30
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040031static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
32{
33 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040034 void *hob_list_ptr = get_hob_list();
35
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040036 /* Verify the HOBs */
37 if (hob_list_ptr == NULL) {
Frans Hendriks509f4692019-06-28 14:11:41 +020038 printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040039 return;
40 }
41
Frans Hendriks509f4692019-06-28 14:11:41 +020042 if (CONFIG(DISPLAY_HOBS))
43 print_hob_type_structure(0, hob_list_ptr);
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040044
45 /*
46 * Verify that FSP is generating the required HOBs:
47 * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
48 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
49 * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
50 * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
51 * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
52 * if the ImageAttribute bit is set
53 * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
54 */
55 if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
Frans Hendriks509f4692019-06-28 14:11:41 +020056 !get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
57 CONFIG(DISPLAY_HOBS)) {
58 printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
59 printk(BIOS_ERR,
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040060 "ERROR - Missing one or more required FSP HOBs!\n");
Frans Hendriks509f4692019-06-28 14:11:41 +020061 }
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040062}
63
Lee Leahycff5f092016-02-08 08:37:53 -080064void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070065{
Lee Leahy0946ec32015-04-20 15:24:54 -070066 FSP_SILICON_INIT fsp_silicon_init;
67 SILICON_INIT_UPD *original_params;
68 SILICON_INIT_UPD silicon_init_params;
69 EFI_STATUS status;
70 UPD_DATA_REGION *upd_ptr;
71 VPD_DATA_REGION *vpd_ptr;
Frans Hendriks50b999f2019-11-08 13:55:45 +010072 const struct cbmem_entry *logo_entry;
Lee Leahy0946ec32015-04-20 15:24:54 -070073
Lee Leahycff5f092016-02-08 08:37:53 -080074 /* Display the FSP header */
Lee Leahy0946ec32015-04-20 15:24:54 -070075 if (fsp_info_header == NULL) {
76 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
77 return;
78 }
79 print_fsp_info(fsp_info_header);
80
81 /* Initialize the UPD values */
82 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
83 fsp_info_header->ImageBase);
Julius Werner540a9802019-12-09 13:03:29 -080084 printk(BIOS_DEBUG, "%p: VPD Data\n", vpd_ptr);
Lee Leahy0946ec32015-04-20 15:24:54 -070085 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
86 fsp_info_header->ImageBase);
Julius Werner540a9802019-12-09 13:03:29 -080087 printk(BIOS_DEBUG, "%p: UPD Data\n", upd_ptr);
Lee Leahy0946ec32015-04-20 15:24:54 -070088 original_params = (void *)((u8 *)upd_ptr +
89 upd_ptr->SiliconInitUpdOffset);
90 memcpy(&silicon_init_params, original_params,
91 sizeof(silicon_init_params));
92 soc_silicon_init_params(&silicon_init_params);
93
94 /* Locate VBT and pass to FSP GOP */
Julius Wernercd49cce2019-03-05 16:53:33 -080095 if (CONFIG(RUN_FSP_GOP))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050096 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -070097 mainboard_silicon_init_params(&silicon_init_params);
98
Frans Hendriks50b999f2019-11-08 13:55:45 +010099 if (CONFIG(FSP1_1_DISPLAY_LOGO) && !is_s3_wakeup) {
100 silicon_init_params.PcdLogoSize = 1 * MiB;
101 logo_entry = cbmem_entry_add(CBMEM_ID_FSP_LOGO,
102 silicon_init_params.PcdLogoSize);
103 silicon_init_params.PcdLogoPtr = (UINT32)cbmem_entry_start(logo_entry);
104 load_logo(&silicon_init_params);
105 }
106
Lee Leahy0946ec32015-04-20 15:24:54 -0700107 /* Display the UPD data */
Julius Wernercd49cce2019-03-05 16:53:33 -0800108 if (CONFIG(DISPLAY_UPD_DATA))
Lee Leahy0946ec32015-04-20 15:24:54 -0700109 soc_display_silicon_init_params(original_params,
110 &silicon_init_params);
111
112 /* Perform silicon initialization after RAM is configured */
113 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
114 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
115 + fsp_info_header->FspSiliconInitEntryOffset);
116 timestamp_add_now(TS_FSP_SILICON_INIT_START);
Julius Werner540a9802019-12-09 13:03:29 -0800117 printk(BIOS_DEBUG, "Calling FspSiliconInit(%p) at %p\n",
Lee Leahy0946ec32015-04-20 15:24:54 -0700118 &silicon_init_params, fsp_silicon_init);
Duncan Lauriefb509832015-11-22 14:53:57 -0800119 post_code(POST_FSP_SILICON_INIT);
Lee Leahy0946ec32015-04-20 15:24:54 -0700120 status = fsp_silicon_init(&silicon_init_params);
121 timestamp_add_now(TS_FSP_SILICON_INIT_END);
122 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
123
Frans Hendriks50b999f2019-11-08 13:55:45 +0100124 /* The logo_entry can be freed up now as it is not required any longer */
125 if (CONFIG(FSP1_1_DISPLAY_LOGO) && !is_s3_wakeup)
126 cbmem_entry_remove(logo_entry);
127
Duncan Laurie59be6242016-03-07 13:21:56 -0800128 /* Mark graphics init done after SiliconInit if VBT was provided */
Julius Wernercd49cce2019-03-05 16:53:33 -0800129#if CONFIG(RUN_FSP_GOP)
Duncan Laurie59be6242016-03-07 13:21:56 -0800130 /* GraphicsConfigPtr doesn't exist in Quark X1000's FSP, so this needs
Elyes HAOUAS2e4d8062016-08-25 20:50:50 +0200131 * to be #if'd out instead of using if (). */
Duncan Laurie59be6242016-03-07 13:21:56 -0800132 if (silicon_init_params.GraphicsConfigPtr)
133 gfx_set_init_done(1);
134#endif
135
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400136 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700137 soc_after_silicon_init();
138}
139
Aaron Durbinabf87a22015-08-05 12:26:56 -0500140static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700141{
Julius Wernercd49cce2019-03-05 16:53:33 -0800142 if (CONFIG(NO_STAGE_CACHE))
Furquan Shaikh1e162bf2016-05-06 09:20:35 -0700143 return;
144
145 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
146
Aaron Durbinabf87a22015-08-05 12:26:56 -0500147 if (prog_entry(fsp) == NULL) {
148 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700149 return;
150 }
151
Aaron Durbinabf87a22015-08-05 12:26:56 -0500152 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700153}
154
Aaron Durbinabf87a22015-08-05 12:26:56 -0500155static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700156{
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500157 if (prog_locate(fsp)) {
158 printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp));
Lee Leahy0946ec32015-04-20 15:24:54 -0700159 return -1;
160 }
161
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500162 if (fsp_relocate(fsp, prog_rdev(fsp))) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500163 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
164 return -1;
165 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700166
Lee Leahy0946ec32015-04-20 15:24:54 -0700167 return 0;
168}
169
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800170void fsp_load(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700171{
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800172 static int load_done;
Aaron Durbin7e7a4df2015-12-08 14:34:35 -0600173 struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500174 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700175
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800176 if (load_done)
177 return;
178
Julius Wernercd49cce2019-03-05 16:53:33 -0800179 if (is_s3_wakeup && !CONFIG(NO_STAGE_CACHE)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700180 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500181 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700182 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500183 fsp_find_and_relocate(&fsp);
Aaron Durbinabf87a22015-08-05 12:26:56 -0500184 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700185 }
186
Aaron Durbinabf87a22015-08-05 12:26:56 -0500187 /* FSP_INFO_HEADER is set as the program entry. */
188 fsp_update_fih(prog_entry(&fsp));
189
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800190 load_done = 1;
191}
192
193void intel_silicon_init(void)
194{
195 fsp_load();
196 fsp_run_silicon_init(fsp_get_fih(), acpi_is_wakeup_s3());
Lee Leahy0946ec32015-04-20 15:24:54 -0700197}
198
199/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600200__weak void mainboard_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700201 SILICON_INIT_UPD *params)
202{
Lee Leahy0946ec32015-04-20 15:24:54 -0700203};
204
205/* Display the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600206__weak void soc_display_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700207 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
208{
209 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
210 hexdump32(BIOS_SPEW, new, sizeof(*new));
211}
212
213/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600214__weak void soc_silicon_init_params(SILICON_INIT_UPD *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700215{
Lee Leahy0946ec32015-04-20 15:24:54 -0700216}