summaryrefslogtreecommitdiff
path: root/src/drivers/intel
diff options
context:
space:
mode:
authorArthur Heymans <arthur@aheymans.xyz>2019-01-06 07:35:11 +0100
committerPatrick Georgi <pgeorgi@google.com>2019-05-21 17:37:32 +0000
commitbe291e8abf173e4f12e6d9e5532fdf1acbcb9a67 (patch)
tree12b2a0c6bcf03649b81ef38aa033b5bc06f4a7c0 /src/drivers/intel
parentf91344cd07a4e9a4c2e183f00431b4fee05daf33 (diff)
downloadcoreboot-be291e8abf173e4f12e6d9e5532fdf1acbcb9a67.tar.xz
soc/intel/fsp1.1: Implement postcar stage
This moves FSP1.1 to use postcar stage to tear down CAR. On platforms with USE_GENERIC_FSP_CAR_INC the FSP header is found during the postcar stage so there is no need to push to save it in CAR global variables. On FSP1.1 platforms with an open source CAR implementation (Skylake, even though it still runs the FSP-T), the soc/intel/common/blocks/cpu/car/exit_car.S code tears down CAR. This also uses common functions to set up the MTRR to use after CAR is torn down. Test: build/boot on google/celes (BSW) and google/chell (SKL) Change-Id: I2330993842aae9c1365230f0c6bd8a2449dc73a5 Signed-off-by: Arthur Heymans <arthur@aheymans.xyz> Reviewed-on: https://review.coreboot.org/c/coreboot/+/30686 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'src/drivers/intel')
-rw-r--r--src/drivers/intel/fsp1_1/Kconfig2
-rw-r--r--src/drivers/intel/fsp1_1/Makefile.inc8
-rw-r--r--src/drivers/intel/fsp1_1/after_raminit.S170
-rw-r--r--src/drivers/intel/fsp1_1/cache_as_ram.inc6
-rw-r--r--src/drivers/intel/fsp1_1/car.c128
-rw-r--r--src/drivers/intel/fsp1_1/exit_car.S27
-rw-r--r--src/drivers/intel/fsp1_1/include/fsp/car.h8
-rw-r--r--src/drivers/intel/fsp1_1/include/fsp/romstage.h2
-rw-r--r--src/drivers/intel/fsp1_1/include/fsp/util.h4
-rw-r--r--src/drivers/intel/fsp1_1/romstage.c20
-rw-r--r--src/drivers/intel/fsp1_1/stack.c161
-rw-r--r--src/drivers/intel/fsp1_1/temp_ram_exit.c44
12 files changed, 181 insertions, 399 deletions
diff --git a/src/drivers/intel/fsp1_1/Kconfig b/src/drivers/intel/fsp1_1/Kconfig
index a8658ec7e6..da9e1888e9 100644
--- a/src/drivers/intel/fsp1_1/Kconfig
+++ b/src/drivers/intel/fsp1_1/Kconfig
@@ -18,6 +18,8 @@ config PLATFORM_USES_FSP1_1
bool
select UEFI_2_4_BINDING
select INTEL_GMA_ADD_VBT if RUN_FSP_GOP
+ select POSTCAR_STAGE
+ select POSTCAR_CONSOLE
help
Does the code require the Intel Firmware Support Package?
diff --git a/src/drivers/intel/fsp1_1/Makefile.inc b/src/drivers/intel/fsp1_1/Makefile.inc
index 953d1e4ffe..93f3b59d4b 100644
--- a/src/drivers/intel/fsp1_1/Makefile.inc
+++ b/src/drivers/intel/fsp1_1/Makefile.inc
@@ -28,7 +28,6 @@ romstage-y += fsp_util.c
romstage-y += hob.c
romstage-y += raminit.c
romstage-y += romstage.c
-romstage-y += stack.c
romstage-y += stage_cache.c
romstage-$(CONFIG_MMA) += mma_core.c
@@ -45,6 +44,13 @@ CPPFLAGS_common += -Isrc/drivers/intel/fsp1_1/include
cpu_incs-$(CONFIG_USE_GENERIC_FSP_CAR_INC) += $(src)/drivers/intel/fsp1_1/cache_as_ram.inc
+postcar-y += stage_cache.c
+ifneq ($(CONFIG_SKIP_FSP_CAR),y)
+postcar-y += temp_ram_exit.c
+postcar-y += exit_car.S
+endif
+postcar-y += fsp_util.c
+
# Add the FSP binary to the cbfs image
ifeq ($(CONFIG_HAVE_FSP_BIN),y)
cbfs-files-y += fsp.bin
diff --git a/src/drivers/intel/fsp1_1/after_raminit.S b/src/drivers/intel/fsp1_1/after_raminit.S
deleted file mode 100644
index 3f2a7ae02f..0000000000
--- a/src/drivers/intel/fsp1_1/after_raminit.S
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
- * Copyright (C) 2007-2008 coresystems GmbH
- * Copyright (C) 2013-2014 Sage Electronic Engineering, LLC.
- * 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
- * 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.
- */
-
-#include <cpu/x86/mtrr.h>
-#include <cpu/x86/cache.h>
-#include <cpu/x86/post_code.h>
-
-/*
- * This is the common entry point after DRAM has been initialized.
- */
- /*
- * eax: New stack address
- */
-
- /* Switch to the stack in RAM */
- movl %eax, %esp
-
-#if CONFIG(SKIP_FSP_CAR)
-
- /* chipset_teardown_car() is expected to disable cache-as-ram. */
- call chipset_teardown_car
-
-#else
-.extern fih_car
-
- post_code(POST_FSP_TEMP_RAM_EXIT)
-
- /* Calculate TempRamExit entry into FSP */
- movl fih_car, %ebp
- mov 0x40(%ebp), %eax
- add 0x1c(%ebp), %eax
-
- /* Build the call frame */
- pushl $0
-
- /* Call TempRamExit */
- call *%eax
- add $4, %esp
- cmp $0, %eax
- jz 1f
- /*
- * Failures for post code BC - failed in TempRamExit
- *
- * 0x00 - FSP_SUCCESS: Temp RAM Exit completed successfully.
- * 0x02 - FSP_INVALID_PARAMETER: Input parameters are invalid.
- * 0x03 - FSP_UNSUPPORTED: The FSP calling conditions were not met.
- * 0x07 - FSP_DEVICE_ERROR: Temp RAM Exit failed.
- */
- movb $0xBC, %ah
- jmp .Lhlt
-1:
-#endif
- /* Display the MTRRs */
- call display_mtrrs
-
- /*
- * The stack contents are initialized in src/soc/intel/common/stack.c
- * to be the following:
- *
- * *
- * *
- * *
- * +36: MTRR mask 1 63:32
- * +32: MTRR mask 1 31:0
- * +28: MTRR base 1 63:32
- * +24: MTRR base 1 31:0
- * +20: MTRR mask 0 63:32
- * +16: MTRR mask 0 31:0
- * +12: MTRR base 0 63:32
- * +8: MTRR base 0 31:0
- * +4: Number of MTRRs to setup (described above)
- * +0: Number of variable MTRRs to clear
- */
-
-#if CONFIG(SOC_SETS_MSRS)
- push %esp
- call soc_set_mtrrs
-
- /* eax: new top_of_stack with setup_stack_and_mtrrs data removed */
- movl %eax, %esp
-#else
- /* Clear all of the variable MTRRs. */
- popl %ebx
- movl $MTRR_PHYS_BASE(0), %ecx
- clr %eax
- clr %edx
-
-1:
- testl %ebx, %ebx
- jz 1f
- wrmsr /* Write MTRR base. */
- inc %ecx
- wrmsr /* Write MTRR mask. */
- inc %ecx
- dec %ebx
- jmp 1b
-
-1:
- /* Get number of MTRRs. */
- popl %ebx
- movl $MTRR_PHYS_BASE(0), %ecx
-2:
- testl %ebx, %ebx
- jz 2f
-
- /* Low 32 bits of MTRR base. */
- popl %eax
- /* Upper 32 bits of MTRR base. */
- popl %edx
- /* Write MTRR base. */
- wrmsr
- inc %ecx
- /* Low 32 bits of MTRR mask. */
- popl %eax
- /* Upper 32 bits of MTRR mask. */
- popl %edx
- /* Write MTRR mask. */
- wrmsr
- inc %ecx
-
- dec %ebx
- jmp 2b
-2:
-#endif /* CONFIG_SOC_SETS_MSRS */
-
- post_code(0x39)
-
- /* And enable cache again after setting MTRRs. */
- movl %cr0, %eax
- andl $~(CR0_CacheDisable | CR0_NoWriteThrough), %eax
- movl %eax, %cr0
-
- post_code(0x3a)
-
-#if CONFIG(SOC_SETS_MSRS)
- call soc_enable_mtrrs
-#else
- /* Enable MTRR. */
- movl $MTRR_DEF_TYPE_MSR, %ecx
- rdmsr
- orl $MTRR_DEF_TYPE_EN, %eax
- wrmsr
-#endif /* CONFIG_SOC_SETS_MSRS */
-
- post_code(0x3b)
-
- /* Invalidate the cache again. */
- invd
-
- post_code(0x3c)
-
-__main:
- post_code(POST_PREPARE_RAMSTAGE)
- cld /* Clear direction flag. */
- call after_cache_as_ram
diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc
index fa5c40677b..f50641e3ae 100644
--- a/src/drivers/intel/fsp1_1/cache_as_ram.inc
+++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc
@@ -147,12 +147,6 @@ before_romstage:
/* Call cache_as_ram_main(struct cache_as_ram_params *) */
call cache_as_ram_main
-/* One will never return from cache_as_ram_main() in verstage so there's
- * no such thing as after RAM init. */
-#if !ENV_VERSTAGE
-#include "after_raminit.S"
-#endif
-
movb $0x69, %ah
jmp .Lhlt
diff --git a/src/drivers/intel/fsp1_1/car.c b/src/drivers/intel/fsp1_1/car.c
index 3a41e40468..34b2518c38 100644
--- a/src/drivers/intel/fsp1_1/car.c
+++ b/src/drivers/intel/fsp1_1/car.c
@@ -18,35 +18,96 @@
#include <cpu/x86/mtrr.h>
#include <fsp/car.h>
#include <fsp/util.h>
+#include <fsp/memmap.h>
#include <program_loading.h>
#include <timestamp.h>
-FSP_INFO_HEADER *fih_car CAR_GLOBAL;
+#define ROMSTAGE_RAM_STACK_SIZE 0x5000
-/* Save FSP_INFO_HEADER for TempRamExit() call in assembly. */
-static inline void set_fih_car(FSP_INFO_HEADER *fih)
+/* platform_enter_postcar() determines the stack to use after
+ * cache-as-ram is torn down as well as the MTRR settings to use,
+ * and continues execution in postcar stage. */
+static void platform_enter_postcar(void)
{
- /* This variable is written in the raw form because it's only
- * ever accessed in code that that has the cache-as-ram enabled. The
- * assembly routine which tears down cache-as-ram utilizes this
- * variable for determining where to find FSP. */
- fih_car = fih;
+ struct postcar_frame pcf;
+ size_t alignment;
+ uint32_t aligned_ram;
+
+ if (postcar_frame_init(&pcf, ROMSTAGE_RAM_STACK_SIZE))
+ die("Unable to initialize postcar frame.\n");
+ /* Cache the ROM as WP just below 4GiB. */
+ postcar_frame_add_mtrr(&pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE,
+ MTRR_TYPE_WRPROT);
+
+ /* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
+ postcar_frame_add_mtrr(&pcf, 0, CACHE_TMP_RAMTOP, MTRR_TYPE_WRBACK);
+
+ /*
+ * +-------------------------+ Top of RAM (aligned)
+ * | System Management Mode |
+ * | code and data | Length: CONFIG_TSEG_SIZE
+ * | (TSEG) |
+ * +-------------------------+ SMM base (aligned)
+ * | |
+ * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE
+ * | |
+ * +-------------------------+ top_of_ram (aligned)
+ * | |
+ * | CBMEM Root |
+ * | |
+ * +-------------------------+
+ * | |
+ * | FSP Reserved Memory |
+ * | |
+ * +-------------------------+
+ * | |
+ * | Various CBMEM Entries |
+ * | |
+ * +-------------------------+ top_of_stack (8 byte aligned)
+ * | |
+ * | stack (CBMEM Entry) |
+ * | |
+ * +-------------------------+
+ */
+
+ alignment = mmap_region_granularity();
+ aligned_ram = ALIGN_DOWN(romstage_ram_stack_bottom(), alignment);
+ postcar_frame_add_mtrr(&pcf, aligned_ram, alignment, MTRR_TYPE_WRBACK);
+
+ if (CONFIG(HAVE_SMI_HANDLER)) {
+ void *smm_base;
+ size_t smm_size;
+
+ /*
+ * Cache the TSEG region at the top of ram. This region 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.
+ */
+ smm_region(&smm_base, &smm_size);
+ postcar_frame_add_mtrr(&pcf, (uintptr_t)smm_base, alignment,
+ MTRR_TYPE_WRBACK);
+ }
+
+ run_postcar_phase(&pcf);
}
-asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
+/* This is the romstage C entry for platforms without
+ CONFIG_C_ENVIRONMENT_BOOTBLOCK */
+asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params)
{
int i;
const int num_guards = 4;
const u32 stack_guard = 0xdeadbeef;
u32 *stack_base;
- void *ram_stack;
u32 size;
/* Size of unallocated CAR. */
size = _car_region_end - _car_relocatable_data_end;
size = ALIGN_DOWN(size, 16);
- stack_base = (u32 *) (_car_region_end - size);
+ stack_base = (u32 *)(_car_region_end - size);
for (i = 0; i < num_guards; i++)
stack_base[i] = stack_guard;
@@ -66,23 +127,20 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
display_mtrrs();
- if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE ||
- car_params->bootloader_car_end !=
- (CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)) {
+ if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE
+ || car_params->bootloader_car_end != (CONFIG_DCACHE_RAM_BASE
+ + CONFIG_DCACHE_RAM_SIZE)) {
printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n",
- CONFIG_DCACHE_RAM_BASE,
- CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE,
- (long)car_params->bootloader_car_start,
- (long)car_params->bootloader_car_end);
+ CONFIG_DCACHE_RAM_BASE,
+ CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE,
+ (long)car_params->bootloader_car_start,
+ (long)car_params->bootloader_car_end);
}
car_soc_post_console_init();
car_mainboard_post_console_init();
- set_fih_car(car_params->fih);
-
- /* Return new stack value in RAM back to assembly stub. */
- ram_stack = cache_as_ram_stage_main(car_params->fih);
+ cache_as_ram_stage_main(car_params->fih);
/* Check the stack. */
for (i = 0; i < num_guards; i++) {
@@ -91,11 +149,13 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
printk(BIOS_DEBUG, "Smashed stack detected in romstage!\n");
}
- return ram_stack;
+ /* we don't return here */
+ platform_enter_postcar();
}
-/* Entry point taken when romstage is called after a separate verstage. */
-asmlinkage void *romstage_c_entry(void)
+/* This is the romstage C entry for platforms with
+ CONFIG_C_ENVIRONMENT_BOOTBLOCK */
+asmlinkage void romstage_c_entry(void)
{
/* Need to locate the current FSP_INFO_HEADER. The cache-as-ram
* is still enabled. We can directly access work buffer here. */
@@ -107,24 +167,16 @@ asmlinkage void *romstage_c_entry(void)
if (prog_locate(&fsp)) {
fih = NULL;
printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp));
- } else
+ } else {
/* This leaks a mapping which this code assumes is benign as
* the flash is memory mapped CPU's address space. */
fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp)));
+ }
- set_fih_car(fih);
-
- /* Return new stack value in RAM back to assembly stub. */
- return cache_as_ram_stage_main(fih);
-}
-
-asmlinkage void after_cache_as_ram(void *chipset_context)
-{
- timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_END);
- printk(BIOS_DEBUG, "FspTempRamExit returned successfully\n");
- display_mtrrs();
+ cache_as_ram_stage_main(fih);
- after_cache_as_ram_stage();
+ /* we don't return here */
+ platform_enter_postcar();
}
void __weak car_mainboard_pre_console_init(void)
diff --git a/src/drivers/intel/fsp1_1/exit_car.S b/src/drivers/intel/fsp1_1/exit_car.S
new file mode 100644
index 0000000000..4b2822a887
--- /dev/null
+++ b/src/drivers/intel/fsp1_1/exit_car.S
@@ -0,0 +1,27 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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.
+ */
+
+
+.text
+.global chipset_teardown_car
+chipset_teardown_car:
+
+ pop %ebx
+ /* Move the stack pointer to real ram */
+ movl post_car_stack_top, %esp
+ /* Align the stack 16 bytes */
+ andl $0xfffffff0, %esp
+
+ call chipset_teardown_car_main
+
+ jmp *%ebx
diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h
index 5214d73b29..0ae687a9d7 100644
--- a/src/drivers/intel/fsp1_1/include/fsp/car.h
+++ b/src/drivers/intel/fsp1_1/include/fsp/car.h
@@ -30,14 +30,12 @@ struct cache_as_ram_params {
};
/* Entry points from the cache-as-ram assembly code. */
-asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params);
-asmlinkage void after_cache_as_ram(void *chipset_context);
-asmlinkage void *romstage_c_entry(void);
+asmlinkage void cache_as_ram_main(struct cache_as_ram_params *car_params);
+asmlinkage void romstage_c_entry(void);
/* Per stage calls from the above two functions. The void * return from
* cache_as_ram_stage_main() is the stack pointer to use in RAM after
* exiting cache-as-ram mode. */
-void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih);
-void after_cache_as_ram_stage(void);
+void cache_as_ram_stage_main(FSP_INFO_HEADER *fih);
/* Mainboard and SoC initialization prior to console. */
void car_mainboard_pre_console_init(void);
diff --git a/src/drivers/intel/fsp1_1/include/fsp/romstage.h b/src/drivers/intel/fsp1_1/include/fsp/romstage.h
index b01f11059c..de37950887 100644
--- a/src/drivers/intel/fsp1_1/include/fsp/romstage.h
+++ b/src/drivers/intel/fsp1_1/include/fsp/romstage.h
@@ -87,7 +87,7 @@ void mainboard_add_dimm_info(struct romstage_params *params,
void raminit(struct romstage_params *params);
void report_memory_config(void);
void romstage_common(struct romstage_params *params);
-asmlinkage void *romstage_main(FSP_INFO_HEADER *fih);
+asmlinkage void romstage_main(FSP_INFO_HEADER *fih);
/* Initialize memory margin analysis settings. */
void setup_mma(MEMORY_INIT_UPD *memory_upd);
void *setup_stack_and_mtrrs(void);
diff --git a/src/drivers/intel/fsp1_1/include/fsp/util.h b/src/drivers/intel/fsp1_1/include/fsp/util.h
index 0ad7a4117a..45b8eda243 100644
--- a/src/drivers/intel/fsp1_1/include/fsp/util.h
+++ b/src/drivers/intel/fsp1_1/include/fsp/util.h
@@ -17,6 +17,8 @@
#ifndef FSP1_1_UTIL_H
#define FSP1_1_UTIL_H
+#include <rules.h>
+#include <arch/cpu.h>
#include <fsp/api.h>
/* Current users expect to get the SoC's FSP definitions by including util.h. */
#include <fsp/soc_binding.h>
@@ -107,4 +109,6 @@ void *get_first_guid_hob(const EFI_GUID *guid);
__attribute__((cdecl)) size_t fsp_write_line(uint8_t *buffer,
size_t number_of_bytes);
+asmlinkage void chipset_teardown_car_main(void);
+
#endif /* FSP1_1_UTIL_H */
diff --git a/src/drivers/intel/fsp1_1/romstage.c b/src/drivers/intel/fsp1_1/romstage.c
index 433e16cf13..40c598877f 100644
--- a/src/drivers/intel/fsp1_1/romstage.c
+++ b/src/drivers/intel/fsp1_1/romstage.c
@@ -38,9 +38,8 @@
#include <timestamp.h>
#include <vendorcode/google/chromeos/chromeos.h>
-asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
+asmlinkage void romstage_main(FSP_INFO_HEADER *fih)
{
- void *top_of_stack;
struct romstage_params params = {
.chipset_context = fih,
};
@@ -72,17 +71,11 @@ asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
mainboard_romstage_entry(&params);
soc_after_ram_init(&params);
post_code(0x38);
-
- top_of_stack = setup_stack_and_mtrrs();
-
- printk(BIOS_DEBUG, "Calling FspTempRamExit API\n");
- timestamp_add_now(TS_FSP_TEMP_RAM_EXIT_START);
- return top_of_stack;
}
-void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
+void cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
{
- return romstage_main(fih);
+ romstage_main(fih);
}
/* Entry from the mainboard. */
@@ -161,13 +154,6 @@ void romstage_common(struct romstage_params *params)
full_reset();
}
-void after_cache_as_ram_stage(void)
-{
- /* Load the ramstage. */
- run_ramstage();
- die("ERROR - Failed to load ramstage!");
-}
-
/* Initialize the power state */
__weak struct chipset_power_state *fill_power_state(void)
{
diff --git a/src/drivers/intel/fsp1_1/stack.c b/src/drivers/intel/fsp1_1/stack.c
deleted file mode 100644
index 88ff36a847..0000000000
--- a/src/drivers/intel/fsp1_1/stack.c
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * This file is part of the coreboot project.
- *
- * Copyright (C) 2013 Google Inc.
- * Copyright (C) 2015-2016 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
- * 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.
- */
-
-#include <arch/cpu.h>
-#include <cbmem.h>
-#include <console/console.h>
-#include <cpu/x86/mtrr.h>
-#include <fsp/memmap.h>
-#include <fsp/romstage.h>
-#include <fsp/stack.h>
-#include <stdlib.h>
-#include <program_loading.h>
-
-/*
- * setup_stack_and_mtrrs() determines the stack to use after
- * cache-as-ram is torn down as well as the MTRR settings to use.
- */
-void *setup_stack_and_mtrrs(void)
-{
- size_t alignment;
- uint32_t aligned_ram;
- uint32_t mtrr_mask_upper;
- uint32_t max_mtrrs;
- uint32_t num_mtrrs;
- uint32_t *slot;
-
- /* Display the MTRRs */
- display_mtrrs();
-
- /* Top of stack needs to be aligned to a 8-byte boundary. */
- slot = (void *)romstage_ram_stack_top();
- num_mtrrs = 0;
- max_mtrrs = get_var_mtrr_count();
-
- /*
- * 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;
- alignment = mmap_region_granularity();
- aligned_ram = ALIGN_DOWN(romstage_ram_stack_bottom(), alignment);
-
- /*
- * 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:
- *
- * +36: MTRR mask 1 63:32
- * +32: MTRR mask 1 31:0
- * +28: MTRR base 1 63:32
- * +24: MTRR base 1 31:0
- * +20: MTRR mask 0 63:32
- * +16: MTRR mask 0 31:0
- * +12: MTRR base 0 63:32
- * +8: MTRR base 0 31:0
- * +4: Number of MTRRs to setup (described above)
- * +0: Number of variable MTRRs to clear
- */
-
- /* Cache RAM as WB from 0 -> CACHE_TMP_RAMTOP. */
- slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
- slot = stack_push32(slot, ~(CACHE_TMP_RAMTOP - 1)
- | MTRR_PHYS_MASK_VALID);
- slot = stack_push32(slot, 0); /* upper base */
- slot = stack_push32(slot, 0 | MTRR_TYPE_WRBACK);
- num_mtrrs++;
-
- /*
- * +-------------------------+ Top of RAM (aligned)
- * | System Management Mode |
- * | code and data | Length: CONFIG_TSEG_SIZE
- * | (TSEG) |
- * +-------------------------+ SMM base (aligned)
- * | |
- * | Chipset Reserved Memory | Length: Multiple of CONFIG_TSEG_SIZE
- * | |
- * +-------------------------+ top_of_ram (aligned)
- * | |
- * | CBMEM Root |
- * | |
- * +-------------------------+
- * | |
- * | FSP Reserved Memory |
- * | |
- * +-------------------------+
- * | |
- * | Various CBMEM Entries |
- * | |
- * +-------------------------+ top_of_stack (8 byte aligned)
- * | |
- * | stack (CBMEM Entry) |
- * | |
- * +-------------------------+
- */
-
- /*
- * Cache the stack and the other CBMEM entries as well as part or all
- * of the FSP reserved memory region.
- */
- slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
- slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID);
- slot = stack_push32(slot, 0); /* upper base */
- slot = stack_push32(slot, aligned_ram | MTRR_TYPE_WRBACK);
- num_mtrrs++;
-
-#if CONFIG(HAVE_SMI_HANDLER)
- void *smm_base;
- size_t smm_size;
- uint32_t tseg_base;
-
- /*
- * Cache the TSEG region at the top of ram. This region 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.
- */
- smm_region(&smm_base, &smm_size);
- tseg_base = (uint32_t)smm_base;
- slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
- slot = stack_push32(slot, ~(alignment - 1) | MTRR_PHYS_MASK_VALID);
- slot = stack_push32(slot, 0); /* upper base */
- slot = stack_push32(slot, tseg_base | MTRR_TYPE_WRBACK);
- num_mtrrs++;
-#endif
-
- /* Cache the ROM as WP just below 4GiB. */
- slot = stack_push32(slot, mtrr_mask_upper); /* upper mask */
- slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1)
- | MTRR_PHYS_MASK_VALID);
- slot = stack_push32(slot, 0); /* upper base */
- slot = stack_push32(slot, ~(CONFIG_ROM_SIZE - 1) | MTRR_TYPE_WRPROT);
- num_mtrrs++;
-
- /* Validate the MTRR usage */
- if (num_mtrrs > max_mtrrs) {
- printk(BIOS_ERR, "MTRRs: max = %d, used = %d, available=%d",
- max_mtrrs, num_mtrrs, max_mtrrs - num_mtrrs);
- die("ERROR - MTRR use count incorrect!\n");
- }
-
- /*
- * Save the number of MTRRs to setup and clear. Return the stack
- * location pointing to the number of MTRRs.
- */
- slot = stack_push32(slot, num_mtrrs);
- slot = stack_push32(slot, max_mtrrs);
- return slot;
-}
diff --git a/src/drivers/intel/fsp1_1/temp_ram_exit.c b/src/drivers/intel/fsp1_1/temp_ram_exit.c
new file mode 100644
index 0000000000..c1535e0bc0
--- /dev/null
+++ b/src/drivers/intel/fsp1_1/temp_ram_exit.c
@@ -0,0 +1,44 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <console/console.h>
+#include <fsp/util.h>
+
+asmlinkage void chipset_teardown_car_main(void)
+{
+ FSP_INFO_HEADER *fih;
+ uint32_t status;
+ FSP_TEMP_RAM_EXIT temp_ram_exit;
+ struct prog fsp = PROG_INIT(PROG_REFCODE, "fsp.bin");
+
+ if (prog_locate(&fsp)) {
+ die("Unable to locate fsp.bin\n");
+ } else {
+ /* This leaks a mapping which this code assumes is benign as
+ * the flash is memory mapped CPU's address space. */
+
+ /* FIXME: the implementation of find_fsp is utter garbage
+ as it casts error values to FSP_INFO_HEADER pointers.
+ Checking for return values can only be done sanely once
+ that is fixed. */
+ fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp)));
+ }
+
+ temp_ram_exit = (FSP_TEMP_RAM_EXIT)(fih->TempRamExitEntryOffset +
+ fih->ImageBase);
+ printk(BIOS_DEBUG, "Calling TempRamExit: %p\n", temp_ram_exit);
+ status = temp_ram_exit(NULL);
+
+ if (status != FSP_SUCCESS) {
+ printk(BIOS_CRIT, "TempRamExit returned 0x%08x\n", status);
+ die("TempRamExit returned an error!\n");
+ }
+}