Broadwell FSP: Successful execution of MemoryInit

Repartition the RAM initialization code to share the setup and caching
support.  Display the parameters for the MemoryInit call.  Initialize
memory using the FSP binary.  Upon return display the HOBs and memory
configuration before hanging displaying POST code 0x35.

BRANCH=none
BUG=None
TEST=Use the following steps to reproduce:
1.  Get the private FSP parts
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_common

Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Change-Id: I02e1ea422644da1f6285812dd36045a70e0f4324
Reviewed-on: https://chromium-review.googlesource.com/231285
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
This commit is contained in:
Lee Leahy 2014-11-19 15:24:56 -08:00 committed by chrome-internal-fetch
commit 102b3840dd
9 changed files with 266 additions and 97 deletions

View file

@ -33,6 +33,7 @@ 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_FSP_RESERVED_MEM_SIZE=0x00400000
CONFIG_HAVE_FSP_BIN=y
CONFIG_MMCONF_BASE_ADDRESS=0xe0000000
CONFIG_PLATFORM_USES_FSP=y

View file

@ -31,3 +31,5 @@ ramstage-y += pei_data.c
romstage-y += board_version.c
ramstage-y += board_version.c
romstage-$(CONFIG_PLATFORM_USES_FSP) += fsp.c

View file

@ -0,0 +1,56 @@
/*
* 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
*/
#include <arch/early_variables.h>
#include <console/console.h>
#include <lib.h> // hexdump
#include <mainboard/google/samus/spd/spd.h>
#include <soc/iomap.h>
#include <soc/romstage.h>
void board_fsp_memory_init_params(
struct romstage_params *params,
FSP_INFO_HEADER *fsp_header,
FSP_MEMORY_INIT_PARAMS *fsp_memory_init_params)
{
FSP_INIT_RT_COMMON_BUFFER *rt_buffer;
UPD_DATA_REGION *upd_data;
/* Set the memory configuration */
rt_buffer = fsp_memory_init_params->RtBufferPtr;
upd_data = rt_buffer->UpdDataRgnPtr;
if (params->pei_data->spd_data[0][0][0] != 0) {
upd_data->SpdDataBuffer_0_0 =
(UINT32)(&params->pei_data->spd_data[0][0]);
upd_data->SpdDataBuffer_1_0 =
(UINT32)(&params->pei_data->spd_data[1][0]);
printk(BIOS_SPEW, "0x%08x: SpdDataBuffer_0_0\n",
upd_data->SpdDataBuffer_0_0);
printk(BIOS_SPEW, "0x%08x: SpdDataBuffer_0_1\n",
upd_data->SpdDataBuffer_0_1);
printk(BIOS_SPEW, "0x%08x: SpdDataBuffer_1_0\n",
upd_data->SpdDataBuffer_0_0);
printk(BIOS_SPEW, "0x%08x: SpdDataBuffer_1_1\n",
upd_data->SpdDataBuffer_0_1);
}
/* Enable/disable the devices */
upd_data->PcdEnableLan = 0;
}

View file

@ -22,9 +22,12 @@
#include <stdint.h>
#include <arch/cpu.h>
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
#include <fsp_util.h>
#endif /* CONFIG_PLATFORM_USES_FSP */
#include <soc/pei_data.h>
#include <soc/pm.h>
struct chipset_power_state;
struct pei_data;
struct romstage_params {
unsigned long bist;
struct chipset_power_state *power_state;
@ -43,22 +46,21 @@ struct romstage_params {
* 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
* 11. src/mainboard/.../fsp.c/board_fsp_memory_init_params
* 12. FSP binary/MemoryInit
* 13. src/soc/intel/broadwell/romstage/romstage.c/romstage_common - return
* 14. src/mainboard/.../romstage.c/mainboard_romstage_entry - return
* 15. src/soc/intel/broadwell/romstage/romstage.c/romstage_main - return
* 16. src/soc/intel/broadwell/stack.c/setup_stack_and_mttrs
* 17. 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
* 18. FSP binary/TempRamExit
* 19. src/soc/intel/broadwell/romstage.c/romstage_after_car
* 20. FSP binary/SiliconInit
* 21. src/soc/intel/broadwell/romstage.c/romstage_after_car - return
* 22. src/soc/intel/broadwell/chip.c/broadwell_final
* 23. src/drivers/intel/fsp/fsp_util.c/fsp_notify
* 24. FSP binary/FspNotify
*
*
* MRC Boot Flow:
@ -83,8 +85,14 @@ 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);
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
void board_fsp_memory_init_params(
struct romstage_params *params,
FSP_INFO_HEADER *fsp_header,
FSP_MEMORY_INIT_PARAMS *fsp_memory_init_params);
#endif /* CONFIG_PLATFORM_USES_FSP */
void asmlinkage romstage_after_car(void);
void raminit(struct pei_data *pei_data);
void raminit(struct romstage_params *params, struct pei_data *pei_data);
void *setup_stack_and_mttrs(void);
struct chipset_power_state;

View file

@ -37,6 +37,11 @@ static unsigned long get_top_of_ram(void)
if (dpr & DPR_EPM)
tom -= (dpr & DPR_SIZE_MASK) << 16;
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
/* Allocate some space for FSP */
tom -= CONFIG_FSP_RESERVED_MEM_SIZE;
#endif /* CONFIG_PLATFORM_USES_FSP */
return (unsigned long)tom;
}

View file

@ -7,9 +7,10 @@ endif
endif
romstage-y += cpu.c
romstage-$(CONFIG_PLATFORM_USES_FSP) += fsp.c
romstage-y += pch.c
romstage-y += power_state.c
romstage-y += raminit.c
romstage-$(CONFIG_HAVE_MRC) += raminit.c
romstage-y += report_platform.c
romstage-y += romstage.c
romstage-y += smbus.c

View file

@ -0,0 +1,108 @@
/*
* 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
*/
#include <cbmem.h>
#include <console/console.h>
#include <fsp_util.h>
#include <lib.h> // hexdump
#include <soc/pei_data.h>
#include <soc/reset.h>
#include <soc/romstage.h>
#include <string.h>
void raminit(struct romstage_params *params, struct pei_data *pei_data)
{
FSP_INFO_HEADER *fsp_header;
FSP_MEMORY_INIT fsp_memory_init;
FSP_MEMORY_INIT_PARAMS fsp_memory_init_params;
FSP_INIT_RT_COMMON_BUFFER fsp_rt_common_buffer;
void *hob_list_ptr;
EFI_STATUS status;
VPD_DATA_REGION *vpd_data;
UPD_DATA_REGION *upd_data;
UPD_DATA_REGION upd_data_buffer;
/* Find and copy the UPD region to the stack so the platform can modify
* the settings if needed. Modifications to the UPD buffer are done in
* the platform callback code. The platform callback code is also
* responsible for assigning the UpdDataRngPtr to this buffer if any
* updates are made. The default state is to leave the UpdDataRngPtr
* set to NULL. This indicates that the FSP code will use the UPD
* region in the FSP binary.*/
fsp_header = find_fsp();
vpd_data = (VPD_DATA_REGION *)(fsp_header->CfgRegionOffset +
fsp_header->ImageBase);
printk(BIOS_DEBUG, "VPD Data: 0x%p\n", vpd_data);
upd_data = (UPD_DATA_REGION *)(vpd_data->PcdUpdRegionOffset +
fsp_header->ImageBase);
printk(BIOS_DEBUG, "UPD Data: 0x%p\n", upd_data);
memcpy(&upd_data_buffer, upd_data, sizeof(upd_data_buffer));
/* Zero fill RT Buffer data and start populating fields. */
memset(&fsp_rt_common_buffer, sizeof(fsp_rt_common_buffer), 0);
fsp_rt_common_buffer.BootMode = pei_data->boot_mode;
fsp_rt_common_buffer.UpdDataRgnPtr = &upd_data_buffer;
/* Get any board specific changes */
fsp_memory_init_params.NvsBufferPtr = NULL;
fsp_memory_init_params.RtBufferPtr = &fsp_rt_common_buffer;
fsp_memory_init_params.HobListPtr = &hob_list_ptr;
board_fsp_memory_init_params(params, fsp_header,
&fsp_memory_init_params);
/* Display the UPD data */
printk(BIOS_SPEW, "Updated Product Data (UPD):\n");
hexdump32(BIOS_SPEW, (void *)&upd_data_buffer, sizeof(upd_data_buffer));
/* Call FspMemoryInit to initialize RAM */
fsp_memory_init = (FSP_MEMORY_INIT)(fsp_header->ImageBase
+ fsp_header->FspMemoryInitEntryOffset);
printk(BIOS_DEBUG, "Calling FspMemoryInit: 0x%p\n", fsp_memory_init);
printk(BIOS_SPEW, " 0x%p: NvsBufferPtr\n",
fsp_memory_init_params.NvsBufferPtr);
printk(BIOS_SPEW, " 0x%p: RtBufferPtr\n",
fsp_memory_init_params.RtBufferPtr);
printk(BIOS_SPEW, " 0x%p: HobListPtr\n",
fsp_memory_init_params.HobListPtr);
status = fsp_memory_init(&fsp_memory_init_params);
printk(BIOS_DEBUG, "FspMemoryInit returned 0x%08x\n", status);
if (status != EFI_SUCCESS)
die("ERROR - FspMemoryInit failed to initialize memory!\n");
/* Display the memory configuration */
report_memory_config();
if (pei_data->boot_mode != SLEEP_STATE_S3) {
cbmem_initialize_empty();
} else if (cbmem_initialize()) {
#if CONFIG_HAVE_ACPI_RESUME
printk(BIOS_DEBUG, "Failed to recover CBMEM in S3 resume.\n");
/* Failed S3 resume, reset to come up cleanly */
reset_system();
#endif
}
/* Save the HOB list */
set_hob_list(hob_list_ptr);
/* Display the HOBs */
if (hob_list_ptr == NULL)
die("ERROR - HOB pointer is NULL!\n");
print_hob_type_structure(0, hob_list_ptr);
}

View file

@ -18,73 +18,23 @@
*/
#include <arch/cbfs.h>
#include <arch/hlt.h>
#include <arch/io.h>
#include <cbfs.h>
#include <cbmem.h>
#include <console/console.h>
#include <device/pci_def.h>
#include <lib.h>
#include <string.h>
#if CONFIG_EC_GOOGLE_CHROMEEC
#include <ec/google/chromeec/ec.h>
#include <ec/google/chromeec/ec_commands.h>
#endif
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/intel/common/mrc_cache.h>
#include <soc/iomap.h>
#include <soc/pei_data.h>
#include <soc/pei_wrapper.h>
#include <soc/pm.h>
#include <soc/reset.h>
#include <soc/romstage.h>
#include <soc/smm.h>
#include <soc/systemagent.h>
/*
* Find PEI executable in coreboot filesystem and execute it.
*/
void raminit(struct pei_data *pei_data)
void raminit(struct romstage_params *params, struct pei_data *pei_data)
{
const struct mrc_saved_data *cache;
struct memory_info* mem_info;
pei_wrapper_entry_t entry;
int ret;
broadwell_fill_pei_data(pei_data);
if (recovery_mode_enabled()) {
/* Recovery mode does not use MRC cache */
printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n");
} else if (!mrc_cache_get_current(&cache)) {
/* MRC cache found */
pei_data->saved_data_size = cache->size;
pei_data->saved_data = &cache->data[0];
} else if (pei_data->boot_mode == SLEEP_STATE_S3) {
/* Waking from S3 and no cache. */
printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n");
post_code(POST_RESUME_FAILURE);
reset_system();
} else {
printk(BIOS_DEBUG, "No MRC cache found.\n");
#if CONFIG_EC_GOOGLE_CHROMEEC
if (pei_data->boot_mode == SLEEP_STATE_S0) {
/* Ensure EC is running RO firmware. */
google_chromeec_check_ec_image(EC_IMAGE_RO);
}
#endif
}
/*
* Do not use saved pei data. Can be set by mainboard romstage
* to force a full train of memory on every boot.
*/
if (pei_data->disable_saved_data) {
printk(BIOS_DEBUG, "Disabling PEI saved data by request\n");
pei_data->saved_data = NULL;
pei_data->saved_data_size = 0;
}
/* Determine if mrc.bin is in the cbfs. */
entry = (pei_wrapper_entry_t)cbfs_get_file_content(
CBFS_DEFAULT_MEDIA, "mrc.bin", 0xab);
@ -119,16 +69,4 @@ void raminit(struct pei_data *pei_data)
reset_system();
#endif
}
printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save,
pei_data->data_to_save_size);
if (pei_data->data_to_save != NULL && pei_data->data_to_save_size > 0)
mrc_cache_stash_data(pei_data->data_to_save,
pei_data->data_to_save_size);
printk(BIOS_DEBUG, "create cbmem for dimm information\n");
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
memcpy(mem_info, &pei_data->meminfo, sizeof(struct memory_info));
}

View file

@ -27,20 +27,20 @@
#include <console/console.h>
#include <cbmem.h>
#include <cpu/x86/mtrr.h>
#include <ec/google/chromeec/ec.h>
#include <ec/google/chromeec/ec_commands.h>
#include <elog.h>
#include <ramstage_cache.h>
#include <romstage_handoff.h>
#include <timestamp.h>
#include <vendorcode/google/chromeos/chromeos.h>
#include <soc/me.h>
#include <soc/pei_data.h>
#include <soc/intel/common/mrc_cache.h>
#include <soc/pei_wrapper.h>
#include <soc/pm.h>
#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. */
asmlinkage void *romstage_main(unsigned int bist,
@ -86,15 +86,6 @@ asmlinkage void *romstage_main(unsigned int bist,
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();
@ -122,12 +113,14 @@ static inline void chromeos_init(int prev_sleep_state)
void romstage_common(struct romstage_params *params)
{
struct romstage_handoff *handoff;
struct pei_data *pei_data;
post_code(0x32);
timestamp_add_now(TS_BEFORE_INITRAM);
params->pei_data->boot_mode = params->power_state->prev_sleep_state;
pei_data = params->pei_data;
pei_data->boot_mode = params->power_state->prev_sleep_state;
#if CONFIG_ELOG_BOOT_COUNT
if (params->power_state->prev_sleep_state != SLEEP_STATE_S3)
@ -141,10 +134,67 @@ void romstage_common(struct romstage_params *params)
intel_me_hsio_version(&params->power_state->hsio_version,
&params->power_state->hsio_checksum);
/* Prepare to initialize memory */
const struct mrc_saved_data *cache;
struct memory_info *mem_info;
broadwell_fill_pei_data(pei_data);
if (recovery_mode_enabled()) {
/* Recovery mode does not use MRC cache */
printk(BIOS_DEBUG, "Recovery mode: not using MRC cache.\n");
} else if (!mrc_cache_get_current(&cache)) {
/* MRC cache found */
pei_data->saved_data_size = cache->size;
pei_data->saved_data = &cache->data[0];
} else if (pei_data->boot_mode == SLEEP_STATE_S3) {
/* Waking from S3 and no cache. */
printk(BIOS_DEBUG, "No MRC cache found in S3 resume path.\n");
post_code(POST_RESUME_FAILURE);
reset_system();
} else {
printk(BIOS_DEBUG, "No MRC cache found.\n");
#if CONFIG_EC_GOOGLE_CHROMEEC
if (pei_data->boot_mode == SLEEP_STATE_S0) {
/* Ensure EC is running RO firmware. */
google_chromeec_check_ec_image(EC_IMAGE_RO);
}
#endif
}
/*
* Do not use saved pei data. Can be set by mainboard romstage
* to force a full train of memory on every boot.
*/
if (pei_data->disable_saved_data) {
printk(BIOS_DEBUG, "Disabling PEI saved data by request\n");
pei_data->saved_data = NULL;
pei_data->saved_data_size = 0;
}
/* Initialize RAM */
raminit(params->pei_data);
raminit(params, pei_data);
timestamp_add_now(TS_AFTER_INITRAM);
#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP)
/* TODO: Remove this code. Temporary code to hang after FspMemoryInit API */
printk(BIOS_DEBUG, "Hanging in romstage_common!\n");
post_code(0x35);
while (1)
;
#endif /* CONFIG_PLATFORM_USES_FSP */
printk(BIOS_DEBUG, "MRC data at %p %d bytes\n", pei_data->data_to_save,
pei_data->data_to_save_size);
if (pei_data->data_to_save != NULL && pei_data->data_to_save_size > 0)
mrc_cache_stash_data(pei_data->data_to_save,
pei_data->data_to_save_size);
printk(BIOS_DEBUG, "create cbmem for dimm information\n");
mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
memcpy(mem_info, &pei_data->meminfo, sizeof(struct memory_info));
handoff = romstage_handoff_find_or_add();
if (handoff != NULL)
handoff->s3_resume = (params->power_state->prev_sleep_state ==