diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-04-20 15:20:28 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-06-25 21:50:48 +0200 |
commit | 32471729d9ebbabe809711ec55568925c6ce2070 (patch) | |
tree | b9f6db4e4969ee5edd6c2571e4f7612121070a9f /src/soc/intel/braswell/romstage/romstage.c | |
parent | 5fe62efb77a2ecfeecdcc526404712b816e74693 (diff) | |
download | coreboot-32471729d9ebbabe809711ec55568925c6ce2070.tar.gz coreboot-32471729d9ebbabe809711ec55568925c6ce2070.tar.bz2 coreboot-32471729d9ebbabe809711ec55568925c6ce2070.zip |
Braswell: Add Braswell SOC support
Add the files to support the Braswell SOC.
BRANCH=none
BUG=None
TEST=Build for a Braswell platform
Change-Id: I968da68733e57647d0a08e4040ff0378b4d59004
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10051
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/braswell/romstage/romstage.c')
-rw-r--r-- | src/soc/intel/braswell/romstage/romstage.c | 318 |
1 files changed, 99 insertions, 219 deletions
diff --git a/src/soc/intel/braswell/romstage/romstage.c b/src/soc/intel/braswell/romstage/romstage.c index 67716d4aae4a..df6efd8bf297 100644 --- a/src/soc/intel/braswell/romstage/romstage.c +++ b/src/soc/intel/braswell/romstage/romstage.c @@ -2,6 +2,7 @@ * This file is part of the coreboot project. * * Copyright (C) 2013 Google Inc. + * Copyright (C) 2015 Intel Corp. * * 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 @@ -17,45 +18,41 @@ * Foundation, Inc. */ +#include <cbmem.h> #include <stddef.h> +#include <arch/early_variables.h> #include <arch/cpu.h> #include <arch/io.h> +#include <arch/cbfs.h> #include <arch/stages.h> -#include <arch/early_variables.h> -#include <console/console.h> -#include <cbfs.h> #include <cbmem.h> +#include <chip.h> #include <cpu/x86/mtrr.h> -#if CONFIG_EC_GOOGLE_CHROMEEC +#include <console/console.h> +#include <device/device.h> +#include <device/pci_def.h> +#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) #include <ec/google/chromeec/ec.h> +#include <ec/google/chromeec/ec_commands.h> #endif #include <elog.h> #include <romstage_handoff.h> -#include <stage_cache.h> #include <timestamp.h> +#include <reset.h> #include <vendorcode/google/chromeos/chromeos.h> +#include <fsp_util.h> +#include <soc/intel/common/mrc_cache.h> #include <soc/gpio.h> #include <soc/iomap.h> +#include <soc/iosf.h> #include <soc/lpc.h> #include <soc/pci_devs.h> -#include <soc/pmc.h> -#include <soc/reset.h> #include <soc/romstage.h> #include <soc/smm.h> #include <soc/spi.h> #include <tpm.h> -/* 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. */ - -static void *setup_stack_and_mttrs(void); - -static void program_base_addresses(void) +void program_base_addresses(void) { uint32_t reg; const uint32_t lpc_dev = PCI_DEV(0, LPC_DEV, LPC_FUNC); @@ -85,8 +82,8 @@ static void program_base_addresses(void) static void spi_init(void) { - u32 *scs = (u32 *)(SPI_BASE_ADDRESS + SCS); - u32 *bcr = (u32 *)(SPI_BASE_ADDRESS + BCR); + void *scs = (void *)(SPI_BASE_ADDRESS + SCS); + void *bcr = (void *)(SPI_BASE_ADDRESS + BCR); uint32_t reg; /* Disable generating SMI when setting WPD bit. */ @@ -100,51 +97,9 @@ static void spi_init(void) write32(bcr, reg); } -/* Entry from cache-as-ram.inc. */ -void * asmlinkage romstage_main(unsigned long bist, - uint32_t tsc_low, uint32_t tsc_hi) -{ - struct romstage_params rp = { - .bist = bist, - .mrc_params = NULL, - }; - - /* Save initial timestamp from bootblock. */ - timestamp_init((((uint64_t)tsc_hi) << 32) | (uint64_t)tsc_low); - - /* Save romstage begin */ - timestamp_add_now(TS_START_ROMSTAGE); - - program_base_addresses(); - - tco_disable(); - - byt_config_com1_and_enable(); - - console_init(); - - spi_init(); - - set_max_freq(); - - punit_init(); - - gfx_init(); - -#if CONFIG_EC_GOOGLE_CHROMEEC - /* Ensure the EC is in the right mode for recovery */ - google_chromeec_early_init(); -#endif - - /* Call into mainboard. */ - mainboard_romstage_entry(&rp); - - return setup_stack_and_mttrs(); -} - static struct chipset_power_state power_state CAR_GLOBAL; -static void migrate_power_state(void) +static void migrate_power_state(int is_recovery) { struct chipset_power_state *ps_cbmem; struct chipset_power_state *ps_car; @@ -158,9 +113,9 @@ static void migrate_power_state(void) } memcpy(ps_cbmem, ps_car, sizeof(*ps_cbmem)); } -CAR_MIGRATE(migrate_power_state); +ROMSTAGE_CBMEM_INIT_HOOK(migrate_power_state); -static struct chipset_power_state *fill_power_state(void) +struct chipset_power_state *fill_power_state(void) { struct chipset_power_state *ps = car_get_var_ptr(&power_state); @@ -170,9 +125,11 @@ static struct chipset_power_state *fill_power_state(void) ps->gpe0_sts = inl(ACPI_BASE_ADDRESS + GPE0_STS); ps->gpe0_en = inl(ACPI_BASE_ADDRESS + GPE0_EN); ps->tco_sts = inl(ACPI_BASE_ADDRESS + TCO_STS); - ps->prsts = read32((u32 *)(PMC_BASE_ADDRESS + PRSTS)); - ps->gen_pmcon1 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON1)); - ps->gen_pmcon2 = read32((u32 *)(PMC_BASE_ADDRESS + GEN_PMCON2)); + ps->prsts = read32((void *)(PMC_BASE_ADDRESS + PRSTS)); + ps->gen_pmcon1 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON1)); + ps->gen_pmcon2 = read32((void *)(PMC_BASE_ADDRESS + GEN_PMCON2)); + + ps->prev_sleep_state = chipset_prev_sleep_state(ps); printk(BIOS_DEBUG, "pm1_sts: %04x pm1_en: %04x pm1_cnt: %08x\n", ps->pm1_sts, ps->pm1_en, ps->pm1_cnt); @@ -180,193 +137,116 @@ static struct chipset_power_state *fill_power_state(void) ps->gpe0_sts, ps->gpe0_en, ps->tco_sts); printk(BIOS_DEBUG, "prsts: %08x gen_pmcon1: %08x gen_pmcon2: %08x\n", ps->prsts, ps->gen_pmcon1, ps->gen_pmcon2); - + printk(BIOS_DEBUG, "prev_sleep_state %d\n", ps->prev_sleep_state); return ps; } /* Return 0, 3, or 5 to indicate the previous sleep state. */ -static int chipset_prev_sleep_state(struct chipset_power_state *ps) +int chipset_prev_sleep_state(struct chipset_power_state *ps) { /* Default to S0. */ - int prev_sleep_state = 0; + int prev_sleep_state = SLEEP_STATE_S0; if (ps->pm1_sts & WAK_STS) { switch ((ps->pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) { - #if CONFIG_HAVE_ACPI_RESUME + #if IS_ENABLED(CONFIG_HAVE_ACPI_RESUME) case SLP_TYP_S3: - prev_sleep_state = 3; + prev_sleep_state = SLEEP_STATE_S3; break; #endif case SLP_TYP_S5: - prev_sleep_state = 5; + prev_sleep_state = SLEEP_STATE_S5; break; } + /* Clear SLP_TYP. */ outl(ps->pm1_cnt & ~(SLP_TYP), ACPI_BASE_ADDRESS + PM1_CNT); } - if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) { - prev_sleep_state = 5; - } + if (ps->gen_pmcon1 & (PWR_FLR | SUS_PWR_FLR)) + prev_sleep_state = SLEEP_STATE_S5; return prev_sleep_state; } -/* Entry from the mainboard. */ -void romstage_common(struct romstage_params *params) -{ - struct romstage_handoff *handoff; - struct chipset_power_state *ps; - int prev_sleep_state; - - timestamp_add_now(TS_BEFORE_INITRAM); - - ps = fill_power_state(); - prev_sleep_state = chipset_prev_sleep_state(ps); - - printk(BIOS_DEBUG, "prev_sleep_state = S%d\n", prev_sleep_state); - -#if CONFIG_ELOG_BOOT_COUNT - if (prev_sleep_state != 3) - boot_count_increment(); -#endif - - - /* Initialize RAM */ - raminit(params->mrc_params, prev_sleep_state); - - timestamp_add_now(TS_AFTER_INITRAM); - - handoff = romstage_handoff_find_or_add(); - if (handoff != NULL) - handoff->s3_resume = (prev_sleep_state == 3); - else - printk(BIOS_DEBUG, "Romstage handoff structure not added!\n"); - - if (CONFIG_LPC_TPM) { - init_tpm(prev_sleep_state == 3); - } -} - -void asmlinkage romstage_after_car(void) -{ - timestamp_add_now(TS_END_ROMSTAGE); - - /* Load the ramstage. */ - copy_and_run(); - while (1); -} - -static inline uint32_t *stack_push(u32 *stack, u32 value) +/* SOC initialization before the console is enabled */ +void soc_pre_console_init(struct romstage_params *params) { - stack = &stack[-1]; - *stack = value; - return stack; + /* Early chipset initialization */ + program_base_addresses(); + tco_disable(); } -/* Romstage needs quite a bit of stack for decompressing images since the lzma - * lib keeps its state on the stack during romstage. */ -static unsigned long choose_top_of_stack(void) +/* SOC initialization after console is enabled */ +void soc_romstage_init(struct romstage_params *params) { - unsigned long stack_top; - const unsigned long romstage_ram_stack_size = 0x5000; + /* Continue chipset initialization */ + spi_init(); - /* cbmem_add() does a find() before add(). */ - stack_top = (unsigned long)cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, - romstage_ram_stack_size); - stack_top += romstage_ram_stack_size; - return stack_top; +#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) + /* Ensure the EC is in the right mode for recovery */ + google_chromeec_early_init(); +#endif } -/* setup_stack_and_mttrs() determines the stack to use after - * cache-as-ram is torn down as well as the MTRR settings to use. */ -static void *setup_stack_and_mttrs(void) +/* SOC initialization after RAM is enabled */ +void soc_after_ram_init(struct romstage_params *params) { - unsigned long top_of_stack; - int num_mtrrs; - uint32_t *slot; - uint32_t mtrr_mask_upper; - uint32_t top_of_ram; - - /* Top of stack needs to be aligned to a 4-byte boundary. */ - top_of_stack = choose_top_of_stack() & ~3; - slot = (void *)top_of_stack; - num_mtrrs = 0; + u32 value; - /* The upper bits of the MTRR mask need to set according to the number - * of physical address bits. */ - mtrr_mask_upper = (1 << ((cpuid_eax(0x80000008) & 0xff) - 32)) - 1; - - /* The order for each MTRR is value then base with upper 32-bits of - * each value coming before the lower 32-bits. The reasoning for - * this ordering is to create a stack layout like the following: - * +0: Number of MTRRs - * +4: MTRR base 0 31:0 - * +8: MTRR base 0 63:32 - * +12: MTRR mask 0 31:0 - * +16: MTRR mask 0 63:32 - * +20: MTRR base 1 31:0 - * +24: MTRR base 1 63:32 - * +28: MTRR mask 1 31:0 - * +32: MTRR mask 1 63:32 - */ - - /* Cache the ROM as WP just below 4GiB. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT); - num_mtrrs++; - - /* Cache RAM as WB from 0 -> CONFIG_RAMTOP. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~(CONFIG_RAMTOP - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, 0 | MTRR_TYPE_WRBACK); - num_mtrrs++; - - top_of_ram = (uint32_t)cbmem_top(); - /* Cache 8MiB below the top of ram. The top of ram under 4GiB is the - * start of the TSEG region. It is required to be 8MiB aligned. Set - * this area as cacheable so it can be used later for ramstage before - * setting up the entire RAM as cacheable. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, (top_of_ram - (8 << 20)) | MTRR_TYPE_WRBACK); - num_mtrrs++; - - /* Cache 8MiB at the top of ram. Top of ram is where the TSEG - * region resides. However, it is not restricted to SMM mode until - * SMM has been relocated. By setting the region to cacheable it - * provides faster access when relocating the SMM handler as well - * as using the TSEG region for other purposes. */ - slot = stack_push(slot, mtrr_mask_upper); /* upper mask */ - slot = stack_push(slot, ~((8 << 20) - 1) | MTRRphysMaskValid); - slot = stack_push(slot, 0); /* upper base */ - slot = stack_push(slot, top_of_ram | MTRR_TYPE_WRBACK); - num_mtrrs++; - - /* Save the number of MTRRs to setup. Return the stack location - * pointing to the number of MTRRs. */ - slot = stack_push(slot, num_mtrrs); - - return slot; + /* Make sure that E0000 and F0000 are RAM */ + printk(BIOS_DEBUG, "Disable ROM shadow below 1MB.\n"); + value = iosf_bunit_read(BUNIT_BMISC); + value |= 3; + iosf_bunit_write(BUNIT_BMISC, value); } -void ramstage_cache_invalid(void) +/* Initialize the UPD parameters for MemoryInit */ +void soc_memory_init_params(MEMORY_INIT_UPD *params) { -#if CONFIG_RESET_ON_INVALID_RAMSTAGE_CACHE - /* Perform cold reset on invalid ramstage cache. */ - cold_reset(); -#endif + const struct device *dev; + const struct soc_intel_braswell_config *config; + + /* Set the parameters for MemoryInit */ + dev = dev_find_slot(0, PCI_DEVFN(LPC_DEV, LPC_FUNC)); + config = dev->chip_info; + printk(BIOS_DEBUG, "Updating UPD values for MemoryInit\n"); + params->PcdMrcInitTsegSize = IS_ENABLED(CONFIG_HAVE_SMI_HANDLER) ? + config->PcdMrcInitTsegSize : 0; + params->PcdMrcInitMmioSize = config->PcdMrcInitMmioSize; + params->PcdMrcInitSpdAddr1 = config->PcdMrcInitSpdAddr1; + params->PcdMrcInitSpdAddr2 = config->PcdMrcInitSpdAddr2; + params->PcdIgdDvmt50PreAlloc = config->PcdIgdDvmt50PreAlloc; + params->PcdApertureSize = config->PcdApertureSize; + params->PcdGttSize = config->PcdGttSize; + params->PcdLegacySegDecode = config->PcdLegacySegDecode; } -#if CONFIG_CHROMEOS -int vboot_get_sw_write_protect(void) +void soc_display_memory_init_params(const MEMORY_INIT_UPD *old, + MEMORY_INIT_UPD *new) { - u8 status; - /* Return unprotected status if status read fails. */ - return (early_spi_read_wpsr(&status) ? 0 : !!(status & 0x80)); + /* Display the parameters for MemoryInit */ + printk(BIOS_SPEW, "UPD values for MemoryInit:\n"); + soc_display_upd_value("PcdMrcInitTsegSize", 2, + old->PcdMrcInitTsegSize, new->PcdMrcInitTsegSize); + soc_display_upd_value("PcdMrcInitMmioSize", 2, + old->PcdMrcInitMmioSize, new->PcdMrcInitMmioSize); + soc_display_upd_value("PcdMrcInitSpdAddr1", 1, + old->PcdMrcInitSpdAddr1, new->PcdMrcInitSpdAddr1); + soc_display_upd_value("PcdMrcInitSpdAddr2", 1, + old->PcdMrcInitSpdAddr2, new->PcdMrcInitSpdAddr2); + soc_display_upd_value("PcdMemChannel0Config", 1, + old->PcdMemChannel0Config, new->PcdMemChannel0Config); + soc_display_upd_value("PcdMemChannel1Config", 1, + old->PcdMemChannel1Config, new->PcdMemChannel1Config); + soc_display_upd_value("PcdMemorySpdPtr", 4, + old->PcdMemorySpdPtr, new->PcdMemorySpdPtr); + soc_display_upd_value("PcdIgdDvmt50PreAlloc", 1, + old->PcdIgdDvmt50PreAlloc, new->PcdIgdDvmt50PreAlloc); + soc_display_upd_value("PcdApertureSize", 1, + old->PcdApertureSize, new->PcdApertureSize); + soc_display_upd_value("PcdGttSize", 1, + old->PcdGttSize, new->PcdGttSize); + soc_display_upd_value("PcdLegacySegDecode", 1, + old->PcdLegacySegDecode, new->PcdLegacySegDecode); } -#endif |