diff --git a/src/soc/intel/broadwell/romstage/romstage.c b/src/soc/intel/broadwell/romstage/romstage.c index d22ec52d89..f77f9141e0 100644 --- a/src/soc/intel/broadwell/romstage/romstage.c +++ b/src/soc/intel/broadwell/romstage/romstage.c @@ -17,238 +17,140 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include #include +#include #include -#include -#include -#include +#include +#include +#include +#include +#include #include #include -#include +#include #include -#if CONFIG_EC_GOOGLE_CHROMEEC -#include -#endif -#include "haswell.h" -#include "northbridge/intel/haswell/haswell.h" -#include "northbridge/intel/haswell/raminit.h" -#include "southbridge/intel/lynxpoint/pch.h" -#include "southbridge/intel/lynxpoint/me.h" +#include +#include +#include +#include +#include +#include - -static inline void reset_system(void) +static inline void mark_ts(struct romstage_params *rp, uint64_t ts) { - hard_reset(); - while (1) { - hlt(); - } + struct romstage_timestamps *rt = &rp->ts; + + rt->times[rt->count] = ts; + rt->count++; } -/* The cache-as-ram assembly file calls romstage_main() after setting up - * cache-as-ram. romstage_main() will then call the mainboards's - * mainboard_romstage_entry() function. That function then calls - * romstage_common() below. The reason for the back and forth is to provide - * common entry point from cache-as-ram while still allowing for code sharing. - * Because we can't use global variables the stack is used for allocations -- - * thus the need to call back and forth. */ - -void * asmlinkage romstage_main(unsigned long bist) +/* Entry from cache-as-ram.inc. */ +void * asmlinkage romstage_main(unsigned long bist, + uint32_t tsc_low, uint32_t tsc_hi) { - int i; - void *romstage_stack_after_car; - const int num_guards = 4; - const u32 stack_guard = 0xdeadbeef; - u32 *stack_base = (void *)(CONFIG_DCACHE_RAM_BASE + - CONFIG_DCACHE_RAM_SIZE - - CONFIG_DCACHE_RAM_ROMSTAGE_STACK_SIZE); + struct romstage_params rp = { + .bist = bist, + .pei_data = NULL, + }; - printk(BIOS_DEBUG, "Setting up stack guards.\n"); - for (i = 0; i < num_guards; i++) - stack_base[i] = stack_guard; + post_code(0x30); - mainboard_romstage_entry(bist); + /* Save initial timestamp from bootblock. */ + mark_ts(&rp, (((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low); - /* Check the stack. */ - for (i = 0; i < num_guards; i++) { - if (stack_base[i] == stack_guard) - continue; - printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n"); - } + /* Save romstage begin */ + mark_ts(&rp, timestamp_get()); - /* Get the stack to use after cache-as-ram is torn down. */ - romstage_stack_after_car = setup_romstage_stack_after_car(); + /* System Agent Early Initialization */ + systemagent_early_init(); - return romstage_stack_after_car; -} + /* PCH Early Initialization */ + pch_early_init(); -void romstage_common(const struct romstage_params *params) -{ - int boot_mode; - int wake_from_s3; - struct romstage_handoff *handoff; - -#if CONFIG_COLLECT_TIMESTAMPS - uint64_t start_romstage_time; - uint64_t before_dram_time; - uint64_t after_dram_time; - uint64_t base_time = - (uint64_t)pci_read_config32(PCI_DEV(0, 0x1f, 2), 0xd0) << 32 || - pci_read_config32(PCI_DEV(0, 0x00, 0), 0xdc); -#endif - -#if CONFIG_COLLECT_TIMESTAMPS - start_romstage_time = timestamp_get(); -#endif - - if (params->bist == 0) - enable_lapic(); - - wake_from_s3 = early_pch_init(params->gpio_map, params->rcba_config); - -#if CONFIG_EC_GOOGLE_CHROMEEC - /* Ensure the EC is in the right mode for recovery */ - google_chromeec_early_init(); -#endif - - /* Halt if there was a built in self test failure */ - report_bist_failure(params->bist); - - /* Perform some early chipset initialization required - * before RAM initialization can work - */ - haswell_early_initialization(HASWELL_MOBILE); - printk(BIOS_DEBUG, "Back from haswell_early_initialization()\n"); - - if (wake_from_s3) { -#if CONFIG_HAVE_ACPI_RESUME - printk(BIOS_DEBUG, "Resume from S3 detected.\n"); -#else - printk(BIOS_DEBUG, "Resume from S3 detected, but disabled.\n"); - wake_from_s3 = 0; -#endif - } - - /* There are hard coded assumptions of 2 meaning s3 wake. Normalize - * the users of the 2 literal here based off wake_from_s3. */ - boot_mode = wake_from_s3 ? 2 : 0; - - /* Prepare USB controller early in S3 resume */ - if (wake_from_s3) - enable_usb_bar(); - - post_code(0x3a); - params->pei_data->boot_mode = boot_mode; -#if CONFIG_COLLECT_TIMESTAMPS - before_dram_time = timestamp_get(); -#endif + /* Start console drivers */ + console_init(); + /* Print useful platform information */ report_platform_info(); - if (params->copy_spd != NULL) - params->copy_spd(params->pei_data); - sdram_initialize(params->pei_data); + /* Call into mainboard. */ + mainboard_romstage_entry(&rp); -#if CONFIG_COLLECT_TIMESTAMPS - after_dram_time = timestamp_get(); + return setup_stack_and_mttrs(); +} + +static inline void chromeos_init(int prev_sleep_state) +{ +#if CONFIG_CHROMEOS + /* Normalize the sleep state to what init_chromeos() wants for S3: 2 */ + init_chromeos(prev_sleep_state == SLEEP_STATE_S3 ? 2 : 0); #endif - post_code(0x3b); +} - intel_early_me_status(); +/* Entry from the mainboard. */ +void romstage_common(struct romstage_params *params) +{ + struct chipset_power_state *ps; + struct romstage_handoff *handoff; - quick_ram_check(); - post_code(0x3e); + post_code(0x32); - if (!wake_from_s3) { - cbmem_initialize_empty(); - /* Save data returned from MRC on non-S3 resumes. */ - save_mrc_data(params->pei_data); - } else if (cbmem_initialize()) { - #if CONFIG_HAVE_ACPI_RESUME - /* Failed S3 resume, reset to come up cleanly */ - reset_system(); - #endif - } + mark_ts(params, timestamp_get()); + + /* Get power state */ + ps = fill_power_state(); + params->pei_data->boot_mode = ps->prev_sleep_state; + +#if CONFIG_ELOG_BOOT_COUNT + if (ps->prev_sleep_state != SLEEP_STATE_S3) + boot_count_increment(); +#endif + + /* Print ME state before MRC */ + intel_me_status(); + + /* Initialize RAM */ + raminit(params->pei_data); + mark_ts(params, timestamp_get()); handoff = romstage_handoff_find_or_add(); if (handoff != NULL) - handoff->s3_resume = wake_from_s3; + handoff->s3_resume = (ps->prev_sleep_state == SLEEP_STATE_S3); else printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); - post_code(0x3f); -#if CONFIG_CHROMEOS - init_chromeos(boot_mode); -#endif -#if CONFIG_COLLECT_TIMESTAMPS - timestamp_init(base_time); - timestamp_add(TS_START_ROMSTAGE, start_romstage_time ); - timestamp_add(TS_BEFORE_INITRAM, before_dram_time ); - timestamp_add(TS_AFTER_INITRAM, after_dram_time ); + chromeos_init(ps->prev_sleep_state); + + /* Save timestamp information. */ + timestamp_init(params->ts.times[0]); + timestamp_add(TS_START_ROMSTAGE, params->ts.times[1]); + timestamp_add(TS_BEFORE_INITRAM, params->ts.times[2]); + timestamp_add(TS_AFTER_INITRAM, params->ts.times[3]); +} + +void asmlinkage romstage_after_car(void) +{ timestamp_add_now(TS_END_ROMSTAGE); -#endif -} -static inline void prepare_for_resume(struct romstage_handoff *handoff) -{ -/* Only need to save memory when ramstage isn't relocatable. */ -#if !CONFIG_RELOCATABLE_RAMSTAGE -#if CONFIG_HAVE_ACPI_RESUME - /* Back up the OS-controlled memory where ramstage will be loaded. */ - if (handoff != NULL && handoff->s3_resume) { - void *src = (void *)CONFIG_RAMBASE; - void *dest = cbmem_find(CBMEM_ID_RESUME); - if (dest != NULL) - memcpy(dest, src, HIGH_MEMORY_SAVE); - } -#endif -#endif -} - -void romstage_after_car(void) -{ - struct romstage_handoff *handoff; - - handoff = romstage_handoff_find_or_add(); - - prepare_for_resume(handoff); - - vboot_verify_firmware(handoff); + /* Run vboot verification if configured. */ + vboot_verify_firmware(romstage_handoff_find_or_add()); /* Load the ramstage. */ copy_and_run(); -} - - -#if CONFIG_RELOCATABLE_RAMSTAGE -#include - -struct ramstage_cache *ramstage_cache_location(long *size) -{ - /* The ramstage cache lives in the TSEG region at RESERVED_SMM_OFFSET. - * The top of ram is defined to be the TSEG base address. */ - *size = RESERVED_SMM_SIZE; - return (void *)(get_top_of_ram() + RESERVED_SMM_OFFSET); + while (1); } void ramstage_cache_invalid(struct ramstage_cache *cache) { #if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE + /* Perform cold reset on invalid ramstage cache. */ reset_system(); #endif } -#endif #if CONFIG_CHROMEOS int vboot_get_sw_write_protect(void)