Broadwell FSP: Successful execution of TempRamInit

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

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

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

View file

@ -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();