diff --git a/configs/config.samus.fsp b/configs/config.samus.fsp new file mode 100644 index 0000000000..7b2f716f48 --- /dev/null +++ b/configs/config.samus.fsp @@ -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 diff --git a/src/drivers/intel/Kconfig b/src/drivers/intel/Kconfig index 9954f31e03..a94e06e4d0 100644 --- a/src/drivers/intel/Kconfig +++ b/src/drivers/intel/Kconfig @@ -18,3 +18,4 @@ ## source src/drivers/intel/gma/Kconfig +source src/drivers/intel/fsp/Kconfig diff --git a/src/drivers/intel/fsp/Kconfig b/src/drivers/intel/fsp/Kconfig index 2d41365320..19147cdd18 100644 --- a/src/drivers/intel/fsp/Kconfig +++ b/src/drivers/intel/fsp/Kconfig @@ -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 diff --git a/src/drivers/intel/fsp/Makefile.inc b/src/drivers/intel/fsp/Makefile.inc index 280f7b94db..e1bf7d9adb 100644 --- a/src/drivers/intel/fsp/Makefile.inc +++ b/src/drivers/intel/fsp/Makefile.inc @@ -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 diff --git a/src/drivers/intel/fsp/fastboot_cache.c b/src/drivers/intel/fsp/fastboot_cache.c index 64982d8dc1..91796c6e78 100644 --- a/src/drivers/intel/fsp/fastboot_cache.c +++ b/src/drivers/intel/fsp/fastboot_cache.c @@ -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, - ®ion_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", diff --git a/src/drivers/intel/fsp/fsp_hob.c b/src/drivers/intel/fsp/fsp_hob.c new file mode 100644 index 0000000000..a64ac349a9 --- /dev/null +++ b/src/drivers/intel/fsp/fsp_hob.c @@ -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 +#include +#include +#include +#include "fsp_util.h" +#include +#include // hexdump +#include + +#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), +}; diff --git a/src/drivers/intel/fsp/fsp_util.c b/src/drivers/intel/fsp/fsp_util.c index a9b5624676..d0f9ef4a01 100644 --- a/src/drivers/intel/fsp/fsp_util.c +++ b/src/drivers/intel/fsp/fsp_util.c @@ -17,416 +17,157 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include #include -#include -#include #include "fsp_util.h" -#include // hexdump -#include #include -#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(¬ify_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__ */ diff --git a/src/drivers/intel/fsp/fsp_util.h b/src/drivers/intel/fsp/fsp_util.h index db8b6dec1d..6ef478874c 100644 --- a/src/drivers/intel/fsp/fsp_util.h +++ b/src/drivers/intel/fsp/fsp_util.h @@ -20,6 +20,21 @@ #ifndef FSP_UTIL_H #define FSP_UTIL_H +#include +#include + +/* + * 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 #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__ diff --git a/src/drivers/intel/fsp/fsp_util_1_0.c b/src/drivers/intel/fsp/fsp_util_1_0.c new file mode 100644 index 0000000000..a4bbdbac19 --- /dev/null +++ b/src/drivers/intel/fsp/fsp_util_1_0.c @@ -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 +#include +#include "fsp_util.h" +#include + +#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__ */ diff --git a/src/soc/intel/broadwell/Kconfig b/src/soc/intel/broadwell/Kconfig index 41823cfc82..fffef0beed 100644 --- a/src/soc/intel/broadwell/Kconfig +++ b/src/soc/intel/broadwell/Kconfig @@ -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 diff --git a/src/soc/intel/broadwell/Makefile.inc b/src/soc/intel/broadwell/Makefile.inc index bb61d4c7ae..d2aa4a3c13 100644 --- a/src/soc/intel/broadwell/Makefile.inc +++ b/src/soc/intel/broadwell/Makefile.inc @@ -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 diff --git a/src/soc/intel/broadwell/include/chipset_fsp_util.h b/src/soc/intel/broadwell/include/chipset_fsp_util.h new file mode 100644 index 0000000000..4eac4c496f --- /dev/null +++ b/src/soc/intel/broadwell/include/chipset_fsp_util.h @@ -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 data types */ +#include /* FSP API definitions */ +#include /* FSP binary layout */ +#include /* UEFI boot mode definitions */ +#include /* UEFI file definitions */ +#include /* UEFI file system defs */ +#include /* UEFI memory types */ +#include /* Hand off block definitions */ +#include /* HOB routine declarations */ +#include /* Vital/updatable product data definitions*/ + +#endif /* CHIPSET_FSP_UTIL_H */ diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index b636223561..23c233b9a9 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -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); diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc index f8a961795b..d64e645f62 100644 --- a/src/soc/intel/broadwell/romstage/Makefile.inc +++ b/src/soc/intel/broadwell/romstage/Makefile.inc @@ -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 + diff --git a/src/soc/intel/broadwell/romstage/fsp_1_1.inc b/src/soc/intel/broadwell/romstage/fsp_1_1.inc new file mode 100644 index 0000000000..fdb7df1e2e --- /dev/null +++ b/src/soc/intel/broadwell/romstage/fsp_1_1.inc @@ -0,0 +1,229 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2000,2007 Ronald G. Minnich + * 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 +#include +#include +#include +#include + +#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 + diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index df9ebf1108..644b3fad6d 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -38,10 +38,13 @@ #include #include #include +#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP) +#include +#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();