blob: 41c0b1c312082ed5bb8142155538370ea56422b1 [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.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc.
19 */
20
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050021#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070022#include <cbmem.h>
23#include <cbfs.h>
24#include <console/console.h>
25#include <fsp_util.h>
26#include <lib.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070027#include <soc/intel/common/memmap.h>
28#include <soc/intel/common/ramstage.h>
29#include <stage_cache.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050030#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070031#include <timestamp.h>
32
33/* SOC initialization after FSP silicon init */
34__attribute__((weak)) void soc_after_silicon_init(void)
35{
36 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
37}
38
Lee Leahy0946ec32015-04-20 15:24:54 -070039/* Display SMM memory map */
40static void smm_memory_map(void)
41{
Aaron Durbinc43d4172015-08-05 14:51:48 -050042 void *base;
43 size_t size;
44 int i;
Lee Leahy0946ec32015-04-20 15:24:54 -070045
Aaron Durbinc43d4172015-08-05 14:51:48 -050046 printk(BIOS_SPEW, "SMM Memory Map\n");
Lee Leahy0946ec32015-04-20 15:24:54 -070047
Aaron Durbinc43d4172015-08-05 14:51:48 -050048 smm_region(&base, &size);
49 printk(BIOS_SPEW, "SMRAM : %p 0x%zx\n", base, size);
50
51 for (i = 0; i < SMM_SUBREGION_NUM; i++) {
52 if (smm_subregion(i, &base, &size))
53 continue;
54 printk(BIOS_SPEW, " Subregion %d: %p 0x%zx\n", i, base, size);
Lee Leahy0946ec32015-04-20 15:24:54 -070055 }
Lee Leahy0946ec32015-04-20 15:24:54 -070056}
57
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -040058static void display_hob_info(FSP_INFO_HEADER *fsp_info_header)
59{
60 const EFI_GUID graphics_info_guid = EFI_PEI_GRAPHICS_INFO_HOB_GUID;
61 int missing_hob = 0;
62 void *hob_list_ptr = get_hob_list();
63
64 if (!IS_ENABLED(CONFIG_DISPLAY_HOBS))
65 return;
66
67 /* Verify the HOBs */
68 if (hob_list_ptr == NULL) {
69 printk(BIOS_INFO, "ERROR - HOB pointer is NULL!\n");
70 return;
71 }
72
73 print_hob_type_structure(0, hob_list_ptr);
74
75 /*
76 * Verify that FSP is generating the required HOBs:
77 * 7.1: FSP_BOOTLOADER_TEMP_MEMORY_HOB only produced for FSP 1.0
78 * 7.2: FSP_RESERVED_MEMORY_RESOURCE_HOB verified by raminit
79 * 7.3: FSP_NON_VOLATILE_STORAGE_HOB verified by raminit
80 * 7.4: FSP_BOOTLOADER_TOLUM_HOB verified by raminit
81 * 7.5: EFI_PEI_GRAPHICS_INFO_HOB verified below,
82 * if the ImageAttribute bit is set
83 * FSP_SMBIOS_MEMORY_INFO HOB verified by raminit
84 */
85 if ((fsp_info_header->ImageAttribute & GRAPHICS_SUPPORT_BIT) &&
86 !get_next_guid_hob(&graphics_info_guid, hob_list_ptr)) {
87 printk(BIOS_INFO, "7.5: EFI_PEI_GRAPHICS_INFO_HOB missing!\n");
88 missing_hob = 1;
89 }
90
91 if (missing_hob)
92 printk(BIOS_INFO,
93 "ERROR - Missing one or more required FSP HOBs!\n");
94}
95
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050096static void fsp_run_silicon_init(int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070097{
98 FSP_INFO_HEADER *fsp_info_header;
99 FSP_SILICON_INIT fsp_silicon_init;
100 SILICON_INIT_UPD *original_params;
101 SILICON_INIT_UPD silicon_init_params;
102 EFI_STATUS status;
103 UPD_DATA_REGION *upd_ptr;
104 VPD_DATA_REGION *vpd_ptr;
105
106 /* Find the FSP image */
107 fsp_info_header = fsp_get_fih();
108 if (fsp_info_header == NULL) {
109 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
110 return;
111 }
112 print_fsp_info(fsp_info_header);
113
114 /* Initialize the UPD values */
115 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
116 fsp_info_header->ImageBase);
117 printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
118 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
119 fsp_info_header->ImageBase);
120 printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
121 original_params = (void *)((u8 *)upd_ptr +
122 upd_ptr->SiliconInitUpdOffset);
123 memcpy(&silicon_init_params, original_params,
124 sizeof(silicon_init_params));
125 soc_silicon_init_params(&silicon_init_params);
126
127 /* Locate VBT and pass to FSP GOP */
128 if (IS_ENABLED(CONFIG_GOP_SUPPORT))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500129 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700130 mainboard_silicon_init_params(&silicon_init_params);
131
132 /* Display the UPD data */
133 if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
134 soc_display_silicon_init_params(original_params,
135 &silicon_init_params);
136
137 /* Perform silicon initialization after RAM is configured */
138 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
139 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
140 + fsp_info_header->FspSiliconInitEntryOffset);
141 timestamp_add_now(TS_FSP_SILICON_INIT_START);
142 printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
143 &silicon_init_params, fsp_silicon_init);
144 status = fsp_silicon_init(&silicon_init_params);
145 timestamp_add_now(TS_FSP_SILICON_INIT_END);
146 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
147
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400148 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700149 soc_after_silicon_init();
150}
151
Aaron Durbinabf87a22015-08-05 12:26:56 -0500152static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700153{
Aaron Durbinabf87a22015-08-05 12:26:56 -0500154 if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
155 smm_memory_map();
Lee Leahy0946ec32015-04-20 15:24:54 -0700156
Aaron Durbinabf87a22015-08-05 12:26:56 -0500157 if (prog_entry(fsp) == NULL) {
158 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700159 return;
160 }
161
Aaron Durbinabf87a22015-08-05 12:26:56 -0500162 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700163}
164
Aaron Durbinabf87a22015-08-05 12:26:56 -0500165static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700166{
Aaron Durbin22ea0072015-08-05 10:17:33 -0500167 struct region_device fsp_rdev;
168 uint32_t type = CBFS_TYPE_FSP;
Lee Leahy0946ec32015-04-20 15:24:54 -0700169
Aaron Durbinabf87a22015-08-05 12:26:56 -0500170 if (cbfs_boot_locate(&fsp_rdev, prog_name(fsp), &type)) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500171 printk(BIOS_ERR, "ERROR: Couldn't find fsp.bin in CBFS.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700172 return -1;
173 }
174
Aaron Durbinabf87a22015-08-05 12:26:56 -0500175 if (fsp_relocate(fsp, &fsp_rdev)) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500176 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
177 return -1;
178 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700179
Lee Leahy0946ec32015-04-20 15:24:54 -0700180 return 0;
181}
182
183void intel_silicon_init(void)
184{
Aaron Durbinabf87a22015-08-05 12:26:56 -0500185 struct prog fsp = PROG_INIT(ASSET_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500186 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700187
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500188 if (is_s3_wakeup) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700189 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500190 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700191 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500192 fsp_find_and_relocate(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700193 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500194 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700195 }
196
Aaron Durbinabf87a22015-08-05 12:26:56 -0500197 /* FSP_INFO_HEADER is set as the program entry. */
198 fsp_update_fih(prog_entry(&fsp));
199
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500200 fsp_run_silicon_init(is_s3_wakeup);
Lee Leahy0946ec32015-04-20 15:24:54 -0700201}
202
203/* Initialize the UPD parameters for SiliconInit */
204__attribute__((weak)) void mainboard_silicon_init_params(
205 SILICON_INIT_UPD *params)
206{
207 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
208};
209
210/* Display the UPD parameters for SiliconInit */
211__attribute__((weak)) void soc_display_silicon_init_params(
212 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
213{
214 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
215 hexdump32(BIOS_SPEW, new, sizeof(*new));
216}
217
218/* Initialize the UPD parameters for SiliconInit */
219__attribute__((weak)) void soc_silicon_init_params(SILICON_INIT_UPD *params)
220{
221 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
222}