blob: 52a886ce309756d0486d415c076068fc5b8fce53 [file] [log] [blame]
Lee Leahy0946ec32015-04-20 15:24:54 -07001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright 2015 Google Inc.
5 * Copyright (C) 2015 Intel Corporation.
6 *
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 Leahy0946ec32015-04-20 15:24:54 -070015 */
16
Duncan Laurie59be6242016-03-07 13:21:56 -080017#include <bootmode.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050018#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070019#include <console/console.h>
Lee Leahy94b856e2015-10-15 12:07:03 -070020#include <fsp/memmap.h>
21#include <fsp/ramstage.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050022#include <fsp/util.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070023#include <lib.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070024#include <stage_cache.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050025#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070026#include <timestamp.h>
27
28/* SOC initialization after FSP silicon init */
Aaron Durbin64031672018-04-21 14:45:32 -060029__weak void soc_after_silicon_init(void)
Lee Leahy0946ec32015-04-20 15:24:54 -070030{
Lee Leahy0946ec32015-04-20 15:24:54 -070031}
32
Lee Leahy0946ec32015-04-20 15:24:54 -070033/* Display SMM memory map */
34static void smm_memory_map(void)
35{
Aaron Durbinc43d4172015-08-05 14:51:48 -050036 void *base;
37 size_t size;
38 int i;
Lee Leahy0946ec32015-04-20 15:24:54 -070039
Aaron Durbinc43d4172015-08-05 14:51:48 -050040 printk(BIOS_SPEW, "SMM Memory Map\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070041
Aaron Durbinc43d4172015-08-05 14:51:48 -050042 smm_region(&base, &size);
43 printk(BIOS_SPEW, "SMRAM : %p 0x%zx\n", base, size);
44
45 for (i = 0; i < SMM_SUBREGION_NUM; i++) {
46 if (smm_subregion(i, &base, &size))
47 continue;
48 printk(BIOS_SPEW, " Subregion %d: %p 0x%zx\n", i, base, size);
Lee Leahy0946ec32015-04-20 15:24:54 -070049 }
Lee Leahy0946ec32015-04-20 15:24:54 -070050}
51
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040052static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
53{
54 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040055 void *hob_list_ptr = get_hob_list();
56
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040057 /* Verify the HOBs */
58 if (hob_list_ptr == NULL) {
Frans Hendriks509f4692019-06-28 14:11:41 +020059 printk(BIOS_ERR, "ERROR - HOB pointer is NULL!\n");
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040060 return;
61 }
62
Frans Hendriks509f4692019-06-28 14:11:41 +020063 if (CONFIG(DISPLAY_HOBS))
64 print_hob_type_structure(0, hob_list_ptr);
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040065
66 /*
67 * Verify that FSP is generating the required HOBs:
68 * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
69 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
70 * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
71 * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
72 * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
73 * if the ImageAttribute bit is set
74 * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
75 */
76 if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
Frans Hendriks509f4692019-06-28 14:11:41 +020077 !get_next_guid_hob(&graphics_info_guid, hob_list_ptr) &&
78 CONFIG(DISPLAY_HOBS)) {
79 printk(BIOS_ERR, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
80 printk(BIOS_ERR,
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040081 "ERROR - Missing one or more required FSP HOBs!\n");
Frans Hendriks509f4692019-06-28 14:11:41 +020082 }
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040083}
84
Lee Leahycff5f092016-02-08 08:37:53 -080085void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070086{
Lee Leahy0946ec32015-04-20 15:24:54 -070087 FSP_SILICON_INIT fsp_silicon_init;
88 SILICON_INIT_UPD *original_params;
89 SILICON_INIT_UPD silicon_init_params;
90 EFI_STATUS status;
91 UPD_DATA_REGION *upd_ptr;
92 VPD_DATA_REGION *vpd_ptr;
93
Lee Leahycff5f092016-02-08 08:37:53 -080094 /* Display the FSP header */
Lee Leahy0946ec32015-04-20 15:24:54 -070095 if (fsp_info_header == NULL) {
96 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
97 return;
98 }
99 print_fsp_info(fsp_info_header);
100
101 /* Initialize the UPD values */
102 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
103 fsp_info_header->ImageBase);
104 printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
105 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
106 fsp_info_header->ImageBase);
107 printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
108 original_params = (void *)((u8 *)upd_ptr +
109 upd_ptr->SiliconInitUpdOffset);
110 memcpy(&silicon_init_params, original_params,
111 sizeof(silicon_init_params));
112 soc_silicon_init_params(&silicon_init_params);
113
114 /* Locate VBT and pass to FSP GOP */
Julius Wernercd49cce2019-03-05 16:53:33 -0800115 if (CONFIG(RUN_FSP_GOP))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500116 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700117 mainboard_silicon_init_params(&silicon_init_params);
118
119 /* Display the UPD data */
Julius Wernercd49cce2019-03-05 16:53:33 -0800120 if (CONFIG(DISPLAY_UPD_DATA))
Lee Leahy0946ec32015-04-20 15:24:54 -0700121 soc_display_silicon_init_params(original_params,
122 &silicon_init_params);
123
124 /* Perform silicon initialization after RAM is configured */
125 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
126 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
127 + fsp_info_header->FspSiliconInitEntryOffset);
128 timestamp_add_now(TS_FSP_SILICON_INIT_START);
129 printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
130 &silicon_init_params, fsp_silicon_init);
Duncan Lauriefb509832015-11-22 14:53:57 -0800131 post_code(POST_FSP_SILICON_INIT);
Lee Leahy0946ec32015-04-20 15:24:54 -0700132 status = fsp_silicon_init(&silicon_init_params);
133 timestamp_add_now(TS_FSP_SILICON_INIT_END);
134 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
135
Duncan Laurie59be6242016-03-07 13:21:56 -0800136 /* Mark graphics init done after SiliconInit if VBT was provided */
Julius Wernercd49cce2019-03-05 16:53:33 -0800137#if CONFIG(RUN_FSP_GOP)
Duncan Laurie59be6242016-03-07 13:21:56 -0800138 /* GraphicsConfigPtr doesn't exist in Quark X1000's FSP, so this needs
Elyes HAOUAS2e4d8062016-08-25 20:50:50 +0200139 * to be #if'd out instead of using if (). */
Duncan Laurie59be6242016-03-07 13:21:56 -0800140 if (silicon_init_params.GraphicsConfigPtr)
141 gfx_set_init_done(1);
142#endif
143
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400144 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700145 soc_after_silicon_init();
146}
147
Aaron Durbinabf87a22015-08-05 12:26:56 -0500148static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700149{
Julius Wernercd49cce2019-03-05 16:53:33 -0800150 if (CONFIG(DISPLAY_SMM_MEMORY_MAP))
Aaron Durbinabf87a22015-08-05 12:26:56 -0500151 smm_memory_map();
Lee Leahy0946ec32015-04-20 15:24:54 -0700152
Julius Wernercd49cce2019-03-05 16:53:33 -0800153 if (CONFIG(NO_STAGE_CACHE))
Furquan Shaikh1e162bf2016-05-06 09:20:35 -0700154 return;
155
156 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
157
Aaron Durbinabf87a22015-08-05 12:26:56 -0500158 if (prog_entry(fsp) == NULL) {
159 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700160 return;
161 }
162
Aaron Durbinabf87a22015-08-05 12:26:56 -0500163 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700164}
165
Aaron Durbinabf87a22015-08-05 12:26:56 -0500166static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700167{
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500168 if (prog_locate(fsp)) {
169 printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp));
Lee Leahy0946ec32015-04-20 15:24:54 -0700170 return -1;
171 }
172
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500173 if (fsp_relocate(fsp, prog_rdev(fsp))) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500174 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
175 return -1;
176 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700177
Lee Leahy0946ec32015-04-20 15:24:54 -0700178 return 0;
179}
180
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800181void fsp_load(void)
Lee Leahy0946ec32015-04-20 15:24:54 -0700182{
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800183 static int load_done;
Aaron Durbin7e7a4df2015-12-08 14:34:35 -0600184 struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500185 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700186
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800187 if (load_done)
188 return;
189
Julius Wernercd49cce2019-03-05 16:53:33 -0800190 if (is_s3_wakeup && !CONFIG(NO_STAGE_CACHE)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700191 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500192 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700193 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500194 fsp_find_and_relocate(&fsp);
Aaron Durbinabf87a22015-08-05 12:26:56 -0500195 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700196 }
197
Aaron Durbinabf87a22015-08-05 12:26:56 -0500198 /* FSP_INFO_HEADER is set as the program entry. */
199 fsp_update_fih(prog_entry(&fsp));
200
Furquan Shaikhf4b20af2017-02-20 13:33:32 -0800201 load_done = 1;
202}
203
204void intel_silicon_init(void)
205{
206 fsp_load();
207 fsp_run_silicon_init(fsp_get_fih(), acpi_is_wakeup_s3());
Lee Leahy0946ec32015-04-20 15:24:54 -0700208}
209
210/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600211__weak void mainboard_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700212 SILICON_INIT_UPD *params)
213{
Lee Leahy0946ec32015-04-20 15:24:54 -0700214};
215
216/* Display the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600217__weak void soc_display_silicon_init_params(
Lee Leahy0946ec32015-04-20 15:24:54 -0700218 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
219{
220 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
221 hexdump32(BIOS_SPEW, new, sizeof(*new));
222}
223
224/* Initialize the UPD parameters for SiliconInit */
Aaron Durbin64031672018-04-21 14:45:32 -0600225__weak void soc_silicon_init_params(SILICON_INIT_UPD *params)
Lee Leahy0946ec32015-04-20 15:24:54 -0700226{
Lee Leahy0946ec32015-04-20 15:24:54 -0700227}