Broadwell FSP: Successful execution of TempRamInit

During execution, src/soc/intel/broadwell/romstage/fsp_1_1.inc calls
src/soc/intel/fsp/fsp_util.c/find_fsp, added in change list 229573,
to locate the FSP binary in CBFS.  Determine the TempRamInit entry point
and call TempRamInit.  After returning, fsp_1_1.inc calls into
src/soc/intel/broadwell/romstage/romstage.c/romstage_main.

BRANCH=none
BUG=None
TEST=Use the following steps to reproduce:
1.  Get the private FSP parts: internal 187295
2.  Copy configs/config.samus.fsp to configs/config.samus
3.  Build and run on Samus
4.  After power on, POST code should be 0x35 if successful, hangs in
    src/soc/intel/broadwell/romstage/romstage.c/romstage_main

Change-Id: Id7d17b7b46e73a7b6b4dae6ee859016dab6e6d6f
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: https://chromium-review.googlesource.com/234140
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
This commit is contained in:
Lee Leahy 2014-11-17 11:58:24 -08:00 committed by chrome-internal-fetch
commit dbcbbcdff2
16 changed files with 1251 additions and 418 deletions

View file

@ -18,3 +18,4 @@
##
source src/drivers/intel/gma/Kconfig
source src/drivers/intel/fsp/Kconfig

View file

@ -17,12 +17,17 @@
## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
##
if PLATFORM_USES_FSP
comment "Intel FSP"
config HAVE_FSP_BIN
config PLATFORM_USES_FSP
bool "Use Intel Firmware Support Package"
help
Does the code require the Intel Firmware Support Package?
if PLATFORM_USES_FSP
config HAVE_FSP_BIN
bool "Should the Intel FSP binary be added to the flash image"
help
Select this option to add an Intel FSP binary to
the resulting coreboot image.
@ -30,6 +35,12 @@ config HAVE_FSP_BIN
Note: Without this binary, coreboot builds relying on the FSP
will not boot
config USING_FSP_1_0
bool "Code uses FSP 1.0 API"
default n
help
Select this option to use the FSP 1.0 API.
config DCACHE_RAM_BASE
hex
default 0xfef00000
@ -45,6 +56,23 @@ config FSP_FILE
help
The path and filename of the Intel FSP binary for this platform.
config FSP_INCLUDE_PATH
string "Path for FSP specific include files"
help
The path and filename of the Intel FSP binary for this platform.
config FSP_IMAGE_ID_DWORD0
hex "First 4 bytes of 8 byte platform string"
help
The first four bytes of the eight byte platform specific string
used to identify the FSP binary that should be used.
config FSP_IMAGE_ID_DWORD1
hex "Second 4 bytes of 8 byte platform string"
help
The second four bytes of the eight byte platform specific string
used to identify the FSP binary that should be used.
config FSP_LOC
hex "Intel FSP Binary location in CBFS"
help
@ -52,6 +80,13 @@ config FSP_LOC
value that is set in the FSP binary. If the FSP needs to be moved,
rebase the FSP with Intel's BCT (tool).
config FSP_RESERVED_MEM_SIZE
hex "FSP Reserved Memory"
default 0x00100000
help
Memory size in bytes reserved by FSP between PEI Memory and the
base of TSEG.
config ENABLE_FSP_FAST_BOOT
bool "Enable Fast Boot"
select ENABLE_MRC_CACHE
@ -70,6 +105,11 @@ config ENABLE_MRC_CACHE
This can either be used for fast boot, or just because the FSP wants
it to be saved.
config MRC_CACHE_FILE
string "File containing the cached MRC values"
help
The path and filename of the cached MRC values.
config MRC_CACHE_SIZE
hex "Fast Boot Data Cache Size"
default 0x10000
@ -119,6 +159,19 @@ config VIRTUAL_ROM_SIZE
the SPI ROMs are loaded with an 8 MB coreboot image, the virtual ROM
size is 16 MB.
config CPU_MICROCODE_CBFS_LEN
hex "Microcode update region length in bytes"
default 0
help
The length in bytes of the microcode update region.
config CPU_MICROCODE_CBFS_LOC
hex "Microcode update base address in CBFS"
default 0
help
The location (base address) in CBFS that contains the microcode update
binary.
endif #HAVE_FSP_BIN
config CACHE_ROM_SIZE_OVERRIDE
@ -142,4 +195,13 @@ config FSP_USES_UPD
default n
help
If this FSP uses UPD/VPD data regions, select this in the chipset Kconfig.
config POST_IO
bool
default y
config POST_IO_PORT
hex
default 0x80
endif #PLATFORM_USES_FSP

View file

@ -19,8 +19,11 @@
ramstage-y += fsp_util.c
romstage-y += fsp_util.c
romstage-$(CONFIG_USING_FSP_1_0) += fsp_util_1_0.c
ramstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
romstage-$(CONFIG_ENABLE_MRC_CACHE) += fastboot_cache.c
romstage-y += fsp_hob.c
ramstage-y += fsp_hob.c
CPPFLAGS_common += -Isrc/drivers/intel/fsp
@ -35,14 +38,14 @@ fsp.bin-position := $(CONFIG_FSP_LOC)
fsp.bin-type := 0xab
endif
ifeq ($(CONFIG_ENABLE_MRC_CACHE),y)
ifeq ($(CONFIG_ENABLE_MRC_CACHE_FILE),y)
$(obj)/mrc.cache:
dd if=/dev/zero count=1 \
bs=$(shell printf "%d" $(CONFIG_MRC_CACHE_SIZE) ) | \
tr '\000' '\377' > $@
cbfs-files-y += mrc.cache
mrc.cache-file := $(obj)/mrc.cache
mrc.cache-file := $(call strip_quotes,$(CONFIG_MRC_CACHE_FILE))
mrc.cache-position := $(CONFIG_MRC_CACHE_LOC)
mrc.cache-type := 0xac
endif

View file

@ -36,8 +36,9 @@
#endif
/* convert a pointer to flash area into the offset inside the flash */
static inline u32 to_flash_offset(void *p) {
return ((u32)p + CONFIG_VIRTUAL_ROM_SIZE);
static inline u32 to_flash_offset(void *p)
{
return (u32)p + CONFIG_VIRTUAL_ROM_SIZE;
}
static struct mrc_data_container *next_mrc_block(
@ -50,24 +51,35 @@ static struct mrc_data_container *next_mrc_block(
mrc_size += MRC_DATA_ALIGN;
}
u8 *region_ptr = (u8*)mrc_cache;
u8 *region_ptr = (u8 *)mrc_cache;
region_ptr += mrc_size;
return (struct mrc_data_container *)region_ptr;
}
static int is_mrc_cache(struct mrc_data_container *mrc_cache)
{
return (!!mrc_cache) && (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
return (!!mrc_cache)
&& (mrc_cache->mrc_signature == MRC_DATA_SIGNATURE);
}
static u32 get_mrc_cache_region(struct mrc_data_container **mrc_region_ptr)
{
size_t region_size;
*mrc_region_ptr = cbfs_get_file_content(CBFS_DEFAULT_MEDIA,
"mrc.cache", 0xac,
&region_size);
const char *name = "mrc.cache";
int type = 0xac;
struct cbfs_file *file = cbfs_get_file(CBFS_DEFAULT_MEDIA, name);
return region_size;
if (file == NULL) {
printk(BIOS_ERR, "Could not find file '%s'.\n", name);
return 0;
}
if (ntohl(file->type) != type) {
printk(BIOS_ERR, "File '%s' is of type %x, but we requested %x.\n",
name, ntohl(file->type), type);
return 0;
}
return ntohl(file->len);
}
/*
@ -95,7 +107,8 @@ static struct mrc_data_container *find_current_mrc_cache_local
}
if (entry_id == 0) {
printk(BIOS_ERR, "%s: No valid fast boot cache found.\n", __func__);
printk(BIOS_ERR, "%s: No valid fast boot cache found.\n",
__func__);
return NULL;
}
@ -103,7 +116,8 @@ static struct mrc_data_container *find_current_mrc_cache_local
if (mrc_cache->mrc_checksum !=
compute_ip_checksum(mrc_cache->mrc_data,
mrc_cache->mrc_data_size)) {
printk(BIOS_ERR, "%s: fast boot cache checksum mismatch\n", __func__);
printk(BIOS_ERR, "%s: fast boot cache checksum mismatch\n",
__func__);
return NULL;
}
@ -163,6 +177,7 @@ void update_mrc_cache(void *unused)
return;
}
cache_base = NULL;
cache_size = get_mrc_cache_region(&cache_base);
if (cache_base == NULL) {
printk(BIOS_ERR, "%s: could not find fast boot cache area\n",
@ -219,17 +234,19 @@ void update_mrc_cache(void *unused)
#endif /* !defined(__PRE_RAM__) */
void * find_and_set_fastboot_cache(void)
void *find_and_set_fastboot_cache(void)
{
struct mrc_data_container *mrc_cache = NULL;
if (((mrc_cache = find_current_mrc_cache()) == NULL) ||
mrc_cache = find_current_mrc_cache();
if ((mrc_cache == NULL) ||
(mrc_cache->mrc_data_size == -1UL)) {
printk(BIOS_DEBUG, "FSP MRC cache not present.\n");
return NULL;
}
printk(BIOS_DEBUG, "FSP MRC cache present at %x.\n", (u32)mrc_cache);
printk(BIOS_SPEW, "Saved MRC data:\n");
hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data, mrc_cache->mrc_data_size);
hexdump32(BIOS_SPEW, (void *)mrc_cache->mrc_data,
mrc_cache->mrc_data_size);
return (void *) mrc_cache->mrc_data;
}
@ -238,6 +255,7 @@ struct mrc_data_container *find_current_mrc_cache(void)
struct mrc_data_container *cache_base;
u32 cache_size;
cache_base = NULL;
cache_size = get_mrc_cache_region(&cache_base);
if (cache_base == NULL) {
printk(BIOS_ERR, "%s: could not find fast boot cache area\n",

View file

@ -0,0 +1,490 @@
/******************************************************************************
Copyright (C) 2013, Intel Corporation
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of Intel Corporation nor the names of its contributors may
be used to endorse or promote products derived from this software without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.
******************************************************************************/
/***********************************************************************
*
* fsp_hob.c
*
* HOB infrastructure code.
*
**********************************************************************/
#include <arch/early_variables.h>
#include <bootstate.h>
#include <cbmem.h>
#include <console/console.h>
#include "fsp_util.h"
#include <ip_checksum.h>
#include <lib.h> // hexdump
#include <string.h>
#define CBMEM_ID_HOB_LIST 0x486f624c /* HobL */
void *fsp_hob_list_ptr CAR_GLOBAL;
/*
* Reads a 64-bit value from memory that may be unaligned.
*
* This function returns the 64-bit value pointed to by buffer. The
* function guarantees that the read operation does not produce an
* alignment fault.
*
* If buffer is NULL, then ASSERT().
*
* buffer: Pointer to a 64-bit value that may be unaligned.
*
* Returns the 64-bit value read from buffer.
*
*/
static
uint64_t
read_unaligned_64(
const uint64_t *buffer
)
{
ASSERT(buffer != NULL);
return *buffer;
}
/*
* Compares two GUIDs.
*
* This function compares guid1 to guid2. If the GUIDs are identical then
* TRUE is returned. If there are any bit differences in the two GUIDs,
* then FALSE is returned.
*
* If guid1 is NULL, then ASSERT().
* If guid2 is NULL, then ASSERT().
*
* guid1: A pointer to a 128 bit GUID.
* guid2: A pointer to a 128 bit GUID.
*
* Returns non-zero if guid1 and guid2 are identical, otherwise returns 0.
*
*/
static
long
compare_guid(
const EFI_GUID * guid1,
const EFI_GUID * guid2
)
{
uint64_t low_part_of_guid1;
uint64_t low_part_of_guid2;
uint64_t high_part_of_guid1;
uint64_t high_part_of_guid2;
low_part_of_guid1 = read_unaligned_64((const uint64_t *) guid1);
low_part_of_guid2 = read_unaligned_64((const uint64_t *) guid2);
high_part_of_guid1 = read_unaligned_64((const uint64_t *) guid1 + 1);
high_part_of_guid2 = read_unaligned_64((const uint64_t *) guid2 + 1);
return ((low_part_of_guid1 == low_part_of_guid2)
&& (high_part_of_guid1 == high_part_of_guid2));
}
/* Returns the pointer to the HOB list. */
void
set_hob_list(
void *hob_list_ptr
)
{
void **hob_ptr;
fsp_hob_list_ptr = hob_list_ptr;
printk(BIOS_SPEW, "0x%p: fsp_hob_list_ptr\n", hob_list_ptr);
hob_ptr = cbmem_add(CBMEM_ID_HOB_LIST, sizeof(hob_list_ptr));
if (hob_ptr == NULL)
die("ERROR - cbmem_add failed in set_hob_list!\n");
*hob_ptr = hob_list_ptr;
}
/* Returns the pointer to the HOB list. */
VOID *
EFIAPI
get_hob_list(
VOID
)
{
void **hob_ptr;
if (fsp_hob_list_ptr == NULL) {
hob_ptr = cbmem_find(CBMEM_ID_HOB_LIST);
if (hob_ptr == NULL)
die("Call set_hob_list before this call!\n");
fsp_hob_list_ptr = *hob_ptr;
}
return fsp_hob_list_ptr;
}
/* Returns the next instance of a HOB type from the starting HOB. */
VOID *
EFIAPI
get_next_hob(
UINT16 type,
CONST VOID *hob_start
)
{
EFI_PEI_HOB_POINTERS hob;
ASSERT(hob_start != NULL);
hob.Raw = (UINT8 *)hob_start;
/* Parse the HOB list until end of list or matching type is found. */
while (!END_OF_HOB_LIST(hob.Raw)) {
if (hob.Header->HobType == type)
return hob.Raw;
if (GET_HOB_LENGTH(hob.Raw) < sizeof(*hob.Header))
break;
hob.Raw = GET_NEXT_HOB(hob.Raw);
}
return NULL;
}
/* Returns the first instance of a HOB type among the whole HOB list. */
VOID *
EFIAPI
get_first_hob(
UINT16 type
)
{
VOID *hob_list;
hob_list = get_hob_list();
return get_next_hob(type, hob_list);
}
/* Returns the next instance of the matched GUID HOB from the starting HOB. */
VOID *
EFIAPI
get_next_guid_hob(
CONST EFI_GUID * guid,
CONST VOID *hob_start
)
{
EFI_PEI_HOB_POINTERS guid_hob;
guid_hob.Raw = (UINT8 *)hob_start;
while ((guid_hob.Raw = get_next_hob(EFI_HOB_TYPE_GUID_EXTENSION,
guid_hob.Raw)) != NULL) {
if (compare_guid(guid, &guid_hob.Guid->Name))
break;
guid_hob.Raw = GET_NEXT_HOB(guid_hob.Raw);
}
return guid_hob.Raw;
}
/*
* Returns the first instance of the matched GUID HOB among the whole HOB list.
*/
VOID *
EFIAPI
get_first_guid_hob(
CONST EFI_GUID * guid
)
{
VOID *hob_list;
hob_list = get_hob_list();
return get_next_guid_hob(guid, hob_list);
}
static void print_hob_mem_attributes(void *hob_ptr)
{
EFI_HOB_MEMORY_ALLOCATION *hob_memory_ptr =
(EFI_HOB_MEMORY_ALLOCATION *)hob_ptr;
EFI_MEMORY_TYPE hob_mem_type =
hob_memory_ptr->AllocDescriptor.MemoryType;
u64 hob_mem_addr = hob_memory_ptr->AllocDescriptor.MemoryBaseAddress;
u64 hob_mem_length = hob_memory_ptr->AllocDescriptor.MemoryLength;
const char *hob_mem_type_names[15];
hob_mem_type_names[0] = "EfiReservedMemoryType";
hob_mem_type_names[1] = "EfiLoaderCode";
hob_mem_type_names[2] = "EfiLoaderData";
hob_mem_type_names[3] = "EfiBootServicesCode";
hob_mem_type_names[4] = "EfiBootServicesData";
hob_mem_type_names[5] = "EfiRuntimeServicesCode";
hob_mem_type_names[6] = "EfiRuntimeServicesData";
hob_mem_type_names[7] = "EfiConventionalMemory";
hob_mem_type_names[8] = "EfiUnusableMemory";
hob_mem_type_names[9] = "EfiACPIReclaimMemory";
hob_mem_type_names[10] = "EfiACPIMemoryNVS";
hob_mem_type_names[11] = "EfiMemoryMappedIO";
hob_mem_type_names[12] = "EfiMemoryMappedIOPortSpace";
hob_mem_type_names[13] = "EfiPalCode";
hob_mem_type_names[14] = "EfiMaxMemoryType";
printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
hob_mem_type_names[(u32)hob_mem_type],
(u32)hob_mem_type);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(unsigned long)hob_mem_addr,
(unsigned long)hob_mem_length);
}
static void print_hob_resource_attributes(void *hob_ptr)
{
EFI_HOB_RESOURCE_DESCRIPTOR *hob_resource_ptr =
(EFI_HOB_RESOURCE_DESCRIPTOR *)hob_ptr;
u32 hob_res_type = hob_resource_ptr->ResourceType;
u32 hob_res_attr = hob_resource_ptr->ResourceAttribute;
u64 hob_res_addr = hob_resource_ptr->PhysicalStart;
u64 hob_res_length = hob_resource_ptr->ResourceLength;
const char *hob_res_type_str = NULL;
/* HOB Resource Types */
switch (hob_res_type) {
case EFI_RESOURCE_SYSTEM_MEMORY:
hob_res_type_str = "EFI_RESOURCE_SYSTEM_MEMORY";
break;
case EFI_RESOURCE_MEMORY_MAPPED_IO:
hob_res_type_str = "EFI_RESOURCE_MEMORY_MAPPED_IO";
break;
case EFI_RESOURCE_IO:
hob_res_type_str = "EFI_RESOURCE_IO";
break;
case EFI_RESOURCE_FIRMWARE_DEVICE:
hob_res_type_str = "EFI_RESOURCE_FIRMWARE_DEVICE";
break;
case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
hob_res_type_str = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT";
break;
case EFI_RESOURCE_MEMORY_RESERVED:
hob_res_type_str = "EFI_RESOURCE_MEMORY_RESERVED";
break;
case EFI_RESOURCE_IO_RESERVED:
hob_res_type_str = "EFI_RESOURCE_IO_RESERVED";
break;
case EFI_RESOURCE_MAX_MEMORY_TYPE:
hob_res_type_str = "EFI_RESOURCE_MAX_MEMORY_TYPE";
break;
default:
hob_res_type_str = "EFI_RESOURCE_UNKNOWN";
break;
}
printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
hob_res_type_str, hob_res_type, hob_res_attr);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(unsigned long)hob_res_addr,
(unsigned long)hob_res_length);
}
static const char *get_hob_type_string(void *hob_ptr)
{
EFI_HOB_GENERIC_HEADER *hob_header_ptr =
(EFI_HOB_GENERIC_HEADER *)hob_ptr;
u16 hob_type = hob_header_ptr->HobType;
const char *hob_type_string = NULL;
switch (hob_type) {
case EFI_HOB_TYPE_HANDOFF:
hob_type_string = "EFI_HOB_TYPE_HANDOFF";
break;
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
hob_type_string = "EFI_HOB_TYPE_MEMORY_ALLOCATION";
break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
hob_type_string = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR";
break;
case EFI_HOB_TYPE_GUID_EXTENSION:
hob_type_string = "EFI_HOB_TYPE_GUID_EXTENSION";
break;
case EFI_HOB_TYPE_MEMORY_POOL:
hob_type_string = "EFI_HOB_TYPE_MEMORY_POOL";
break;
case EFI_HOB_TYPE_UNUSED:
hob_type_string = "EFI_HOB_TYPE_UNUSED";
break;
case EFI_HOB_TYPE_END_OF_HOB_LIST:
hob_type_string = "EFI_HOB_TYPE_END_OF_HOB_LIST";
break;
default:
hob_type_string = "EFI_HOB_TYPE_UNRECOGNIZED";
break;
}
return hob_type_string;
}
/*
* Print out a structure of all the HOBs
* that match a certain type:
* Print all types (0x0000)
* EFI_HOB_TYPE_HANDOFF (0x0001)
* EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
* EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
* EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
* EFI_HOB_TYPE_MEMORY_POOL (0x0007)
* EFI_HOB_TYPE_UNUSED (0xFFFE)
* EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
*/
void print_hob_type_structure(u16 hob_type, void *hob_list_ptr)
{
u32 *current_hob;
u32 *next_hob = 0;
u8 last_hob = 0;
u32 current_type;
const char *current_type_str;
current_hob = hob_list_ptr;
/*
* Print out HOBs of our desired type until
* the end of the HOB list
*/
printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
printk(BIOS_DEBUG, "0x%p: hob_list_ptr\n", hob_list_ptr);
do {
EFI_HOB_GENERIC_HEADER *current_header_ptr =
(EFI_HOB_GENERIC_HEADER *)current_hob;
/* Get the type of this HOB */
current_type = current_header_ptr->HobType;
current_type_str = get_hob_type_string(current_hob);
if (current_type == hob_type || hob_type == 0x0000) {
printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
(u32)current_hob, current_type_str,
current_type);
switch (current_type) {
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
print_hob_mem_attributes(current_hob);
break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
print_hob_resource_attributes(current_hob);
break;
}
}
/* Check for end of HOB list */
last_hob = END_OF_HOB_LIST(current_hob);
if (!last_hob) {
/* Get next HOB pointer */
next_hob = GET_NEXT_HOB(current_hob);
/* Start on next HOB */
current_hob = next_hob;
}
} while (!last_hob);
printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
}
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
/*
* Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
*/
int save_mrc_data(void *hob_start)
{
u32 *mrc_hob;
u32 *mrc_hob_data;
u32 mrc_hob_size;
struct mrc_data_container *mrc_data;
int output_len;
const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
mrc_hob = get_next_guid_hob(&mrc_guid, hob_start);
if (mrc_hob == NULL) {
printk(BIOS_DEBUG,
"Memory Configure Data Hob is not present\n");
return 0;
}
mrc_hob_data = GET_GUID_HOB_DATA(mrc_hob);
mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
(void *)mrc_hob_data, mrc_hob_size);
output_len = ALIGN(mrc_hob_size, 16);
/* Save the MRC S3/fast boot/ADR restore data to cbmem */
mrc_data = cbmem_add(CBMEM_ID_MRCDATA,
output_len + sizeof(struct mrc_data_container));
/* Just return if there was a problem with getting CBMEM */
if (mrc_data == NULL) {
printk(BIOS_WARNING,
"CBMEM was not available to save the fast boot cache data.\n");
return 0;
}
printk(BIOS_DEBUG,
"Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
(void *)mrc_hob_data, mrc_data, output_len);
mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
mrc_data->mrc_data_size = output_len;
mrc_data->reserved = 0;
memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
/* Zero the unused space in aligned buffer. */
if (output_len > mrc_hob_size)
memset((mrc_data->mrc_data + mrc_hob_size), 0,
output_len - mrc_hob_size);
mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
mrc_data->mrc_data_size);
printk(BIOS_SPEW, "Fast boot data (includes align and checksum):\n");
hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len);
return 1;
}
#endif /* CONFIG_ENABLE_MRC_CACHE */
static void find_fsp_hob_update_mrc(void *unused)
{
void *hob_list_ptr;
/* 0x0000: Print all types */
hob_list_ptr = get_hob_list();
print_hob_type_structure(0x000, hob_list_ptr);
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
if (save_mrc_data(hob_list_ptr))
update_mrc_cache(NULL);
else
printk(BIOS_DEBUG, "Not updating MRC data in flash.\n");
#endif
}
void __attribute__ ((weak)) update_mrc_cache(void *unused)
{
printk(BIOS_ERR, "Add routine %s to save the MRC data.\n", __func__);
}
/* Update the MRC/fast boot cache as part of the late table writing stage */
BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
find_fsp_hob_update_mrc, NULL),
};

View file

@ -17,416 +17,157 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <types.h>
#include <string.h>
#include <cpu/x86/stack.h>
#include <console/console.h>
#include <bootstate.h>
#include <cbmem.h>
#include "fsp_util.h"
#include <lib.h> // hexdump
#include <ip_checksum.h>
#include <timestamp.h>
#ifndef __PRE_RAM__
/* Globals pointers for FSP structures */
void *FspHobListPtr = NULL;
FSP_INFO_HEADER *fsp_header_ptr = NULL;
void FspNotify (u32 Phase)
/* Locate the FSP binary in the coreboot filesystem */
FSP_INFO_HEADER *find_fsp(void)
{
FSP_NOTFY_PHASE NotifyPhaseProc;
NOTIFY_PHASE_PARAMS NotifyPhaseParams;
EFI_STATUS Status;
if (fsp_header_ptr == NULL) {
fsp_header_ptr = (void *)find_fsp();
if ((u32)fsp_header_ptr < 0xff) {
post_code(0x4F); /* output something in case there is no serial */
die("Can't find the FSP!\n");
}
}
/* call FSP PEI to Notify PostPciEnumeration */
NotifyPhaseProc = (FSP_NOTFY_PHASE)(fsp_header_ptr->ImageBase +
fsp_header_ptr->NotifyPhaseEntry);
NotifyPhaseParams.Phase = Phase;
timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
Status = NotifyPhaseProc (&NotifyPhaseParams);
timestamp_add_now(Phase == EnumInitPhaseReadyToBoot ?
TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
if (Status != 0)
printk(BIOS_ERR,"FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n", Phase, Status);
}
#endif /* #ifndef __PRE_RAM__ */
#ifdef __PRE_RAM__
/*
* Call the FSP to do memory init. The FSP doesn't return to this function.
* The FSP returns to the romstage_main_continue().
*/
void __attribute__ ((noreturn)) fsp_early_init (FSP_INFO_HEADER *fsp_ptr)
{
FSP_FSP_INIT FspInitApi;
FSP_INIT_PARAMS FspInitParams;
FSP_INIT_RT_BUFFER FspRtBuffer;
#if IS_ENABLED(CONFIG_FSP_USES_UPD)
UPD_DATA_REGION fsp_upd_data;
#endif
memset((void*)&FspRtBuffer, 0, sizeof(FSP_INIT_RT_BUFFER));
FspRtBuffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
FspInitParams.NvsBufferPtr = NULL;
#if IS_ENABLED(CONFIG_FSP_USES_UPD)
FspRtBuffer.Common.UpdDataRgnPtr = &fsp_upd_data;
#endif
FspInitParams.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&FspRtBuffer;
FspInitParams.ContinuationFunc = (CONTINUATION_PROC)ChipsetFspReturnPoint;
FspInitApi = (FSP_FSP_INIT)(fsp_ptr->ImageBase + fsp_ptr->FspInitEntry);
/* Call the chipset code to fill in the chipset specific structures */
chipset_fsp_early_init(&FspInitParams, fsp_ptr);
/* Call back to romstage for board specific changes */
romstage_fsp_rt_buffer_callback(&FspRtBuffer);
FspInitApi(&FspInitParams);
/* Should never return. Control will continue from ContinuationFunc */
die("Uh Oh! FspInitApi returned");
}
#endif /* __PRE_RAM__ */
volatile u8 * __attribute__((optimize("O0"))) find_fsp ()
{
#ifdef __PRE_RAM__
volatile register u8 *fsp_ptr asm ("eax");
/* Entry point for CAR assembly routine */
__asm__ __volatile__ (
".global find_fsp\n\t"
"find_fsp:\n\t"
);
#else
volatile u8 *fsp_ptr;
#endif /* __PRE_RAM__ */
union {
EFI_FFS_FILE_HEADER *ffh;
FSP_INFO_HEADER *fih;
EFI_FIRMWARE_VOLUME_EXT_HEADER *fveh;
EFI_FIRMWARE_VOLUME_HEADER *fvh;
EFI_RAW_SECTION *rs;
u8 *u8;
u32 u32;
} fsp_ptr;
u32 *image_id;
#ifndef CONFIG_FSP_LOC
#error "CONFIG_FSP_LOC must be set."
#endif
/* The FSP is stored in CBFS */
fsp_ptr = (u8 *) CONFIG_FSP_LOC;
for (;;) {
/* Get the FSP binary base address in CBFS */
fsp_ptr.u8 = (u8 *)CONFIG_FSP_LOC;
/* Check the FV signature, _FVH */
if (((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->Signature == 0x4856465F) {
/* Go to the end of the FV header and align the address. */
fsp_ptr += ((EFI_FIRMWARE_VOLUME_HEADER *)fsp_ptr)->ExtHeaderOffset;
fsp_ptr += ((EFI_FIRMWARE_VOLUME_EXT_HEADER *)fsp_ptr)->ExtHeaderSize;
fsp_ptr = (u8 *)(((u32)fsp_ptr + 7) & 0xFFFFFFF8);
} else {
fsp_ptr = (u8*)ERROR_NO_FV_SIG;
/* Check the FV signature, _FVH */
if (fsp_ptr.fvh->Signature != 0x4856465F) {
fsp_ptr.u8 = (u8 *)ERROR_NO_FV_SIG;
break;
}
/* Locate the file header which follows the FV header. */
fsp_ptr.u8 += fsp_ptr.fvh->ExtHeaderOffset;
fsp_ptr.u8 += fsp_ptr.fveh->ExtHeaderSize;
fsp_ptr.u8 = (u8 *)((fsp_ptr.u32 + 7) & 0xFFFFFFF8);
/* Check the FFS GUID */
if ((((u32 *)&fsp_ptr.ffh->Name)[0] != 0x912740BE)
|| (((u32 *)&fsp_ptr.ffh->Name)[1] != 0x47342284)
|| (((u32 *)&fsp_ptr.ffh->Name)[2] != 0xB08471B9)
|| (((u32 *)&fsp_ptr.ffh->Name)[3] != 0x0C3F3527)) {
fsp_ptr.u8 = (u8 *)ERROR_NO_FFS_GUID;
break;
}
/* Locate the Raw Section Header */
fsp_ptr.u8 += sizeof(EFI_FFS_FILE_HEADER);
if (fsp_ptr.rs->Type != EFI_SECTION_RAW) {
fsp_ptr.u8 = (u8 *)ERROR_NO_INFO_HEADER;
break;
}
/* Locate the FSP INFO Header which follows the Raw Header. */
fsp_ptr.u8 += sizeof(EFI_RAW_SECTION);
/* Verify that the FSP base address.*/
if (fsp_ptr.fih->ImageBase != CONFIG_FSP_LOC) {
fsp_ptr.u8 = (u8 *)ERROR_IMAGEBASE_MISMATCH;
break;
}
/* Verify the FSP Signature */
if (fsp_ptr.fih->Signature != FSP_SIG) {
fsp_ptr.u8 = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
break;
}
/* Verify the FSP ID */
image_id = (u32 *)&fsp_ptr.fih->ImageId[0];
if ((image_id[0] != CONFIG_FSP_IMAGE_ID_DWORD0)
|| (image_id[1] != CONFIG_FSP_IMAGE_ID_DWORD1))
fsp_ptr.u8 = (u8 *)ERROR_FSP_SIG_MISMATCH;
break;
}
/* Check the FFS GUID */
if (((u32)fsp_ptr > 0xff) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[0] == 0x912740BE) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[1] == 0x47342284) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[2] == 0xB08471B9) &&
(((u32 *)&(((EFI_FFS_FILE_HEADER *)fsp_ptr)->Name))[3] == 0x0C3F3527)) {
/* Add the FFS Header size to the base to find the Raw section Header */
fsp_ptr += sizeof(EFI_FFS_FILE_HEADER);
} else {
fsp_ptr = (u8 *)ERROR_NO_FFS_GUID;
}
if (((u32)fsp_ptr > 0xff) &&
((EFI_RAW_SECTION *)fsp_ptr)->Type == EFI_SECTION_RAW) {
/* Add the Raw Header size to the base to find the FSP INFO Header */
fsp_ptr += sizeof(EFI_RAW_SECTION);
} else {
fsp_ptr = (u8 *)ERROR_NO_INFO_HEADER;
}
/* Verify that the FSP is set to the base address we're expecting.*/
if (((u32)fsp_ptr > 0xff) &&
(*(u32*)(fsp_ptr + FSP_IMAGE_BASE_LOC) != CONFIG_FSP_LOC)) {
fsp_ptr = (u8 *)ERROR_IMAGEBASE_MISMATCH;
}
/* Verify the FSP Signature */
if (((u32)fsp_ptr > 0xff) &&
(*(u32*)(fsp_ptr + FSP_IMAGE_SIG_LOC) != FSP_SIG)){
fsp_ptr = (u8 *)ERROR_INFO_HEAD_SIG_MISMATCH;
}
/* Verify the FSP ID */
if (((u32)fsp_ptr > 0xff) &&
((*(u32 *)(fsp_ptr + FSP_IMAGE_ID_LOC) != FSP_IMAGE_ID_DWORD0) ||
(*(u32 *)(fsp_ptr + (FSP_IMAGE_ID_LOC + 4)) != FSP_IMAGE_ID_DWORD1))) {
fsp_ptr = (u8 *)ERROR_FSP_SIG_MISMATCH;
}
return (fsp_ptr);
return fsp_ptr.fih;
}
#ifndef __PRE_RAM__ /* Only parse HOB data in ramstage */
void print_fsp_info(FSP_INFO_HEADER *fsp_header)
{
u8 *fsp_base;
void print_fsp_info(void) {
fsp_base = (u8 *)fsp_header->ImageBase;
printk(BIOS_SPEW, "FSP_INFO_HEADER: %p\n", fsp_header);
printk(BIOS_INFO, "FSP Signature: %c%c%c%c%c%c%c%c\n",
fsp_header->ImageId[0], fsp_header->ImageId[1],
fsp_header->ImageId[2], fsp_header->ImageId[3],
fsp_header->ImageId[4], fsp_header->ImageId[5],
fsp_header->ImageId[6], fsp_header->ImageId[7]);
printk(BIOS_INFO, "FSP Header Version: %d\n",
fsp_header->HeaderRevision);
printk(BIOS_INFO, "FSP Revision: %d.%d\n",
(u8)((fsp_header->ImageRevision >> 8) & 0xff),
(u8)(fsp_header->ImageRevision & 0xff));
printk(BIOS_SPEW, "FSP Entry Points:\n");
printk(BIOS_SPEW, " 0x%p: Image Base\n", fsp_base);
printk(BIOS_SPEW, " 0x%p: TempRamInit\n",
&fsp_base[fsp_header->TempRamInitEntryOffset]);
printk(BIOS_SPEW, " 0x%p: FspInit\n",
&fsp_base[fsp_header->FspInitEntryOffset]);
if (fsp_header->HeaderRevision >= FSP_HEADER_REVISION_1_1) {
printk(BIOS_SPEW, " 0x%p: MemoryInit\n",
&fsp_base[fsp_header->FspMemoryInitEntryOffset]);
printk(BIOS_SPEW, " 0x%p: TempRamExit\n",
&fsp_base[fsp_header->TempRamExitEntryOffset]);
printk(BIOS_SPEW, " 0x%p: SiliconInit\n",
&fsp_base[fsp_header->FspSiliconInitEntryOffset]);
}
printk(BIOS_SPEW, " 0x%p: NotifyPhase\n",
&fsp_base[fsp_header->NotifyPhaseEntryOffset]);
printk(BIOS_SPEW, " 0x%p: Image End\n",
&fsp_base[fsp_header->ImageSize]);
}
if (fsp_header_ptr == NULL)
#ifndef __PRE_RAM__
FSP_INFO_HEADER *fsp_header_ptr = NULL;
void fsp_notify(u32 phase)
{
FSP_NOTIFY_PHASE notify_phase_proc;
NOTIFY_PHASE_PARAMS notify_phase_params;
EFI_STATUS status;
if (fsp_header_ptr == NULL) {
fsp_header_ptr = (void *)find_fsp();
if ((u32)fsp_header_ptr < 0xff) {
post_code(0x4F); /* output something in case there is no serial */
/* output something in case there is no serial */
post_code(0x4F);
die("Can't find the FSP!\n");
}
if (FspHobListPtr == NULL) {
FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
}
printk(BIOS_SPEW,"fsp_header_ptr: %p\n", fsp_header_ptr);
printk(BIOS_INFO,"FSP Header Version: %d\n", fsp_header_ptr->HeaderRevision);
printk(BIOS_INFO,"FSP Revision: %d.%d\n",
(u8)((fsp_header_ptr->ImageRevision >> 8) & 0xff),
(u8)(fsp_header_ptr->ImageRevision & 0xff));
/* call FSP PEI to Notify PostPciEnumeration */
notify_phase_proc = (FSP_NOTIFY_PHASE)(fsp_header_ptr->ImageBase +
fsp_header_ptr->NotifyPhaseEntryOffset);
notify_phase_params.Phase = phase;
timestamp_add_now(phase == EnumInitPhaseReadyToBoot ?
TS_FSP_BEFORE_FINALIZE : TS_FSP_BEFORE_ENUMERATE);
status = notify_phase_proc(&notify_phase_params);
timestamp_add_now(phase == EnumInitPhaseReadyToBoot ?
TS_FSP_AFTER_FINALIZE : TS_FSP_AFTER_ENUMERATE);
if (status != 0)
printk(BIOS_ERR, "FSP API NotifyPhase failed for phase 0x%x with status: 0x%x\n",
phase, status);
}
static void print_hob_mem_attributes(void *Hobptr) {
EFI_HOB_MEMORY_ALLOCATION *HobMemoryPtr = (EFI_HOB_MEMORY_ALLOCATION *)Hobptr;
EFI_MEMORY_TYPE Hobmemtype = HobMemoryPtr->AllocDescriptor.MemoryType;
u64 Hobmemaddr = HobMemoryPtr->AllocDescriptor.MemoryBaseAddress;
u64 Hobmemlength = HobMemoryPtr->AllocDescriptor.MemoryLength;
const char * Hobmemtypenames[15];
Hobmemtypenames[0] = "EfiReservedMemoryType";
Hobmemtypenames[1] = "EfiLoaderCode";
Hobmemtypenames[2] = "EfiLoaderData";
Hobmemtypenames[3] = "EfiBootServicesCode";
Hobmemtypenames[4] = "EfiBootServicesData";
Hobmemtypenames[5] = "EfiRuntimeServicesCode";
Hobmemtypenames[6] = "EfiRuntimeServicesData";
Hobmemtypenames[7] = "EfiConventionalMemory";
Hobmemtypenames[8] = "EfiUnusableMemory";
Hobmemtypenames[9] = "EfiACPIReclaimMemory";
Hobmemtypenames[10] = "EfiACPIMemoryNVS";
Hobmemtypenames[11] = "EfiMemoryMappedIO";
Hobmemtypenames[12] = "EfiMemoryMappedIOPortSpace";
Hobmemtypenames[13] = "EfiPalCode";
Hobmemtypenames[14] = "EfiMaxMemoryType";
printk(BIOS_SPEW, " Memory type %s (0x%x)\n",
Hobmemtypenames[(u32)Hobmemtype], (u32) Hobmemtype);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(unsigned long)Hobmemaddr, (unsigned long)Hobmemlength);
}
static void print_hob_resource_attributes(void *Hobptr) {
EFI_HOB_RESOURCE_DESCRIPTOR *HobResourcePtr =
(EFI_HOB_RESOURCE_DESCRIPTOR *)Hobptr;
u32 Hobrestype = HobResourcePtr->ResourceType;
u32 Hobresattr = HobResourcePtr->ResourceAttribute;
u64 Hobresaddr = HobResourcePtr->PhysicalStart;
u64 Hobreslength = HobResourcePtr->ResourceLength;
const char *Hobrestypestr = NULL;
// HOB Resource Types
switch (Hobrestype) {
case EFI_RESOURCE_SYSTEM_MEMORY:
Hobrestypestr = "EFI_RESOURCE_SYSTEM_MEMORY"; break;
case EFI_RESOURCE_MEMORY_MAPPED_IO:
Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO"; break;
case EFI_RESOURCE_IO:
Hobrestypestr = "EFI_RESOURCE_IO"; break;
case EFI_RESOURCE_FIRMWARE_DEVICE:
Hobrestypestr = "EFI_RESOURCE_FIRMWARE_DEVICE"; break;
case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
Hobrestypestr = "EFI_RESOURCE_MEMORY_MAPPED_IO_PORT"; break;
case EFI_RESOURCE_MEMORY_RESERVED:
Hobrestypestr = "EFI_RESOURCE_MEMORY_RESERVED"; break;
case EFI_RESOURCE_IO_RESERVED:
Hobrestypestr = "EFI_RESOURCE_IO_RESERVED"; break;
case EFI_RESOURCE_MAX_MEMORY_TYPE:
Hobrestypestr = "EFI_RESOURCE_MAX_MEMORY_TYPE"; break;
default:
Hobrestypestr = "EFI_RESOURCE_UNKNOWN"; break;
}
printk(BIOS_SPEW, " Resource %s (0x%0x) has attributes 0x%0x\n",
Hobrestypestr, Hobrestype, Hobresattr);
printk(BIOS_SPEW, " at location 0x%0lx with length 0x%0lx\n",
(unsigned long)Hobresaddr, (unsigned long)Hobreslength);
}
static const char * get_hob_type_string(void *Hobptr) {
EFI_HOB_GENERIC_HEADER *HobHeaderPtr = (EFI_HOB_GENERIC_HEADER *)Hobptr;
u16 Hobtype = HobHeaderPtr->HobType;
const char *Hobtypestring = NULL;
switch (Hobtype) {
case EFI_HOB_TYPE_HANDOFF:
Hobtypestring = "EFI_HOB_TYPE_HANDOFF"; break;
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
Hobtypestring = "EFI_HOB_TYPE_MEMORY_ALLOCATION"; break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
Hobtypestring = "EFI_HOB_TYPE_RESOURCE_DESCRIPTOR"; break;
case EFI_HOB_TYPE_GUID_EXTENSION:
Hobtypestring = "EFI_HOB_TYPE_GUID_EXTENSION"; break;
case EFI_HOB_TYPE_MEMORY_POOL:
Hobtypestring = "EFI_HOB_TYPE_MEMORY_POOL"; break;
case EFI_HOB_TYPE_UNUSED:
Hobtypestring = "EFI_HOB_TYPE_UNUSED"; break;
case EFI_HOB_TYPE_END_OF_HOB_LIST:
Hobtypestring = "EFI_HOB_TYPE_END_OF_HOB_LIST"; break;
default:
Hobtypestring = "EFI_HOB_TYPE_UNRECOGNIZED"; break;
}
return Hobtypestring;
}
/* Print out a structure of all the HOBs
* that match a certain type:
* Print all types (0x0000)
* EFI_HOB_TYPE_HANDOFF (0x0001)
* EFI_HOB_TYPE_MEMORY_ALLOCATION (0x0002)
* EFI_HOB_TYPE_RESOURCE_DESCRIPTOR (0x0003)
* EFI_HOB_TYPE_GUID_EXTENSION (0x0004)
* EFI_HOB_TYPE_MEMORY_POOL (0x0007)
* EFI_HOB_TYPE_UNUSED (0xFFFE)
* EFI_HOB_TYPE_END_OF_HOB_LIST (0xFFFF)
*/
void print_hob_type_structure(u16 Hobtype, void *Hoblistptr) {
u32 *Currenthob;
u32 *Nexthob = 0;
u8 Lasthob = 0;
u32 Currenttype;
const char *Currenttypestr;
Currenthob = Hoblistptr;
/* Print out HOBs of our desired type until
* the end of the HOB list
*/
printk(BIOS_DEBUG, "\n=== FSP HOB Data Structure ===\n");
printk(BIOS_DEBUG, "FSP Hoblistptr: 0x%0x\n",
(u32) Hoblistptr);
do {
EFI_HOB_GENERIC_HEADER *CurrentHeaderPtr =
(EFI_HOB_GENERIC_HEADER *)Currenthob;
Currenttype = CurrentHeaderPtr->HobType; /* Get the type of this HOB */
Currenttypestr = get_hob_type_string(Currenthob);
if (Currenttype == Hobtype || Hobtype == 0x0000) {
printk(BIOS_DEBUG, "HOB 0x%0x is an %s (type 0x%0x)\n",
(u32) Currenthob, Currenttypestr, Currenttype);
switch (Currenttype) {
case EFI_HOB_TYPE_MEMORY_ALLOCATION:
print_hob_mem_attributes(Currenthob); break;
case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
print_hob_resource_attributes(Currenthob); break;
}
}
Lasthob = END_OF_HOB_LIST(Currenthob); /* Check for end of HOB list */
if (!Lasthob) {
Nexthob = GET_NEXT_HOB(Currenthob); /* Get next HOB pointer */
Currenthob = Nexthob; // Start on next HOB
}
} while (!Lasthob);
printk(BIOS_DEBUG, "=== End of FSP HOB Data Structure ===\n\n");
}
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
/**
* Save the FSP memory HOB (mrc data) to the MRC area in CBMEM
*/
int save_mrc_data(void *hob_start)
{
u32 *mrc_hob;
u32 *mrc_hob_data;
u32 mrc_hob_size;
struct mrc_data_container *mrc_data;
int output_len;
const EFI_GUID mrc_guid = FSP_NON_VOLATILE_STORAGE_HOB_GUID;
mrc_hob = GetNextGuidHob(&mrc_guid, hob_start);
if (mrc_hob == NULL){
printk(BIOS_DEBUG, "Memory Configure Data Hob is not present\n");
return(0);
}
mrc_hob_data = GET_GUID_HOB_DATA (mrc_hob);
mrc_hob_size = (u32) GET_HOB_LENGTH(mrc_hob);
printk(BIOS_DEBUG, "Memory Configure Data Hob at %p (size = 0x%x).\n",
(void *)mrc_hob_data, mrc_hob_size);
output_len = ALIGN(mrc_hob_size, 16);
/* Save the MRC S3/fast boot/ADR restore data to cbmem */
mrc_data = cbmem_add (CBMEM_ID_MRCDATA,
output_len + sizeof(struct mrc_data_container));
/* Just return if there was a problem with getting CBMEM */
if (mrc_data == NULL) {
printk(BIOS_WARNING, "CBMEM was not available to save the fast boot cache data.\n");
return 0;
}
printk(BIOS_DEBUG, "Copy FSP MRC DATA to HOB (source addr %p, dest addr %p, %u bytes)\n",
(void *)mrc_hob_data, mrc_data, output_len);
mrc_data->mrc_signature = MRC_DATA_SIGNATURE;
mrc_data->mrc_data_size = output_len;
mrc_data->reserved = 0;
memcpy(mrc_data->mrc_data, (const void *)mrc_hob_data, mrc_hob_size);
/* Zero the unused space in aligned buffer. */
if (output_len > mrc_hob_size)
memset((mrc_data->mrc_data + mrc_hob_size), 0,
output_len - mrc_hob_size);
mrc_data->mrc_checksum = compute_ip_checksum(mrc_data->mrc_data,
mrc_data->mrc_data_size);
printk(BIOS_SPEW, "Fast boot data (includes align and checksum):\n");
hexdump32(BIOS_SPEW, (void *)mrc_data->mrc_data, output_len);
return (1);
}
#endif /* CONFIG_ENABLE_MRC_CACHE */
static void find_fsp_hob_update_mrc(void *unused)
{
/* Set the global HOB list pointer */
FspHobListPtr = (void*)*((u32*) cbmem_find(CBMEM_ID_HOB_POINTER));
if (!FspHobListPtr){
printk(BIOS_ERR, "ERROR: Could not find FSP HOB pointer in CBFS!\n");
} else {
/* 0x0000: Print all types */
print_hob_type_structure(0x000, FspHobListPtr);
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
if(save_mrc_data(FspHobListPtr))
update_mrc_cache(NULL);
else
printk(BIOS_DEBUG,"Not updating MRC data in flash.\n");
#endif
}
}
/* Update the MRC/fast boot cache as part of the late table writing stage */
BOOT_STATE_INIT_ENTRIES(fsp_hob_find) = {
BOOT_STATE_INIT_ENTRY(BS_WRITE_TABLES, BS_ON_ENTRY,
find_fsp_hob_update_mrc, NULL),
};
#endif /* #ifndef __PRE_RAM__ */

View file

@ -20,6 +20,21 @@
#ifndef FSP_UTIL_H
#define FSP_UTIL_H
#include <types.h>
#include <arch/cpu.h>
/*
* The following are functions with prototypes defined in the EDK2 headers. The
* EDK2 headers are included with chipset_fsp_util.h. Define the following
* names to reduce the use of CamelCase in the other source files.
*/
#define GetHobList get_hob_list
#define GetNextHob get_next_hob
#define GetFirstHob get_first_hob
#define GetNextGuidHob get_next_guid_hob
#define GetFirstGuidHob get_first_guid_hob
/* Include the EDK2 headers */
#include <chipset_fsp_util.h>
#if IS_ENABLED(CONFIG_ENABLE_MRC_CACHE)
@ -27,17 +42,26 @@ int save_mrc_data(void *hob_start);
void * find_and_set_fastboot_cache(void);
#endif
volatile u8 * find_fsp (void);
FSP_INFO_HEADER *find_fsp(void);
void fsp_early_init(FSP_INFO_HEADER *fsp_info);
void FspNotify(u32 Phase);
void FspNotifyReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
void print_hob_type_structure(u16 Hobtype, void *Hoblistptr);
void romstage_fsp_rt_buffer_callback(FSP_INIT_RT_BUFFER *FspRtBuffer);
void print_fsp_info(void);
void fsp_notify(u32 phase);
void print_hob_type_structure(u16 hob_type, void *hob_list_ptr);
void print_fsp_info(FSP_INFO_HEADER *fsp_header);
void set_hob_list(void *hob_list_ptr);
void chipset_fsp_early_init(FSP_INIT_PARAMS *FspInitParams,
/* The following are chipset support routines */
#if IS_ENABLED(CONFIG_USING_FSP_1_0)
void chipset_fsp_early_init(FSP_INIT_PARAMS * fsp_init_params,
FSP_INFO_HEADER *fsp_ptr);
void ChipsetFspReturnPoint(EFI_STATUS Status, VOID *HobListPtr);
void chipset_fsp_return_point(EFI_STATUS status, VOID *hob_list_ptr);
#endif
/* The following are board support routines */
#if IS_ENABLED(CONFIG_USING_FSP_1_0)
void romstage_fsp_rt_buffer_callback(
FSP_INIT_RT_COMMON_BUFFER * fsp_rt_common_buffer);
#endif
/* Additional HOB types not included in the FSP:
* #define EFI_HOB_TYPE_HANDOFF 0x0001
@ -68,24 +92,22 @@ struct mrc_data_container {
struct mrc_data_container *find_current_mrc_cache(void);
#if !defined(__PRE_RAM__)
void update_mrc_cache(void *unused);
#endif
#endif
#endif /* CONFIG_ENABLE_MRC_CACHE */
/* The offset in bytes from the start of the info structure */
#define FSP_IMAGE_SIG_LOC 0
#define FSP_IMAGE_ID_LOC 16
#define FSP_IMAGE_BASE_LOC 28
#define FSP_IMAGE_SIG_LOC 0
#define FSP_IMAGE_ID_LOC 16
#define FSP_IMAGE_BASE_LOC 28
#define FSP_SIG 0x48505346 /* 'FSPH' */
#define FSP_SIG 0x48505346 /* 'FSPH' */
#define ERROR_NO_FV_SIG 1
#define ERROR_NO_FFS_GUID 2
#define ERROR_NO_FFS_GUID 2
#define ERROR_NO_INFO_HEADER 3
#define ERROR_IMAGEBASE_MISMATCH 4
#define ERROR_INFO_HEAD_SIG_MISMATCH 5
#define ERROR_INFO_HEAD_SIG_MISMATCH 5
#define ERROR_FSP_SIG_MISMATCH 6
#ifndef __PRE_RAM__

View file

@ -0,0 +1,64 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
*
* 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <console/console.h>
#include <cpu/x86/stack.h>
#include "fsp_util.h"
#include <string.h>
#ifdef __PRE_RAM__
/*
* Call the FSP to do memory init. The FSP doesn't return to this function.
* The FSP returns to the romstage_main_continue().
*/
void __attribute__ ((noreturn)) fsp_early_init(FSP_INFO_HEADER *fsp_ptr)
{
FSP_FSP_INIT fsp_init_api;
FSP_INIT_PARAMS fsp_init_params;
FSP_INIT_RT_BUFFER fsp_rt_buffer;
#if IS_ENABLED(CONFIG_FSP_USES_UPD)
UPD_DATA_REGION fsp_upd_data;
#endif
memset((void *)&fsp_rt_buffer, 0, sizeof(FSP_INIT_RT_BUFFER));
fsp_rt_buffer.Common.StackTop = (u32 *)ROMSTAGE_STACK;
fsp_init_params.NvsBufferPtr = NULL;
#if IS_ENABLED(CONFIG_FSP_USES_UPD)
fsp_rt_buffer.Common.UpdDataRgnPtr = &fsp_upd_data;
#endif
fsp_init_params.RtBufferPtr = (FSP_INIT_RT_BUFFER *)&fsp_rt_buffer;
fsp_init_params.ContinuationFunc =
(CONTINUATION_PROC)chipset_fsp_return_point;
fsp_init_api = (FSP_FSP_INIT)(fsp_ptr->ImageBase
+ fsp_ptr->FspInitEntryOffset);
/* Call the chipset code to fill in the chipset specific structures */
chipset_fsp_early_init(&fsp_init_params, fsp_ptr);
/* Call back to romstage for board specific changes */
romstage_fsp_rt_buffer_callback(&fsp_rt_buffer);
fsp_init_api(&fsp_init_params);
/* Should never return. Control will continue from ContinuationFunc */
die("Uh Oh! FspInit returned");
}
#endif /* __PRE_RAM__ */