blob: aa1b6580683a0104d6d2245f8b487561e9476594 [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
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050017#include <arch/acpi.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070018#include <cbmem.h>
19#include <cbfs.h>
20#include <console/console.h>
Lee Leahy94b856e2015-10-15 12:07:03 -070021#include <fsp/memmap.h>
22#include <fsp/ramstage.h>
Aaron Durbin789f2b62015-09-09 17:05:06 -050023#include <fsp/util.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070024#include <lib.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070025#include <stage_cache.h>
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050026#include <string.h>
Lee Leahy0946ec32015-04-20 15:24:54 -070027#include <timestamp.h>
28
29/* SOC initialization after FSP silicon init */
30__attribute__((weak)) void soc_after_silicon_init(void)
31{
32 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
33}
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
Aaron Durbin39bdb0b2015-08-04 23:59:43 -050092static void fsp_run_silicon_init(int is_s3_wakeup)
Lee Leahy0946ec32015-04-20 15:24:54 -070093{
94 FSP_INFO_HEADER *fsp_info_header;
95 FSP_SILICON_INIT fsp_silicon_init;
96 SILICON_INIT_UPD *original_params;
97 SILICON_INIT_UPD silicon_init_params;
98 EFI_STATUS status;
99 UPD_DATA_REGION *upd_ptr;
100 VPD_DATA_REGION *vpd_ptr;
101
102 /* Find the FSP image */
103 fsp_info_header = fsp_get_fih();
104 if (fsp_info_header == NULL) {
105 printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
106 return;
107 }
108 print_fsp_info(fsp_info_header);
109
110 /* Initialize the UPD values */
111 vpd_ptr = (VPD_DATA_REGION *)(fsp_info_header->CfgRegionOffset +
112 fsp_info_header->ImageBase);
113 printk(BIOS_DEBUG, "0x%p: VPD Data\n", vpd_ptr);
114 upd_ptr = (UPD_DATA_REGION *)(vpd_ptr->PcdUpdRegionOffset +
115 fsp_info_header->ImageBase);
116 printk(BIOS_DEBUG, "0x%p: UPD Data\n", upd_ptr);
117 original_params = (void *)((u8 *)upd_ptr +
118 upd_ptr->SiliconInitUpdOffset);
119 memcpy(&silicon_init_params, original_params,
120 sizeof(silicon_init_params));
121 soc_silicon_init_params(&silicon_init_params);
122
123 /* Locate VBT and pass to FSP GOP */
124 if (IS_ENABLED(CONFIG_GOP_SUPPORT))
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500125 load_vbt(is_s3_wakeup, &silicon_init_params);
Lee Leahy0946ec32015-04-20 15:24:54 -0700126 mainboard_silicon_init_params(&silicon_init_params);
127
128 /* Display the UPD data */
129 if (IS_ENABLED(CONFIG_DISPLAY_UPD_DATA))
130 soc_display_silicon_init_params(original_params,
131 &silicon_init_params);
132
133 /* Perform silicon initialization after RAM is configured */
134 printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
135 fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
136 + fsp_info_header->FspSiliconInitEntryOffset);
137 timestamp_add_now(TS_FSP_SILICON_INIT_START);
138 printk(BIOS_DEBUG, "Calling FspSiliconInit(0x%p) at 0x%p\n",
139 &silicon_init_params, fsp_silicon_init);
Duncan Lauriefb509832015-11-22 14:53:57 -0800140 post_code(POST_FSP_SILICON_INIT);
Lee Leahy0946ec32015-04-20 15:24:54 -0700141 status = fsp_silicon_init(&silicon_init_params);
142 timestamp_add_now(TS_FSP_SILICON_INIT_END);
143 printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
144
Alexandru Gagniuc41c003c2015-08-28 19:07:35 -0400145 display_hob_info(fsp_info_header);
Lee Leahy0946ec32015-04-20 15:24:54 -0700146 soc_after_silicon_init();
147}
148
Aaron Durbinabf87a22015-08-05 12:26:56 -0500149static void fsp_cache_save(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700150{
Aaron Durbinabf87a22015-08-05 12:26:56 -0500151 if (IS_ENABLED(CONFIG_DISPLAY_SMM_MEMORY_MAP))
152 smm_memory_map();
Lee Leahy0946ec32015-04-20 15:24:54 -0700153
Aaron Durbinabf87a22015-08-05 12:26:56 -0500154 if (prog_entry(fsp) == NULL) {
155 printk(BIOS_ERR, "ERROR: No FSP to save in cache.\n");
Lee Leahy0946ec32015-04-20 15:24:54 -0700156 return;
157 }
158
Aaron Durbinabf87a22015-08-05 12:26:56 -0500159 stage_cache_add(STAGE_REFCODE, fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700160}
161
Aaron Durbinabf87a22015-08-05 12:26:56 -0500162static int fsp_find_and_relocate(struct prog *fsp)
Lee Leahy0946ec32015-04-20 15:24:54 -0700163{
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500164 if (prog_locate(fsp)) {
165 printk(BIOS_ERR, "ERROR: Couldn't find %s\n", prog_name(fsp));
Lee Leahy0946ec32015-04-20 15:24:54 -0700166 return -1;
167 }
168
Aaron Durbin5d6f0f92015-10-08 15:06:28 -0500169 if (fsp_relocate(fsp, prog_rdev(fsp))) {
Aaron Durbin22ea0072015-08-05 10:17:33 -0500170 printk(BIOS_ERR, "ERROR: FSP relocation failed.\n");
171 return -1;
172 }
Lee Leahy0946ec32015-04-20 15:24:54 -0700173
Lee Leahy0946ec32015-04-20 15:24:54 -0700174 return 0;
175}
176
177void intel_silicon_init(void)
178{
Aaron Durbinabf87a22015-08-05 12:26:56 -0500179 struct prog fsp = PROG_INIT(ASSET_REFCODE, "fsp.bin");
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500180 int is_s3_wakeup = acpi_is_wakeup_s3();
Lee Leahy0946ec32015-04-20 15:24:54 -0700181
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500182 if (is_s3_wakeup) {
Lee Leahy0946ec32015-04-20 15:24:54 -0700183 printk(BIOS_DEBUG, "FSP: Loading binary from cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500184 stage_cache_load_stage(STAGE_REFCODE, &fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700185 } else {
Aaron Durbinabf87a22015-08-05 12:26:56 -0500186 fsp_find_and_relocate(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700187 printk(BIOS_DEBUG, "FSP: Saving binary in cache\n");
Aaron Durbinabf87a22015-08-05 12:26:56 -0500188 fsp_cache_save(&fsp);
Lee Leahy0946ec32015-04-20 15:24:54 -0700189 }
190
Aaron Durbinabf87a22015-08-05 12:26:56 -0500191 /* FSP_INFO_HEADER is set as the program entry. */
192 fsp_update_fih(prog_entry(&fsp));
193
Aaron Durbin39bdb0b2015-08-04 23:59:43 -0500194 fsp_run_silicon_init(is_s3_wakeup);
Lee Leahy0946ec32015-04-20 15:24:54 -0700195}
196
197/* Initialize the UPD parameters for SiliconInit */
198__attribute__((weak)) void mainboard_silicon_init_params(
199 SILICON_INIT_UPD *params)
200{
201 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
202};
203
204/* Display the UPD parameters for SiliconInit */
205__attribute__((weak)) void soc_display_silicon_init_params(
206 const SILICON_INIT_UPD *old, SILICON_INIT_UPD *new)
207{
208 printk(BIOS_SPEW, "UPD values for SiliconInit:\n");
209 hexdump32(BIOS_SPEW, new, sizeof(*new));
210}
211
212/* Initialize the UPD parameters for SiliconInit */
213__attribute__((weak)) void soc_silicon_init_params(SILICON_INIT_UPD *params)
214{
215 printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
216}