blob: dd1abbeab78475a59bb22de7bf616707eefebd70 [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 <cbmem.h>
20#include <cbfs.h>
21#include <console/console.h>
Lee Leahy94b856e2015-10-15 12:07:03 -070022#include <fsp/memmap.h>
23#include <fsp/ramstage.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050024#include <fsp/util.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070025#include <lib.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070026#include <stage_cache.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050027#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070028#include <timestamp.h>
29
30/* SOC initialization after FSP silicon init */
31__attribute__((weak)) void soc_after_silicon_init(void)
32{
Lee Leahy0946ec32015-04-20 15:24:54 -070033}
34
Lee Leahy0946ec32015-04-20 15:24:54 -070035/* Display SMM memory map */
36static void smm_memory_map(void)
37{
Aaron Durbinc43d4172015-08-05 14:51:48 -050038 void *base;
39 size_t size;
40 int i;
Lee Leahy0946ec32015-04-20 15:24:54 -070041
Aaron Durbinc43d4172015-08-05 14:51:48 -050042 printk(BIOS_SPEW, "SMM Memory Map\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070043
Aaron Durbinc43d4172015-08-05 14:51:48 -050044 smm_region(&base, &size);
45 printk(BIOS_SPEW, "SMRAM : %p 0x%zx\n", base, size);
46
47 for (i = 0; i < SMM_SUBREGION_NUM; i++) {
48 if (smm_subregion(i, &base, &size))
49 continue;
50 printk(BIOS_SPEW, " Subregion %d: %p 0x%zx\n", i, base, size);
Lee Leahy0946ec32015-04-20 15:24:54 -070051 }
Lee Leahy0946ec32015-04-20 15:24:54 -070052}
53
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040054static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
55{
56 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
57 int missing_hob = 0;
58 void *hob_list_ptr = get_hob_list();
59
60 if (!IS_ENABLED(CONFIG_DISPLAY_HOBS))
61 return;
62
63 /* Verify the HOBs */
64 if (hob_list_ptr == NULL) {
65 printk(BIOS_INFO, "ERROR - HOB pointer is NULL!\n");
66 return;
67 }
68
69 print_hob_type_structure(0, hob_list_ptr);
70
71 /*
72 * Verify that FSP is generating the required HOBs:
73 * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
74 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
75 * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
76 * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
77 * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
78 * if the ImageAttribute bit is set
79 * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
80 */
81 if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
82 !get_next_guid_hob(&graphics_info_guid, hob_list_ptr)) {
83 printk(BIOS_INFO, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
84 missing_hob = 1;
85 }
86
87 if (missing_hob)
88 printk(BIOS_INFO,
89 "ERROR - Missing one or more required FSP HOBs!\n");
90}
91
Lee Leahycff5f092016-02-08 08:37:53 -080092void fsp_run_silicon_init(FSP_INFO_HEADER *fsp_info_header, int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070093{
Lee Leahy0946ec32015-04-20 15:24:54 -070094 FSP_SILICON_INIT fsp_silicon_init;
95 SILICON_INIT_UPD *original_params;
96 SILICON_INIT_UPD silicon_init_params;
97 EFI_STATUS status;
98 UPD_DATA_REGION *upd_ptr;
99 VPD_DATA_REGION *vpd_ptr;
100
Lee Leahycff5f092016-02-08 08:37:53 -0800101 /* Display the FSP header */
Lee Leahy0946ec32015-04-20 15:24:54 -0700102 if (fsp_info_header == NULL) {
103 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
104 return;
105 }
106 print_fsp_info(fsp_info_header);
107
108 /* Initialize the UPD values */
109 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
110 fsp_info_header->ImageBase);
111 printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
112 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
113 fsp_info_header->ImageBase);
114 printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
115 original_params = (void *)((u8 *)upd_ptr +
116 upd_ptr->SiliconInitUpdOffset);
117 memcpy(&silicon_init_params, original_params,
118 sizeof(silicon_init_params));
119 soc_silicon_init_params(&silicon_init_params);
120
121 /* Locate VBT and pass to FSP GOP */
122 if (IS_ENABLED(CONFIG_GOP_SUPPORT))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500123 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700124 mainboard_silicon_init_params(&silicon_init_params);
125
126 /* Display the UPD data */
127 if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
128 soc_display_silicon_init_params(original_params,
129 &silicon_init_params);
130
131 /* Perform silicon initialization after RAM is configured */
132 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
133 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
134 + fsp_info_header->FspSiliconInitEntryOffset);
135 timestamp_add_now(TS_FSP_SILICON_INIT_START);
136 printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
137 &silicon_init_params, fsp_silicon_init);
Duncan Lauriefb509832015-11-22 14:53:57 -0800138 post_code(POST_FSP_SILICON_INIT);
Lee Leahy0946ec32015-04-20 15:24:54 -0700139 status = fsp_silicon_init(&silicon_init_params);
140 timestamp_add_now(TS_FSP_SILICON_INIT_END);
141 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
142
Duncan Laurie59be6242016-03-07 13:21:56 -0800143 /* Mark graphics init done after SiliconInit if VBT was provided */
144#if IS_ENABLED(CONFIG_GOP_SUPPORT)
145 /* GraphicsConfigPtr doesn't exist in Quark X1000's FSP, so this needs
Elyes HAOUAS2e4d8062016-08-25 20:50:50 +0200146 * to be #if'd out instead of using if (). */
Duncan Laurie59be6242016-03-07 13:21:56 -0800147 if (silicon_init_params.GraphicsConfigPtr)
148 gfx_set_init_done(1);
149#endif
150
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400151 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700152 soc_after_silicon_init();
153}
154
Aaron Durbinabf87a22015-08-05 12:26:56 -0500155static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700156{
Aaron Durbinabf87a22015-08-05 12:26:56 -0500157 if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
158 smm_memory_map();
Lee Leahy0946ec32015-04-20 15:24:54 -0700159
Furquan Shaikh1e162bf2016-05-06 09:20:35 -0700160 if (IS_ENABLED(CONFIG_NO_STAGE_CACHE))
161 return;
162
163 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
164
Aaron Durbinabf87a22015-08-05 12:26:56 -0500165 if (prog_entry(fsp) == NULL) {
166 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700167 return;
168 }
169
Aaron Durbinabf87a22015-08-05 12:26:56 -0500170 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700171}
172
Aaron Durbinabf87a22015-08-05 12:26:56 -0500173static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700174{
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500175 if (prog_locate(fsp)) {
176 printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp));
Lee Leahy0946ec32015-04-20 15:24:54 -0700177 return -1;
178 }
179
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500180 if (fsp_relocate(fsp, prog_rdev(fsp))) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500181 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
182 return -1;
183 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700184
Lee Leahy0946ec32015-04-20 15:24:54 -0700185 return 0;
186}
187
188void intel_silicon_init(void)
189{
Aaron Durbin7e7a4df2015-12-08 14:34:35 -0600190 struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500191 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700192
Furquan Shaikh1e162bf2016-05-06 09:20:35 -0700193 if (is_s3_wakeup && !IS_ENABLED(CONFIG_NO_STAGE_CACHE)) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700194 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500195 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700196 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500197 fsp_find_and_relocate(&fsp);
Aaron Durbinabf87a22015-08-05 12:26:56 -0500198 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700199 }
200
Aaron Durbinabf87a22015-08-05 12:26:56 -0500201 /* FSP_INFO_HEADER is set as the program entry. */
202 fsp_update_fih(prog_entry(&fsp));
203
Lee Leahycff5f092016-02-08 08:37:53 -0800204 fsp_run_silicon_init(fsp_get_fih(), is_s3_wakeup);
Lee Leahy0946ec32015-04-20 15:24:54 -0700205}
206
207/* Initialize the UPD parameters for SiliconInit */
208__attribute__((weak)) void mainboard_silicon_init_params(
209 SILICON_INIT_UPD *params)
210{
Lee Leahy0946ec32015-04-20 15:24:54 -0700211};
212
213/* Display the UPD parameters for SiliconInit */
214__attribute__((weak)) void soc_display_silicon_init_params(
215 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
216{
217 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
218 hexdump32(BIOS_SPEW, new, sizeof(*new));
219}
220
221/* Initialize the UPD parameters for SiliconInit */
222__attribute__((weak)) void soc_silicon_init_params(SILICON_INIT_UPD *params)
223{
Lee Leahy0946ec32015-04-20 15:24:54 -0700224}