blob: d278d08ed2222949b7b26c112bfe09a28e6f3824 [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>
24
25/* SOC initialization after FSP silicon init */
Aaron Durbin64031672018-04-21 14:45:32 -060026__weak void soc_after_silicon_init(void)
Lee Leahy0946ec32015-04-20 15:24:54 -070027{
Lee Leahy0946ec32015-04-20 15:24:54 -070028}
29
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040030static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
31{
32 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040033 void *hob_list_ptr = get_hob_list();
34
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040035 /* Verify the HOBs */
36 if (hob_list_ptr == NULL) {
Frans Hendriks509f4692019-06-28 14:11:41 +020037 printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040038 return;
39 }
40
Frans Hendriks509f4692019-06-28 14:11:41 +020041 if (CONFIG(DISPLAY_HOBS))
42 print_hob_type_structure(0, hob_list_ptr);
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040043
44 /*
45 * Verify that FSP is generating the required HOBs:
46 * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
47 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
48 * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
49 * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
50 * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
51 * if the ImageAttribute bit is set
52 * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
53 */
54 if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
Frans Hendriks509f4692019-06-28 14:11:41 +020055 !get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
56 CONFIG(DISPLAY_HOBS)) {
57 printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
58 printk(BIOS_ERR,
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040059 "ERROR - Missing one or more required FSP HOBs!\n");
Frans Hendriks509f4692019-06-28 14:11:41 +020060 }
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040061}
62
Lee Leahycff5f092016-02-08 08:37:53 -080063void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070064{
Lee Leahy0946ec32015-04-20 15:24:54 -070065 FSP_SILICON_INIT fsp_silicon_init;
66 SILICON_INIT_UPD *original_params;
67 SILICON_INIT_UPD silicon_init_params;
68 EFI_STATUS status;
69 UPD_DATA_REGION *upd_ptr;
70 VPD_DATA_REGION *vpd_ptr;
71
Lee Leahycff5f092016-02-08 08:37:53 -080072 /* Display the FSP header */
Lee Leahy0946ec32015-04-20 15:24:54 -070073 if (fsp_info_header == NULL) {
74 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
75 return;
76 }
77 print_fsp_info(fsp_info_header);
78
79 /* Initialize the UPD values */
80 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
81 fsp_info_header->ImageBase);
82 printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
83 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
84 fsp_info_header->ImageBase);
85 printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
86 original_params = (void *)((u8 *)upd_ptr +
87 upd_ptr->SiliconInitUpdOffset);
88 memcpy(&silicon_init_params, original_params,
89 sizeof(silicon_init_params));
90 soc_silicon_init_params(&silicon_init_params);
91
92 /* Locate VBT and pass to FSP GOP */
Julius Wernercd49cce2019-03-05 16:53:33 -080093 if (CONFIG(RUN_FSP_GOP))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050094 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -070095 mainboard_silicon_init_params(&silicon_init_params);
96
97 /* Display the UPD data */
Julius Wernercd49cce2019-03-05 16:53:33 -080098 if (CONFIG(DISPLAY_UPD_DATA))
Lee Leahy0946ec32015-04-20 15:24:54 -070099 soc_display_silicon_init_params(original_params,
100 &silicon_init_params);
101
102 /* Perform silicon initialization after RAM is configured */
103 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
104 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
105 + fsp_info_header->FspSiliconInitEntryOffset);
106 timestamp_add_now(TS_FSP_SILICON_INIT_START);
107 printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
108 &silicon_init_params, fsp_silicon_init);
Duncan Lauriefb509832015-11-22 14:53:57 -0800109 post_code(POST_FSP_SILICON_INIT);
Lee Leahy0946ec32015-04-20 15:24:54 -0700110 status = fsp_silicon_init(&silicon_init_params);
111 timestamp_add_now(TS_FSP_SILICON_INIT_END);
112 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
113
Duncan Laurie59be6242016-03-07 13:21:56 -0800114 /* Mark graphics init done after SiliconInit if VBT was provided */
Julius Wernercd49cce2019-03-05 16:53:33 -0800115#if CONFIG(RUN_FSP_GOP)
Duncan Laurie59be6242016-03-07 13:21:56 -0800116 /* GraphicsConfigPtr doesn't exist in Quark X1000's FSP, so this needs
Elyes HAOUAS2e4d8062016-08-25 20:50:50 +0200117 * to be #if'd out instead of using if (). */
Duncan Laurie59be6242016-03-07 13:21:56 -0800118 if (silicon_init_params.GraphicsConfigPtr)
119 gfx_set_init_done(1);
120#endif
121
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400122 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700123 soc_after_silicon_init();
124}
125
Aaron Durbinabf87a22015-08-05 12:26:56 -0500126static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700127{
Julius Wernercd49cce2019-03-05 16:53:33 -0800128 if (CONFIG(NO_STAGE_CACHE))
Furquan Shaikh1e162bf2016-05-06 09:20:35 -0700129 return;
130
131 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
132
Aaron Durbinabf87a22015-08-05 12:26:56 -0500133 if (prog_entry(fsp) == NULL) {
134 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700135 return;
136 }
137
Aaron Durbinabf87a22015-08-05 12:26:56 -0500138 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700139}
140
Aaron Durbinabf87a22015-08-05 12:26:56 -0500141static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700142{
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500143 if (prog_locate(fsp)) {
144 printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp));
Lee Leahy0946ec32015-04-20 15:24:54 -0700145 return -1;
146 }
147
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500148 if (fsp_relocate(fsp, prog_rdev(fsp))) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500149 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
150 return -1;
151 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700152
Lee Leahy0946ec32015-04-20 15:24:54 -0700153 return 0;
154}
155
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800156void fsp_load(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700157{
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800158 static int load_done;
Aaron Durbin7e7a4df2015-12-08 14:34:35 -0600159 struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500160 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700161
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800162 if (load_done)
163 return;
164
Julius Wernercd49cce2019-03-05 16:53:33 -0800165 if (is_s3_wakeup && !CONFIG(NO_STAGE_CACHE)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700166 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500167 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700168 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500169 fsp_find_and_relocate(&fsp);
Aaron Durbinabf87a22015-08-05 12:26:56 -0500170 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700171 }
172
Aaron Durbinabf87a22015-08-05 12:26:56 -0500173 /* FSP_INFO_HEADER is set as the program entry. */
174 fsp_update_fih(prog_entry(&fsp));
175
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800176 load_done = 1;
177}
178
179void intel_silicon_init(void)
180{
181 fsp_load();
182 fsp_run_silicon_init(fsp_get_fih(), acpi_is_wakeup_s3());
Lee Leahy0946ec32015-04-20 15:24:54 -0700183}
184
185/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600186__weak void mainboard_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700187 SILICON_INIT_UPD *params)
188{
Lee Leahy0946ec32015-04-20 15:24:54 -0700189};
190
191/* Display the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600192__weak void soc_display_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700193 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
194{
195 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
196 hexdump32(BIOS_SPEW, new, sizeof(*new));
197}
198
199/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600200__weak void soc_silicon_init_params(SILICON_INIT_UPD *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700201{
Lee Leahy0946ec32015-04-20 15:24:54 -0700202}