aboutsummaryrefslogtreecommitdiff
path: root/src/soc/intel/braswell/romstage/romstage.c
diff options
context:
space:
mode:
authorLee Leahy <leroy.p.leahy@intel.com>2015-04-20 15:20:28 -0700
committerLeroy P Leahy <leroy.p.leahy@intel.com>2015-06-25 21:50:48 +0200
commit32471729d9ebbabe809711ec55568925c6ce2070 (patch)
treeb9f6db4e4969ee5edd6c2571e4f7612121070a9f /src/soc/intel/braswell/romstage/romstage.c
parent5fe62efb77a2ecfeecdcc526404712b816e74693 (diff)
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.c318
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 67716d4aae..df6efd8bf2 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