summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/drivers/intel/fsp1_1/Makefile.inc5
-rw-r--r--src/drivers/intel/fsp1_1/after_raminit.S4
-rw-r--r--src/drivers/intel/fsp1_1/cache_as_ram.inc5
-rw-r--r--src/drivers/intel/fsp1_1/car.c42
-rw-r--r--src/drivers/intel/fsp1_1/include/fsp/car.h1
-rw-r--r--src/drivers/intel/fsp1_1/romstage_after_verstage.S52
-rw-r--r--src/drivers/intel/fsp1_1/verstage.c28
7 files changed, 134 insertions, 3 deletions
diff --git a/src/drivers/intel/fsp1_1/Makefile.inc b/src/drivers/intel/fsp1_1/Makefile.inc
index 78e1006de4f2..a90e23a0af39 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 2cc4ef3f20f6..fe88c9d79569 100644
--- a/src/drivers/intel/fsp1_1/after_raminit.S
+++ b/src/drivers/intel/fsp1_1/after_raminit.S
@@ -24,19 +24,19 @@
#include <cpu/x86/cache.h>
#include <cpu/x86/post_code.h>
+.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 dd4522103089..57e69e67efea 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 <rules.h>
#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 9f8798366830..aa728c708ec7 100644
--- a/src/drivers/intel/fsp1_1/car.c
+++ b/src/drivers/intel/fsp1_1/car.c
@@ -17,12 +17,27 @@
* Foundation, Inc.
*/
+#include <arch/early_variables.h>
+#include <assets.h>
#include <console/console.h>
#include <ec/google/chromeec/ec.h>
#include <fsp/car.h>
+#include <fsp/util.h>
#include <soc/intel/common/util.h>
#include <timestamp.h>
+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 8234b37ea8f6..f2d1c74729a2 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 000000000000..5d4e91e8d8ee
--- /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 000000000000..608cdea726ff
--- /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 <fsp/car.h>
+#include <program_loading.h>
+
+void *cache_as_ram_stage_main(FSP_INFO_HEADER *fih)
+{
+ run_romstage();
+ /* Will actually never return. */
+ return NULL;
+}