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

69
configs/config.samus.fsp Normal file
View file

@ -0,0 +1,69 @@
CONFIG_COLLECT_TIMESTAMPS=y
CONFIG_USE_BLOBS=y
CONFIG_VENDOR_GOOGLE=y
CONFIG_BOARD_GOOGLE_SAMUS=y
CONFIG_CBFS_SIZE=0x100000
CONFIG_CONSOLE_CBMEM=y
# Enable Serial Debugging
CONFIG_CONSOLE_SERIAL=y
CONFIG_MAXIMUM_CONSOLE_LOGLEVEL=8
CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
CONFIG_DEBUG_CAR=y
CONFIG_DEBUG_CBFS=y
CONFIG_DEBUG_COVERAGE=y
CONFIG_DEBUG_MALLOC=y
CONFIG_DEBUG_INTEL_ME=y
CONFIG_DEBUG_PIRQ=y
#CONFIG_DEBUG_RAM_SETUP=y
CONFIG_DEBUG_SMBUS=y
CONFIG_DEBUG_SMI=y
CONFIG_DEBUG_SMM_RELOCATION=y
#CONFIG_DEBUG_SPI=y
CONFIG_DEBUG_SPI_FLASH=y
CONFIG_DEBUG_TPM=y
# Enable FSP
CONFIG_CPU_MICROCODE_CBFS_LEN=0xd040
CONFIG_CPU_MICROCODE_CBFS_LOC=0xffe11540
CONFIG_DCACHE_RAM_BASE=0xfef00000
CONFIG_DCACHE_RAM_SIZE=0x00004000
CONFIG_FSP_FILE="3rdparty/mainboard/google/samus/fsp/FSP.fd"
CONFIG_FSP_IMAGE_ID_DWORD0=0x2d574442
CONFIG_FSP_IMAGE_ID_DWORD1=0x30505346
CONFIG_FSP_INCLUDE_PATH="3rdparty/mainboard/google/samus/fsp"
CONFIG_FSP_LOC=0xfff30000
CONFIG_HAVE_FSP_BIN=y
CONFIG_MMCONF_BASE_ADDRESS=0xe0000000
CONFIG_PLATFORM_USES_FSP=y
# CONFIG_PCI_ROM_RUN is not set
# CONFIG_ON_DEVICE_ROM_RUN is not set
# CONFIG_S3_VGA_ROM_RUN is not set
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_USER=y
CONFIG_FRAMEBUFFER_VESA_MODE=0x161
CONFIG_FRAMEBUFFER_KEEP_VESA_MODE=y
CONFIG_VGA_BIOS_ID="8086,0406"
CONFIG_VGA_BIOS=y
CONFIG_VGA_BIOS_FILE="3rdparty/mainboard/google/samus/vgabios.bin"
CONFIG_CPU_ADDR_BITS=36
CONFIG_CACHE_ROM=y
CONFIG_MARK_GRAPHICS_MEM_WRCOMB=y
CONFIG_ELOG=y
CONFIG_ELOG_GSMI=y
CONFIG_ELOG_BOOT_COUNT=y
CONFIG_ELOG_BOOT_COUNT_CMOS_OFFSET=144
CONFIG_SPI_FLASH_SMM=y
CONFIG_CMOS_POST=y
CONFIG_CMOS_POST_OFFSET=0x70
CONFIG_CMOS_POST_EXTRA=y
CONFIG_RELOCATABLE_RAMSTAGE=y
CONFIG_CACHE_RELOCATED_RAMSTAGE_OUTSIDE_CBMEM=y
CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE=y
CONFIG_VBOOT_VERIFY_FIRMWARE=y
CONFIG_FLASHMAP_OFFSET=0x00610000
# CONFIG_MULTIBOOT is not set
CONFIG_PAYLOAD_NONE=y
CONFIG_PRE_GRAPHICS_DELAY=200
# CONFIG_LOCK_MANAGEMENT_ENGINE is not set

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__ */

View file

@ -63,7 +63,7 @@ config MICROCODE_INCLUDE_PATH
default "src/soc/intel/broadwell/microcode"
config MMCONF_BASE_ADDRESS
hex
hex "MMIO Base Address"
default 0xf0000000
config SERIAL_CPU_INIT
@ -91,11 +91,11 @@ config CACHE_MRC_SIZE_KB
default 512
config DCACHE_RAM_BASE
hex
hex "Base address of cache-as-RAM"
default 0xff7c0000
config DCACHE_RAM_SIZE
hex
hex "Length in bytes of cache-as-RAM"
default 0x10000
help
The size of the cache-as-ram region required during bootblock

View file

@ -72,6 +72,14 @@ smm-y += usbdebug.c
endif
INCLUDES += -Isrc/soc/intel/broadwell/include
ifeq ($(CONFIG_PLATFORM_USES_FSP),y)
INCLUDES += -Isrc/drivers/intel/fsp
INCLUDES += -Isrc/vendorcode/intel/fsp/fsp_1_1
INCLUDES += -Isrc/vendorcode/intel/edk2/uefi_2.4
INCLUDES += -Isrc/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include
INCLUDES += -Isrc/vendorcode/intel/edk2/uefi_2.4/MdePkg/Include/Ia32
INCLUDES += -I$(CONFIG_FSP_INCLUDE_PATH)
endif
# Run an intermediate step when producing coreboot.rom
# that adds additional components to the final firmware

View file

@ -0,0 +1,42 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2014 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef CHIPSET_FSP_UTIL_H
#define CHIPSET_FSP_UTIL_H
/*
* Include the FSP binary interface files
*
* These files include the necessary UEFI constants and data structures
* that are used to interface to the FSP binary.
*/
#include <uefi_types.h> /* UEFI data types */
#include <IntelFspPkg/Include/FspApi.h> /* FSP API definitions */
#include <IntelFspPkg/Include/FspInfoHeader.h> /* FSP binary layout */
#include <MdePkg/Include/Pi/PiBootMode.h> /* UEFI boot mode definitions */
#include <MdePkg/Include/Pi/PiFirmwareFile.h> /* UEFI file definitions */
#include <MdePkg/Include/Pi/PiFirmwareVolume.h> /* UEFI file system defs */
#include <MdePkg/Include/Uefi/UefiMultiPhase.h> /* UEFI memory types */
#include <MdePkg/Include/Pi/PiHob.h> /* Hand off block definitions */
#include <MdePkg/Include/Library/HobLib.h> /* HOB routine declarations */
#include <VpdHeader.h> /* Vital/updatable product data definitions*/
#endif /* CHIPSET_FSP_UTIL_H */

View file

@ -31,10 +31,58 @@ struct romstage_params {
struct pei_data *pei_data;
};
/*
* FSP Boot Flow:
* 1. src/cpu/x86/16bit/reset.inc
* 2. src/cpu/x86/16bit/entry.inc
* 3. other modules
* 4. src/soc/intel/broadwell/romstage/fsp_1_1.inc
* 5. src/drivers/intel/fsp/fsp_util.c/find_fsp
* 6. FSP binary/TempRamInit
* 7. src/soc/intel/broadwell/romstage/fsp_1_1.inc - return
* 8. src/soc/intel/broadwell/romstage/romstage.c/romstage_main
* 9. src/mainboard/.../romstage.c/mainboard_romstage_entry
* 10. src/soc/intel/broadwell/romstage/romstage.c/romstage_common
* 11. src/soc/intel/broadwell/romstage/fsp.c/chipset_fsp_memory_init_params
* 12. src/mainboard/.../fsp.c/board_fsp_memory_init_params
* 13. FSP binary/MemoryInit
* 14. src/soc/intel/broadwell/romstage/romstage.c/romstage_common - return
* 15. src/mainboard/.../romstage.c/mainboard_romstage_entry - return
* 16. src/soc/intel/broadwell/romstage/romstage.c/romstage_main - return
* 17. src/soc/intel/broadwell/stack.c/setup_stack_and_mttrs
* 18. src/soc/intel/broadwell/romstage/fsp_1_1.inc - return, cleanup
* after call to romstage_main
* 19. FSP binary/TempRamExit
* 20. src/soc/intel/broadwell/romstage.c/romstage_after_car
* 21. FSP binary/SiliconInit
* 22. src/soc/intel/broadwell/romstage.c/romstage_after_car - return
* 23. src/soc/intel/broadwell/chip.c/broadwell_final
* 24. src/drivers/intel/fsp/fsp_util.c/fsp_notify
* 25. FSP binary/FspNotify
*
*
* MRC Boot Flow:
* 1. src/cpu/x86/16bit/reset.inc
* 2. src/cpu/x86/16bit/entry.inc
* 3. other modules
* 4. src/soc/intel/broadwell/romstage/cache_as_ram.inc
* 5. src/soc/intel/broadwell/romstage/romstage.c/romstage_main
* 6. src/mainboard/.../romstage.c/mainboard_romstage_entry
* 7. src/soc/intel/broadwell/romstage/romstage.c/romstage_common
* 8. src/soc/intel/broadwell/ram_init.c/ram_init
* 9. src/soc/intel/broadwell/romstage/romstage.c/romstage_common - return
* 10. src/mainboard/.../romstage.c/mainboard_romstage_entry - return
* 11. src/soc/intel/broadwell/romstage/romstage.c/romstage_main - return
* 12. src/soc/intel/broadwell/stack.c/setup_stack_and_mttrs
* 13. src/soc/intel/broadwell/romstage/cache_as_ram.inc - return, cleanup
* after call to romstage_main
* 14. src/soc/intel/broadwell/romstage.c/romstage_after_car
*/
asmlinkage void *romstage_main(unsigned int bist, uint32_t tsc_lo,
uint32_t tsc_high);
void mainboard_romstage_entry(struct romstage_params *params);
void romstage_common(struct romstage_params *params);
void *asmlinkage romstage_main(unsigned long bist, uint32_t tsc_lo,
uint32_t tsc_high);
void asmlinkage romstage_after_car(void);
void raminit(struct pei_data *pei_data);
void *setup_stack_and_mttrs(void);

View file

@ -1,4 +1,10 @@
ifeq ($(CONFIG_HAVE_MRC),y)
cpu_incs += $(src)/soc/intel/broadwell/romstage/cache_as_ram.inc
else
ifeq ($(CONFIG_PLATFORM_USES_FSP),y)
cpu_incs += $(src)/soc/intel/broadwell/romstage/fsp_1_1.inc
endif
endif
romstage-y += cpu.c
romstage-y += pch.c
@ -11,3 +17,4 @@ romstage-y += spi.c
romstage-y += stack.c
romstage-y += systemagent.c
romstage-$(CONFIG_CONSOLE_SERIAL8250MEM) += uart.c

View file

@ -0,0 +1,229 @@
/*
* This file is part of the coreboot project.
*
* Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
* Copyright (C) 2007-2008 coresystems GmbH
* 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
*/
/*
* Replacement for cache_as_ram.inc when using the FSP binary. This code
* locates the FSP binary, initializes the cache as RAM and performs the
* first stage of initialization. Next this code switches the stack from
* the cache to RAM and then disables the cache as RAM. Finally this code
* performs the final stage of initialization.
*/
#include <cpu/x86/stack.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
#include <cbmem.h>
#ifndef CONFIG_FSP_LOC
# error "CONFIG_FSP_LOC must be set."
#endif
#ifndef CONFIG_POST_IO
# error "CONFIG_POST_IO must be set."
#endif
#if CONFIG_POST_IO
# ifndef CONFIG_POST_IO_PORT
# error "CONFIG_POST_IO_PORT must be set."
# endif
#endif
#ifndef CONFIG_CPU_MICROCODE_CBFS_LOC
# error "CONFIG_CPU_MICROCODE_CBFS_LOC must be set."
#endif
#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */
/*
* eax: BIST value
* mm0: low 32-bits of TSC value
* mm1: high 32-bits of TSC value
*/
cmp $0, %eax
jne bisthalt
cache_as_ram:
post_code(0x20)
/*
* BIST value is zero
* mm0: low 32-bits of TSC value
* mm1: high 32-bits of TSC value
*/
/*
* Find the FSP binary in cbfs.
* Make a fake stack that has the return value back to this code.
*/
lea fake_fsp_stack, %esp
jmp find_fsp
find_fsp_ret:
/* Save the FSP location */
mov %eax, %ebp
cmp $CONFIG_FSP_LOC, %eax
jb halt1
post_code(0x22)
/* Calculate entry into FSP */
mov 0x30(%ebp), %eax /* Load TempRamInitEntry */
add 0x1c(%ebp), %eax /* add in the offset for the FSP base address */
/*
* Pass early init variables on a fake stack (no memory yet)
* as well as the return location
*/
lea CAR_init_stack, %esp
/*
* BIST value is zero
* eax: TempRamInitApi address
* ebp: FSP_INFO_HEADER address
* mm0: low 32-bits of TSC value
* mm1: high 32-bits of TSC value
*/
/* call FSP binary to setup temporary stack */
jmp *%eax
CAR_init_done:
addl $4, %esp
cmp $0, %eax
jne halt2
/* Setup bootloader stack */
lea -4(%edx), %esp
/*
* ebp: FSP_INFO_HEADER address
* ecx: temp RAM base (stack base)
* edx: temp RAM top (stack top)
* mm0: low 32-bits of TSC value
* mm1: high 32-bits of TSC value
*/
/* Coreboot assumes stack/heap region will be zero */
cld
movl %ecx, %esi
movl %esi, %edi
sub %ecx, %edx
movl %edx, %ecx
shrl $2, %ecx
xorl %eax, %eax
rep stosl
/* Save FSP_INFO_HEADER location in ebx */
mov %ebp, %ebx
/*
* ebx: FSP_INFO_HEADER address
* esi: temp RAM base
* mm0: low 32-bits of TSC value
* mm1: high 32-bits of TSC value
*/
/* Build the call frame */
movl %esp, %ebp
movd %mm1, %eax
pushl %eax
movd %mm0, %eax
pushl %eax
pushl $0
before_romstage:
post_code(0x23)
/* Call romstage.c main function. */
call romstage_main
/*
* ebx: FSP_INFO_HEADER address
*/
movb $0x69, %ah
jmp .Lhlt
bisthalt:
movb $0xB9, %ah
jmp .Lhlt
halt1:
/*
* Failures for postcode 0xBA - failed in find_fsp()
*
* Values are:
* 0x01 - FV signature, "_FVH" not present
* 0x02 - FFS GUID not present
* 0x03 - FSP INFO Header not found
* 0x04 - ImageBase does not equal CONFIG_FSP_LOC - Is the FSP rebased to
* a different location, or does it need to be?
* 0x05 - FSP INFO Header signature "FSPH" not found
* 0x06 - FSP Image ID is not the expected ID.
*/
movb $0xBA, %ah
jmp .Lhlt
halt2:
/*
* Failures for postcode 0xBB - failed in the FSP:
*
* 0x00 - FSP_SUCCESS: Temp RAM was initialized successfully.
* 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
* 0x0E - FSP_NOT_FOUND: No valid microcode was found in the microcode region.
* 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
* 0x07 - FSP_DEVICE_ERROR: Temp RAM initialization failed
* 0x14 - FSP_ALREADY_STARTED: Temp RAM initialization has been invoked
*/
movb $0xBB, %ah
.Lhlt:
xchg %al, %ah
#if CONFIG_POST_IO
outb %al, $CONFIG_POST_IO_PORT
#else
post_code(POST_DEAD_CODE)
#endif
movl $LHLT_DELAY, %ecx
.Lhlt_Delay:
outb %al, $0xED
loop .Lhlt_Delay
jmp .Lhlt
/*
* esp is set to this location so that the call into and return from the FSP
* in find_fsp will work.
*/
.align 4
fake_fsp_stack:
.long find_fsp_ret
CAR_init_params:
.long CONFIG_CPU_MICROCODE_CBFS_LOC /* Microcode Location */
.long CONFIG_CPU_MICROCODE_CBFS_LEN /* Microcode Length */
.long 0xFFFFFFFF - CONFIG_CBFS_SIZE + 1 /* Firmware Location */
.long CONFIG_CBFS_SIZE /* Total Firmware Length */
CAR_init_stack:
.long CAR_init_done
.long CAR_init_params

View file

@ -38,10 +38,13 @@
#include <soc/reset.h>
#include <soc/romstage.h>
#include <soc/spi.h>
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
#include <fsp_util.h>
#endif /* CONFIG_PLATFORM_USES_FSP */
/* Entry from cache-as-ram.inc. */
void * asmlinkage romstage_main(unsigned long bist,
uint32_t tsc_low, uint32_t tsc_hi)
asmlinkage void *romstage_main(unsigned int bist,
uint32_t tsc_low, uint32_t tsc_hi)
{
struct romstage_params rp = {
.bist = bist,
@ -66,6 +69,32 @@ void * asmlinkage romstage_main(unsigned long bist,
/* Start console drivers */
console_init();
/* Display parameters */
printk(BIOS_SPEW, "bist: 0x%08x\n", bist);
printk(BIOS_SPEW, "tsc_low: 0x%08x\n", tsc_low);
printk(BIOS_SPEW, "tsc_hi: 0x%08x\n", tsc_hi);
printk(BIOS_SPEW, "CONFIG_MMCONF_BASE_ADDRESS: 0x%08x\n",
CONFIG_MMCONF_BASE_ADDRESS);
printk(BIOS_INFO, "Using: %s\n",
IS_ENABLED(CONFIG_PLATFORM_USES_FSP) ? "FSP" :
(IS_ENABLED(CONFIG_HAVE_MRC) ? "MRC" :
"No Memory Support"));
/* Display FSP banner */
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
printk(BIOS_DEBUG, "FSP TempRamInit successful\n");
print_fsp_info(find_fsp());
#endif /* CONFIG_PLATFORM_USES_FSP */
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
/* TODO: Remove this code. Temporary code to hang after FSP TempRamInit API */
printk(BIOS_DEBUG, "Hanging in romstage_main!\n");
post_code(0x35);
while (1)
;
#endif /* CONFIG_PLATFORM_USES_FSP */
/* Get power state */
rp.power_state = fill_power_state();