blob: 3be3666c26a4e118b29703e5fc58efc860ea2542 [file] [log] [blame]
/*
* This file is part of the coreboot project.
*
* Copyright 2015 Google Inc.
* Copyright (C) 2015 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.
*/
#include <cbmem.h>
#include <cbfs.h>
#include <console/console.h>
#include <fsp_util.h>
#include <romstage_handoff.h>
#include <soc/intel/common/ramstage.h>
#include <timestamp.h>
/* SOC initialization after FSP silicon init */
__attribute__((weak)) void soc_after_silicon_init(void)
{
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
}
__attribute__((weak)) void soc_save_support_code(void *start, size_t size,
void *entry)
{
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
}
__attribute__((weak)) void *soc_restore_support_code(void)
{
printk(BIOS_DEBUG, "WEAK: %s/%s called\n", __FILE__, __func__);
return NULL;
}
static void fsp_run_silicon_init(void)
{
FSP_INFO_HEADER *fsp_info_header;
FSP_SILICON_INIT fsp_silicon_init;
EFI_STATUS status;
/* Find the FSP image */
timestamp_add_now(TS_FSP_FIND_START);
fsp_info_header = fsp_get_fih();
timestamp_add_now(TS_FSP_FIND_END);
if (fsp_info_header == NULL) {
printk(BIOS_ERR, "FSP_INFO_HEADER not set!\n");
return;
}
/* Perform silicon initialization after RAM is configured */
printk(BIOS_DEBUG, "Calling FspSiliconInit\n");
fsp_silicon_init = (FSP_SILICON_INIT)(fsp_info_header->ImageBase
+ fsp_info_header->FspSiliconInitEntryOffset);
timestamp_add_now(TS_FSP_SILICON_INIT_START);
status = fsp_silicon_init(NULL);
timestamp_add_now(TS_FSP_SILICON_INIT_END);
printk(BIOS_DEBUG, "FspSiliconInit returned 0x%08x\n", status);
soc_after_silicon_init();
}
static void fsp_cache_save(void)
{
const struct cbmem_entry *fsp_entry;
FSP_INFO_HEADER *fih;
fsp_entry = cbmem_entry_find(CBMEM_ID_REFCODE);
if (fsp_entry == NULL) {
printk(BIOS_ERR, "ERROR: FSP not found in CBMEM.\n");
return;
}
fih = fsp_get_fih();
if (fih == NULL) {
printk(BIOS_ERR, "ERROR: No FIH found.\n");
return;
}
soc_save_support_code(cbmem_entry_start(fsp_entry),
cbmem_entry_size(fsp_entry), fih);
}
static int fsp_find_and_relocate(void)
{
struct cbfs_file *file;
void *fih;
file = cbfs_get_file(CBFS_DEFAULT_MEDIA, "fsp.bin");
if (file == NULL) {
printk(BIOS_ERR, "Couldn't find fsp.bin in CBFS.\n");
return -1;
}
fih = fsp_relocate(CBFS_SUBHEADER(file), ntohl(file->len));
fsp_update_fih(fih);
return 0;
}
void intel_silicon_init(void)
{
struct romstage_handoff *handoff;
handoff = cbmem_find(CBMEM_ID_ROMSTAGE_INFO);
if (handoff != NULL && handoff->s3_resume)
fsp_update_fih(soc_restore_support_code());
else {
fsp_find_and_relocate();
fsp_cache_save();
}
fsp_run_silicon_init();
}