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:
Arthur Heymans 2019-01-06 07:35:11 +01:00 committed by Patrick Georgi
parent f91344cd07
commit be291e8abf
17 changed files with 188 additions and 410 deletions

View File

@ -18,6 +18,8 @@ config PLATFORM_USES_FSP1_1
bool bool
select UEFI_2_4_BINDING select UEFI_2_4_BINDING
select INTEL_GMA_ADD_VBT if RUN_FSP_GOP select INTEL_GMA_ADD_VBT if RUN_FSP_GOP
select POSTCAR_STAGE
select POSTCAR_CONSOLE
help help
Does the code require the Intel Firmware Support Package? Does the code require the Intel Firmware Support Package?

View File

@ -28,7 +28,6 @@ romstage-y += fsp_util.c
romstage-y += hob.c romstage-y += hob.c
romstage-y += raminit.c romstage-y += raminit.c
romstage-y += romstage.c romstage-y += romstage.c
romstage-y += stack.c
romstage-y += stage_cache.c romstage-y += stage_cache.c
romstage-$(CONFIG_MMA) += mma_core.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 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 # Add the FSP binary to the cbfs image
ifeq ($(CONFIG_HAVE_FSP_BIN),y) ifeq ($(CONFIG_HAVE_FSP_BIN),y)
cbfs-files-y += fsp.bin cbfs-files-y += fsp.bin

View File

@ -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

View File

@ -147,12 +147,6 @@ before_romstage:
/* Call cache_as_ram_main(struct cache_as_ram_params *) */ /* Call cache_as_ram_main(struct cache_as_ram_params *) */
call cache_as_ram_main 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 movb $0x69, %ah
jmp .Lhlt jmp .Lhlt

View File

@ -18,28 +18,89 @@
#include <cpu/x86/mtrr.h> #include <cpu/x86/mtrr.h>
#include <fsp/car.h> #include <fsp/car.h>
#include <fsp/util.h> #include <fsp/util.h>
#include <fsp/memmap.h>
#include <program_loading.h> #include <program_loading.h>
#include <timestamp.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. */ /* platform_enter_postcar() determines the stack to use after
static inline void set_fih_car(FSP_INFO_HEADER *fih) * 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 struct postcar_frame pcf;
* ever accessed in code that that has the cache-as-ram enabled. The size_t alignment;
* assembly routine which tears down cache-as-ram utilizes this uint32_t aligned_ram;
* variable for determining where to find FSP. */
fih_car = fih; 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);
} }
asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) run_postcar_phase(&pcf);
}
/* 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; int i;
const int num_guards = 4; const int num_guards = 4;
const u32 stack_guard = 0xdeadbeef; const u32 stack_guard = 0xdeadbeef;
u32 *stack_base; u32 *stack_base;
void *ram_stack;
u32 size; u32 size;
/* Size of unallocated CAR. */ /* Size of unallocated CAR. */
@ -66,9 +127,9 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params)
display_mtrrs(); display_mtrrs();
if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE || if (car_params->bootloader_car_start != CONFIG_DCACHE_RAM_BASE
car_params->bootloader_car_end != || car_params->bootloader_car_end != (CONFIG_DCACHE_RAM_BASE
(CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE)) { + CONFIG_DCACHE_RAM_SIZE)) {
printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n", printk(BIOS_INFO, "CAR mismatch: %08x--%08x vs %08lx--%08lx\n",
CONFIG_DCACHE_RAM_BASE, CONFIG_DCACHE_RAM_BASE,
CONFIG_DCACHE_RAM_BASE + CONFIG_DCACHE_RAM_SIZE, 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_soc_post_console_init();
car_mainboard_post_console_init(); car_mainboard_post_console_init();
set_fih_car(car_params->fih); cache_as_ram_stage_main(car_params->fih);
/* Return new stack value in RAM back to assembly stub. */
ram_stack = cache_as_ram_stage_main(car_params->fih);
/* Check the stack. */ /* Check the stack. */
for (i = 0; i < num_guards; i++) { 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"); 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. */ /* This is the romstage C entry for platforms with
asmlinkage void *romstage_c_entry(void) CONFIG_C_ENVIRONMENT_BOOTBLOCK */
asmlinkage void romstage_c_entry(void)
{ {
/* Need to locate the current FSP_INFO_HEADER. The cache-as-ram /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram
* is still enabled. We can directly access work buffer here. */ * is still enabled. We can directly access work buffer here. */
@ -107,24 +167,16 @@ asmlinkage void *romstage_c_entry(void)
if (prog_locate(&fsp)) { if (prog_locate(&fsp)) {
fih = NULL; fih = NULL;
printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp)); printk(BIOS_ERR, "Unable to locate %s\n", prog_name(&fsp));
} else } else {
/* This leaks a mapping which this code assumes is benign as /* This leaks a mapping which this code assumes is benign as
* the flash is memory mapped CPU's address space. */ * the flash is memory mapped CPU's address space. */
fih = find_fsp((uintptr_t)rdev_mmap_full(prog_rdev(&fsp))); 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) cache_as_ram_stage_main(fih);
{
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) void __weak car_mainboard_pre_console_init(void)

View File

@ -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

View File

@ -30,14 +30,12 @@ struct cache_as_ram_params {
}; };
/* Entry points from the cache-as-ram assembly code. */ /* Entry points from the cache-as-ram assembly code. */
asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params); 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 *romstage_c_entry(void);
/* Per stage calls from the above two functions. The void * return from /* 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 * cache_as_ram_stage_main() is the stack pointer to use in RAM after
* exiting cache-as-ram mode. */ * exiting cache-as-ram mode. */
void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih); void cache_as_ram_stage_main(FSP_INFO_HEADER *fih);
void after_cache_as_ram_stage(void);
/* Mainboard and SoC initialization prior to console. */ /* Mainboard and SoC initialization prior to console. */
void car_mainboard_pre_console_init(void); void car_mainboard_pre_console_init(void);

View File

@ -87,7 +87,7 @@ void mainboard_add_dimm_info(struct romstage_params *params,
void raminit(struct romstage_params *params); void raminit(struct romstage_params *params);
void report_memory_config(void); void report_memory_config(void);
void romstage_common(struct romstage_params *params); 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. */ /* Initialize memory margin analysis settings. */
void setup_mma(MEMORY_INIT_UPD *memory_upd); void setup_mma(MEMORY_INIT_UPD *memory_upd);
void *setup_stack_and_mtrrs(void); void *setup_stack_and_mtrrs(void);

View File

@ -17,6 +17,8 @@
#ifndef FSP1_1_UTIL_H #ifndef FSP1_1_UTIL_H
#define FSP1_1_UTIL_H #define FSP1_1_UTIL_H
#include <rules.h>
#include <arch/cpu.h>
#include <fsp/api.h> #include <fsp/api.h>
/* Current users expect to get the SoC's FSP definitions by including util.h. */ /* Current users expect to get the SoC's FSP definitions by including util.h. */
#include <fsp/soc_binding.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, __attribute__((cdecl)) size_t fsp_write_line(uint8_t *buffer,
size_t number_of_bytes); size_t number_of_bytes);
asmlinkage void chipset_teardown_car_main(void);
#endif /* FSP1_1_UTIL_H */ #endif /* FSP1_1_UTIL_H */

View File

@ -38,9 +38,8 @@
#include <timestamp.h> #include <timestamp.h>
#include <vendorcode/google/chromeos/chromeos.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 = { struct romstage_params params = {
.chipset_context = fih, .chipset_context = fih,
}; };
@ -72,17 +71,11 @@ asmlinkage void *romstage_main(FSP_INFO_HEADER *fih)
mainboard_romstage_entry(&params); mainboard_romstage_entry(&params);
soc_after_ram_init(&params); soc_after_ram_init(&params);
post_code(0x38); 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. */ /* Entry from the mainboard. */
@ -161,13 +154,6 @@ void romstage_common(struct romstage_params *params)
full_reset(); full_reset();
} }
void after_cache_as_ram_stage(void)
{
/* Load the ramstage. */
run_ramstage();
die("ERROR - Failed to load ramstage!");
}
/* Initialize the power state */ /* Initialize the power state */
__weak struct chipset_power_state *fill_power_state(void) __weak struct chipset_power_state *fill_power_state(void)
{ {

View File

@ -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;
}

View File

@ -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");
}
}

View File

@ -17,6 +17,8 @@ romstage-y += pmutil.c
romstage-y += smbus.c romstage-y += smbus.c
romstage-y += tsc_freq.c romstage-y += tsc_freq.c
postcar-y += memmap.c
postcar-y += iosf.c
postcar-y += tsc_freq.c postcar-y += tsc_freq.c
ramstage-y += acpi.c ramstage-y += acpi.c

View File

@ -25,7 +25,7 @@
#include <soc/car.h> #include <soc/car.h>
#include <soc/reg_access.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 clear_smi_and_wake_events(void);
void disable_rom_shadow(void); void disable_rom_shadow(void);
void *locate_rmu_file(size_t *rmu_file_len); void *locate_rmu_file(size_t *rmu_file_len);

View File

@ -29,12 +29,6 @@ car_stage_entry:
/* Enter the C code */ /* Enter the C code */
call car_stage_c_entry 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 */ /* The code should never reach this point */
movb $0x69, %ah movb $0x69, %ah
jmp .Lhlt jmp .Lhlt

View File

@ -26,7 +26,7 @@
#include <soc/reg_access.h> #include <soc/reg_access.h>
#include <soc/storage_test.h> #include <soc/storage_test.h>
asmlinkage void *car_stage_c_entry(void) asmlinkage void car_stage_c_entry(void)
{ {
struct postcar_frame pcf; struct postcar_frame pcf;
bool s3wake; bool s3wake;
@ -83,7 +83,6 @@ asmlinkage void *car_stage_c_entry(void)
postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRTHROUGH); postcar_frame_add_romcache(&pcf, MTRR_TYPE_WRTHROUGH);
run_postcar_phase(&pcf); run_postcar_phase(&pcf);
return NULL;
} }
static struct chipset_power_state power_state CAR_GLOBAL; static struct chipset_power_state power_state CAR_GLOBAL;

View File

@ -13,6 +13,8 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <cpu/x86/post_code.h>
/* I/O delay between post codes on failure */ /* I/O delay between post codes on failure */
#define LHLT_DELAY 0x50000 #define LHLT_DELAY 0x50000
@ -20,9 +22,8 @@
.global car_stage_entry .global car_stage_entry
car_stage_entry: car_stage_entry:
call romstage_c_entry call romstage_c_entry
#include "src/drivers/intel/fsp1_1/after_raminit.S"
/* we don't return here */
movb $0x69, %ah movb $0x69, %ah
jmp .Lhlt jmp .Lhlt