From 102b3840ddd2132b04d56b468ca8a9ebcbe6b6dd Mon Sep 17 00:00:00 2001 From: Lee Leahy Date: Wed, 19 Nov 2014 15:24:56 -0800 Subject: [PATCH] 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 Change-Id: I02e1ea422644da1f6285812dd36045a70e0f4324 Reviewed-on: https://chromium-review.googlesource.com/231285 Reviewed-by: Duncan Laurie --- configs/config.samus.fsp | 1 + src/mainboard/google/samus/Makefile.inc | 2 + src/mainboard/google/samus/fsp.c | 56 +++++++++ .../intel/broadwell/include/soc/romstage.h | 44 ++++--- src/soc/intel/broadwell/memmap.c | 5 + src/soc/intel/broadwell/romstage/Makefile.inc | 3 +- src/soc/intel/broadwell/romstage/fsp.c | 108 ++++++++++++++++++ src/soc/intel/broadwell/romstage/raminit.c | 64 +---------- src/soc/intel/broadwell/romstage/romstage.c | 80 ++++++++++--- 9 files changed, 266 insertions(+), 97 deletions(-) create mode 100644 src/mainboard/google/samus/fsp.c create mode 100644 src/soc/intel/broadwell/romstage/fsp.c diff --git a/configs/config.samus.fsp b/configs/config.samus.fsp index 7b2f716f48..e97b184b85 100644 --- a/configs/config.samus.fsp +++ b/configs/config.samus.fsp @@ -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 diff --git a/src/mainboard/google/samus/Makefile.inc b/src/mainboard/google/samus/Makefile.inc index 63edf1bea3..9bf6ff2a44 100644 --- a/src/mainboard/google/samus/Makefile.inc +++ b/src/mainboard/google/samus/Makefile.inc @@ -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 diff --git a/src/mainboard/google/samus/fsp.c b/src/mainboard/google/samus/fsp.c new file mode 100644 index 0000000000..3c10fb25c3 --- /dev/null +++ b/src/mainboard/google/samus/fsp.c @@ -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 +#include +#include // hexdump +#include +#include +#include + +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)(¶ms->pei_data->spd_data[0][0]); + upd_data->SpdDataBuffer_1_0 = + (UINT32)(¶ms->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; +} + diff --git a/src/soc/intel/broadwell/include/soc/romstage.h b/src/soc/intel/broadwell/include/soc/romstage.h index 23c233b9a9..0c0e6b8c7a 100644 --- a/src/soc/intel/broadwell/include/soc/romstage.h +++ b/src/soc/intel/broadwell/include/soc/romstage.h @@ -22,9 +22,12 @@ #include #include +#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP) +#include +#endif /* CONFIG_PLATFORM_USES_FSP */ +#include +#include -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; diff --git a/src/soc/intel/broadwell/memmap.c b/src/soc/intel/broadwell/memmap.c index 370349c686..dd4856575a 100644 --- a/src/soc/intel/broadwell/memmap.c +++ b/src/soc/intel/broadwell/memmap.c @@ -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; } diff --git a/src/soc/intel/broadwell/romstage/Makefile.inc b/src/soc/intel/broadwell/romstage/Makefile.inc index d64e645f62..8486e3f341 100644 --- a/src/soc/intel/broadwell/romstage/Makefile.inc +++ b/src/soc/intel/broadwell/romstage/Makefile.inc @@ -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 diff --git a/src/soc/intel/broadwell/romstage/fsp.c b/src/soc/intel/broadwell/romstage/fsp.c new file mode 100644 index 0000000000..dd21aaef47 --- /dev/null +++ b/src/soc/intel/broadwell/romstage/fsp.c @@ -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 +#include +#include +#include // hexdump +#include +#include +#include +#include + +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); +} diff --git a/src/soc/intel/broadwell/romstage/raminit.c b/src/soc/intel/broadwell/romstage/raminit.c index 4e68ea7971..c541299ac7 100644 --- a/src/soc/intel/broadwell/romstage/raminit.c +++ b/src/soc/intel/broadwell/romstage/raminit.c @@ -18,73 +18,23 @@ */ #include -#include -#include #include #include #include -#include #include -#include -#if CONFIG_EC_GOOGLE_CHROMEEC -#include -#include -#endif -#include -#include -#include -#include #include -#include #include #include -#include #include /* * 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)); - } diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index 644b3fad6d..2f8b04a0e9 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -27,20 +27,20 @@ #include #include #include +#include +#include #include #include #include #include #include #include -#include +#include +#include #include #include #include #include -#if IS_ENABLED(CONFIG_PLATFORM_USES_FSP) -#include -#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(¶ms->power_state->hsio_version, ¶ms->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 ==