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>
This commit is contained in:
parent
f91344cd07
commit
be291e8abf
|
@ -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?
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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,9 +127,9 @@ 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,
|
||||
|
@ -79,10 +140,7 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
|
|||
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);
|
||||
cache_as_ram_stage_main(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();
|
||||
|
||||
after_cache_as_ram_stage();
|
||||
/* we don't return here */
|
||||
platform_enter_postcar();
|
||||
}
|
||||
|
||||
void __weak car_mainboard_pre_console_init(void)
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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(¶ms);
|
||||
soc_after_ram_init(¶ms);
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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");
|
||||
}
|
||||
}
|
|
@ -17,6 +17,8 @@ romstage-y += pmutil.c
|
|||
romstage-y += smbus.c
|
||||
romstage-y += tsc_freq.c
|
||||
|
||||
postcar-y += memmap.c
|
||||
postcar-y += iosf.c
|
||||
postcar-y += tsc_freq.c
|
||||
|
||||
ramstage-y += acpi.c
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#include <soc/car.h>
|
||||
#include <soc/reg_access.h>
|
||||
|
||||
asmlinkage void *car_stage_c_entry(void);
|
||||
asmlinkage void car_stage_c_entry(void);
|
||||
void clear_smi_and_wake_events(void);
|
||||
void disable_rom_shadow(void);
|
||||
void *locate_rmu_file(size_t *rmu_file_len);
|
||||
|
|
|
@ -29,12 +29,6 @@ car_stage_entry:
|
|||
/* Enter the C code */
|
||||
call car_stage_c_entry
|
||||
|
||||
#if CONFIG(PLATFORM_USES_FSP1_1)
|
||||
#if !ENV_VERSTAGE
|
||||
#include "src/drivers/intel/fsp1_1/after_raminit.S"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* The code should never reach this point */
|
||||
movb $0x69, %ah
|
||||
jmp .Lhlt
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <soc/reg_access.h>
|
||||
#include <soc/storage_test.h>
|
||||
|
||||
asmlinkage void *car_stage_c_entry(void)
|
||||
asmlinkage void car_stage_c_entry(void)
|
||||
{
|
||||
struct postcar_frame pcf;
|
||||
bool s3wake;
|
||||
|
@ -83,7 +83,6 @@ asmlinkage void *car_stage_c_entry(void)
|
|||
postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRTHROUGH);
|
||||
|
||||
run_postcar_phase(&pcf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct chipset_power_state power_state CAR_GLOBAL;
|
||||
|
|
|
@ -13,6 +13,8 @@
|
|||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <cpu/x86/post_code.h>
|
||||
|
||||
/* I/O delay between post codes on failure */
|
||||
#define LHLT_DELAY 0x50000
|
||||
|
||||
|
@ -20,9 +22,8 @@
|
|||
.global car_stage_entry
|
||||
car_stage_entry:
|
||||
call romstage_c_entry
|
||||
#include "src/drivers/intel/fsp1_1/after_raminit.S"
|
||||
|
||||
|
||||
/* we don't return here */
|
||||
movb $0x69, %ah
|
||||
jmp .Lhlt
|
||||
|
||||
|
|
Loading…
Reference in New Issue