Alexandru Gagniuc (mr.nuke.me@gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13341
-gerrit
commit af790f746fc5ebb6d24e956404698dbf935f0c74 Author: Andrey Petrov andrey.petrov@intel.com Date: Mon Nov 2 15:18:34 2015 -0800
soc/apollolake: Implement post-raminit romstage and ramstage entry
In order to decompress ramstage, romstage needs significantly larger stack than originally set up. To do this, we switch the stack to memory right after raminit is done. The new stack is allocated in a fashion similar to other soc platforms, by reserving it in CBMEM.
Change-Id: I068c283a90f318ce9ee2ad370c3fc2ccb1f8a746 Signed-off-by: Andrey Petrov andrey.petrov@intel.com --- src/soc/intel/apollolake/Kconfig | 10 ++++++++ src/soc/intel/apollolake/include/soc/romstage.h | 3 ++- src/soc/intel/apollolake/romstage/entry.inc | 13 ++++++++++ src/soc/intel/apollolake/romstage/romstage.c | 33 ++++++++++++++++++++++--- 4 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index 8bc7ad4..eb9bd79 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -72,6 +72,16 @@ config DCACHE_RAM_BOOTBLOCK_STACK_SIZE The amount of anticipated stack usage from the bootblock during pre-romstage initialization.
+config ROMSTAGE_RAM_STACK_SIZE + hex + default 0x5000 + help + The size of the romstage stack after memory is available. Because CAR + space is very crowded, only a very limited part of CAR is available + for stack. More than that is needed to decompress ramstage. This + variable indicates how much RAM to reserve for the stack after + raminit. The stack is automatically switched after romstage_main(). + config IFD_BIOS_START hex default 0x1000 diff --git a/src/soc/intel/apollolake/include/soc/romstage.h b/src/soc/intel/apollolake/include/soc/romstage.h index f57f26d..eb69558 100644 --- a/src/soc/intel/apollolake/include/soc/romstage.h +++ b/src/soc/intel/apollolake/include/soc/romstage.h @@ -15,6 +15,7 @@
#include <arch/cpu.h>
-asmlinkage void romstage_entry(void); +asmlinkage void *romstage_entry(void); +asmlinkage void romstage_after_raminit(void);
#endif /* _SOC_APOLLOLAKE_ROMSTAGE_H_ */ diff --git a/src/soc/intel/apollolake/romstage/entry.inc b/src/soc/intel/apollolake/romstage/entry.inc index b04e17e..8c0670c 100644 --- a/src/soc/intel/apollolake/romstage/entry.inc +++ b/src/soc/intel/apollolake/romstage/entry.inc @@ -19,3 +19,16 @@ apollolake_entry: mov esp, (CONFIG_DCACHE_RAM_BASE + 0x4000)
call romstage_entry + + /* + * eax contains pointer to a region in RAM that we've been given the go + * ahead to use as stack. The old stack is empty at this point, so we + * don't have to relocate anything. + */ + mov esp, eax + + /* + * TODO: set up temporary cache for RAM + * We can't tear down CAR yet because romstage resides in CAR. + */ + call romstage_after_raminit diff --git a/src/soc/intel/apollolake/romstage/romstage.c b/src/soc/intel/apollolake/romstage/romstage.c index 99953fd..6efbdd5 100644 --- a/src/soc/intel/apollolake/romstage/romstage.c +++ b/src/soc/intel/apollolake/romstage/romstage.c @@ -12,6 +12,8 @@ */
#include <arch/io.h> +#include <cbfs.h> +#include <cbmem.h> #include <console/console.h> #include <cpu/x86/msr.h> #include <device/pci_def.h> @@ -50,7 +52,26 @@ static void soc_early_romstage_init(void) pci_write_config32(PCI_DEV(0, 13, 0), 0x60, 1<<7); }
-asmlinkage void romstage_entry(void) +static void *alloc_stack_in_ram(void) +{ + uint8_t *ram_stack = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, + CONFIG_ROMSTAGE_RAM_STACK_SIZE); + + /* + * If cbmem fails to give us a memory window, try to get a stack at + * 2 MiB, and hope we can go forward. The 2 MiB address is arbitrary. + */ + if (ram_stack == NULL) { + printk(BIOS_ALERT, "Could not find place for stack\n"); + return (void *)(2 * MiB); + } + + /* The initial stack pointer should point at the top of the region */ + ram_stack += CONFIG_ROMSTAGE_RAM_STACK_SIZE - sizeof(size_t); + return ram_stack; +} + +asmlinkage void* romstage_entry(void) { /* Be careful. Bootblock might already have initialized the console */ if (!IS_ENABLED(CONFIG_BOOTBLOCK_CONSOLE)) { @@ -64,7 +85,11 @@ asmlinkage void romstage_entry(void)
fsp_memory_init();
- /* This function must not return */ - while(1) - ; + cbmem_initialize_empty(); + return alloc_stack_in_ram(); +} + +asmlinkage void romstage_after_raminit(void) +{ + run_ramstage(); }