diff --git a/src/drivers/intel/fsp1_1/Makefile.inc b/src/drivers/intel/fsp1_1/Makefile.inc index 78e1006de4..a90e23a0af 100644 --- a/src/drivers/intel/fsp1_1/Makefile.inc +++ b/src/drivers/intel/fsp1_1/Makefile.inc @@ -18,9 +18,14 @@ # Foundation, Inc. # +verstage-y += car.c +verstage-y += fsp_util.c +verstage-y += verstage.c + romstage-y += car.c romstage-y += fsp_util.c romstage-y += hob.c +romstage-$(CONFIG_SEPARATE_VERSTAGE) += romstage_after_verstage.S ramstage-$(CONFIG_GOP_SUPPORT) += fsp_gop.c ramstage-y += fsp_relocate.c diff --git a/src/drivers/intel/fsp1_1/after_raminit.S b/src/drivers/intel/fsp1_1/after_raminit.S index 2cc4ef3f20..fe88c9d795 100644 --- a/src/drivers/intel/fsp1_1/after_raminit.S +++ b/src/drivers/intel/fsp1_1/after_raminit.S @@ -24,19 +24,19 @@ #include #include +.extern fih_car /* * This is the common entry point after DRAM has been initialized. */ /* * eax: New stack address - * ebx: FSP_INFO_HEADER address */ /* Switch to the stack in RAM */ movl %eax, %esp /* Calculate TempRamExit entry into FSP */ - movl %ebx, %ebp + movl fih_car, %ebp mov 0x40(%ebp), %eax add 0x1c(%ebp), %eax diff --git a/src/drivers/intel/fsp1_1/cache_as_ram.inc b/src/drivers/intel/fsp1_1/cache_as_ram.inc index dd45221030..57e69e67ef 100644 --- a/src/drivers/intel/fsp1_1/cache_as_ram.inc +++ b/src/drivers/intel/fsp1_1/cache_as_ram.inc @@ -28,6 +28,7 @@ * performs the final stage of initialization. */ +#include #define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */ @@ -151,7 +152,11 @@ 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 9f87983668..aa728c708e 100644 --- a/src/drivers/intel/fsp1_1/car.c +++ b/src/drivers/intel/fsp1_1/car.c @@ -17,12 +17,27 @@ * Foundation, Inc. */ +#include +#include #include #include #include +#include #include #include +FSP_INFO_HEADER *fih_car CAR_GLOBAL; + +/* Save FSP_INFO_HEADER for TempRamExit() call in assembly. */ +static inline void set_fih_car(FSP_INFO_HEADER *fih) +{ + /* 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; +} + asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) { /* Initialize timestamp book keeping only once. */ @@ -52,13 +67,38 @@ asmlinkage void *cache_as_ram_main(struct cache_as_ram_params *car_params) car_mainboard_post_console_init(); /* Ensure the EC is in the right mode for recovery */ - if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC)) + if (IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) && + !IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)) google_chromeec_early_init(); + set_fih_car(car_params->fih); + /* Return new stack value in ram back to assembly stub. */ return cache_as_ram_stage_main(car_params->fih); } +/* Entry point taken when romstage is called after a separate verstage. */ +asmlinkage void *romstage_after_verstage(void) +{ + /* Need to locate the current FSP_INFO_HEADER. The cache-as-ram + * is still enabled. We can directly access work buffer here. */ + FSP_INFO_HEADER *fih; + struct asset fsp = ASSET_INIT(ASSET_REFCODE, "fsp.bin"); + + console_init(); + + if (asset_locate(&fsp)) { + fih = NULL; + printk(BIOS_ERR, "Unable to locate %s\n", asset_name(&fsp)); + } else + fih = find_fsp((uintptr_t)asset_mmap(&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); diff --git a/src/drivers/intel/fsp1_1/include/fsp/car.h b/src/drivers/intel/fsp1_1/include/fsp/car.h index 8234b37ea8..f2d1c74729 100644 --- a/src/drivers/intel/fsp1_1/include/fsp/car.h +++ b/src/drivers/intel/fsp1_1/include/fsp/car.h @@ -36,6 +36,7 @@ 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_after_verstage(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. */ diff --git a/src/drivers/intel/fsp1_1/romstage_after_verstage.S b/src/drivers/intel/fsp1_1/romstage_after_verstage.S new file mode 100644 index 0000000000..5d4e91e8d8 --- /dev/null +++ b/src/drivers/intel/fsp1_1/romstage_after_verstage.S @@ -0,0 +1,52 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#define LHLT_DELAY 0x50000 /* I/O delay between post codes on failure */ + +.text +.global _start +_start: + /* This is the romstage entry point when CONFIG_SEPARATE_VERSTAGE + * is used. The stack, descriptors, and gdt are already initialized + * by verstage. However, in order to maintain the semantics of + * CAR_GLOBAL variables we need to clear those to zero. */ + cld + xor %eax, %eax + movl $(_car_global_end), %ecx + movl $(_car_global_start), %edi + sub %edi, %ecx + rep stosl + call romstage_after_verstage + #include "after_raminit.S" + + movb $0x69, %ah + jmp .Lhlt + +.Lhlt: + xchg %al, %ah +#if IS_ENABLED(CONFIG_POST_IO) + outb %al, $CONFIG_POST_IO_PORT +#else + post_code(POST_DEAD_CODE) +#endif + movl $LHLT_DELAY, %ecx +.Lhlt_Delay: + outb %al, $0xED + loop .Lhlt_Delay + jmp .Lhlt diff --git a/src/drivers/intel/fsp1_1/verstage.c b/src/drivers/intel/fsp1_1/verstage.c new file mode 100644 index 0000000000..608cdea726 --- /dev/null +++ b/src/drivers/intel/fsp1_1/verstage.c @@ -0,0 +1,28 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc. + */ + +#include +#include + +void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih) +{ + run_romstage(); + /* Will actually never return. */ + return NULL; +}