diff options
Diffstat (limited to 'src/drivers/intel/fsp1_1/car.c')
-rw-r--r-- | src/drivers/intel/fsp1_1/car.c | 128 |
1 files changed, 90 insertions, 38 deletions
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) |