x86: add standalone verstage support
To support x86 verstage one needs a working buffer for vboot. That buffer resides in the cache-as-ram region which persists across verstage and romstage. The current assumption is that verstage brings cache-as-ram up and romstage tears cache-as-ram down. The timestamp, cbmem console, and the vboot work buffer are persistent through in both romstage and verstage. The vboot work buffer as well as the cbmem console are permanently destroyed once cache-as-ram is torn down. The timestamp region is migrated. When verstage is enabled the assumption is that _start is the romstage entry point. It's currently expected that the chipset provides the entry point to romstage when verstage is employed. Also, the car_var_*() APIs use direct access when in verstage since its expected verstage does not tear down cache-as-ram. Lastly, supporting files were added to verstage-y such that an x86 verstage will build and link. BUG=chrome-os-partner:44827 BRANCH=None TEST=Built and booted glados using separate verstage. Change-Id: I097aa0b92f3bb95275205a3fd8b21362c67b97aa Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/11822 Tested-by: build bot (Jenkins) Reviewed-by: Patrick Georgi <pgeorgi@google.com>
This commit is contained in:
parent
e3d2d6fd70
commit
75c51d9af1
|
@ -377,6 +377,7 @@ $(obj)/mainboard/$(MAINBOARDDIR)/static.c: $(src)/mainboard/$(MAINBOARDDIR)/devi
|
||||||
|
|
||||||
ramstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
|
ramstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
|
||||||
romstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
|
romstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
|
||||||
|
verstage-y+=$(obj)/mainboard/$(MAINBOARDDIR)/static.c
|
||||||
|
|
||||||
$(obj)/%.ramstage.o $(abspath $(obj))/%.ramstage.o: $(obj)/%.c $(obj)/config.h $(OPTION_TABLE_H)
|
$(obj)/%.ramstage.o $(abspath $(obj))/%.ramstage.o: $(obj)/%.c $(obj)/config.h $(OPTION_TABLE_H)
|
||||||
@printf " CC $(subst $(obj)/,,$(@))\n"
|
@printf " CC $(subst $(obj)/,,$(@))\n"
|
||||||
|
|
|
@ -145,6 +145,9 @@ $(1)-y += memlayout.ld
|
||||||
$(1)-y += assembly_entry.S
|
$(1)-y += assembly_entry.S
|
||||||
$$(obj)/arch/x86/assembly_entry.$(1).o: $(objgenerated)/assembly.inc
|
$$(obj)/arch/x86/assembly_entry.$(1).o: $(objgenerated)/assembly.inc
|
||||||
|
|
||||||
|
# The '.' include path is needed for the generated assembly.inc file.
|
||||||
|
$(1)-S-ccopts += -I.
|
||||||
|
|
||||||
$$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
|
$$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
|
||||||
@printf " LINK $$(subst $$(obj)/,,$$(@))\n"
|
@printf " LINK $$(subst $$(obj)/,,$$(@))\n"
|
||||||
$$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $$(obj)/arch/x86/memlayout.$(1).ld --oformat $(2)
|
$$(LD_$(1)) $$(LDFLAGS_$(1)) -o $$@ -L$$(obj) $$(COMPILER_RT_FLAGS_$(1)) --whole-archive --start-group $$(filter-out %.ld,$$($(1)-objs)) $$($(1)-libs) --no-whole-archive $$(COMPILER_RT_$(1)) --end-group -T $$(obj)/arch/x86/memlayout.$(1).ld --oformat $(2)
|
||||||
|
@ -156,6 +159,35 @@ $$(objcbfs)/$(1).debug: $$$$($(1)-libs) $$$$($(1)-objs)
|
||||||
else true; fi
|
else true; fi
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# verstage
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32)$(CONFIG_ARCH_VERSTAGE_X86_64),y)
|
||||||
|
|
||||||
|
verstage-y += boot.c
|
||||||
|
|
||||||
|
verstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += cpu_common.c
|
||||||
|
verstage-y += memset.c
|
||||||
|
verstage-y += memcpy.c
|
||||||
|
verstage-y += memmove.c
|
||||||
|
verstage-y += mmap_boot.c
|
||||||
|
|
||||||
|
verstage-$(CONFIG_COLLECT_TIMESTAMPS) += timestamp.c
|
||||||
|
|
||||||
|
verstage-libs += $(objgenerated)/libverstage.a
|
||||||
|
|
||||||
|
ifeq ($(CONFIG_ARCH_VERSTAGE_X86_32),y)
|
||||||
|
$(eval $(call early_x86_stage,verstage,elf32-i386))
|
||||||
|
else
|
||||||
|
$(eval $(call early_x86_stage,verstage,elf64-x86-64))
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Verstage on x86 expected to be xip.
|
||||||
|
CBFSTOOL_VERSTAGE_OPTS = -a 64 --xip -S ".car.data"
|
||||||
|
|
||||||
|
endif # CONFIG_ARCH_VERSTAGE_X86_32 / CONFIG_ARCH_VERSTAGE_X86_64
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
# romstage
|
# romstage
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -211,7 +243,7 @@ $(eval $(call early_x86_stage,romstage,elf64-x86-64))
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Compiling crt0 with -g seems to trigger https://sourceware.org/bugzilla/show_bug.cgi?id=6428
|
# Compiling crt0 with -g seems to trigger https://sourceware.org/bugzilla/show_bug.cgi?id=6428
|
||||||
romstage-S-ccopts += -I. -g0
|
romstage-S-ccopts += -g0
|
||||||
|
|
||||||
endif # CONFIG_ARCH_ROMSTAGE_X86_32 / CONFIG_ARCH_ROMSTAGE_X86_64
|
endif # CONFIG_ARCH_ROMSTAGE_X86_32 / CONFIG_ARCH_ROMSTAGE_X86_64
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,12 @@ static void main(unsigned long bist)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_SEPARATE_VERSTAGE
|
||||||
|
const char* target1 = "fallback/verstage";
|
||||||
|
#else
|
||||||
const char* target1 = "fallback/romstage";
|
const char* target1 = "fallback/romstage";
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long entry;
|
unsigned long entry;
|
||||||
entry = findstage(target1);
|
entry = findstage(target1);
|
||||||
if (entry) call(entry, bist);
|
if (entry) call(entry, bist);
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
/* This file is included inside a SECTIONS block */
|
/* This file is included inside a SECTIONS block */
|
||||||
. = CONFIG_DCACHE_RAM_BASE;
|
. = CONFIG_DCACHE_RAM_BASE;
|
||||||
.car.data . (NOLOAD) : {
|
.car.data . (NOLOAD) : {
|
||||||
|
/* Vboot work buffer is completely volatile outside of verstage and
|
||||||
|
* romstage. Appropriate code needs to handle the transition. */
|
||||||
|
#if IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)
|
||||||
|
VBOOT2_WORK(., 16K)
|
||||||
|
#endif
|
||||||
/* The pre-ram cbmem console as well as the timestamp region are fixed
|
/* The pre-ram cbmem console as well as the timestamp region are fixed
|
||||||
* in size. Therefore place them at the beginning .car.data section
|
* in size. Therefore place them at the beginning .car.data section
|
||||||
* so that multiple stages (romstage and verstage) have a consistent
|
* so that multiple stages (romstage and verstage) have a consistent
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#define ARCH_EARLY_VARIABLES_H
|
#define ARCH_EARLY_VARIABLES_H
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <rules.h>
|
||||||
|
|
||||||
#if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_CACHE_AS_RAM)
|
#if defined(__PRE_RAM__) && IS_ENABLED(CONFIG_CACHE_AS_RAM)
|
||||||
asm(".section .car.global_data,\"w\",@nobits");
|
asm(".section .car.global_data,\"w\",@nobits");
|
||||||
|
@ -31,11 +32,27 @@ asm(".previous");
|
||||||
#define CAR_GLOBAL __attribute__((used,section(".car.global_data#")))
|
#define CAR_GLOBAL __attribute__((used,section(".car.global_data#")))
|
||||||
#endif /* __clang__ */
|
#endif /* __clang__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* On x86 verstage, all CAR_GLOBAL variables are accessed unconditionally
|
||||||
|
* because cbmem is never initialized until romstage when dram comes up.
|
||||||
|
*/
|
||||||
|
#if ENV_VERSTAGE
|
||||||
|
static inline void *car_get_var_ptr(void *var)
|
||||||
|
{
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *car_sync_var_ptr(void *var)
|
||||||
|
{
|
||||||
|
return var;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* Get the correct pointer for the CAR global variable. */
|
/* Get the correct pointer for the CAR global variable. */
|
||||||
void *car_get_var_ptr(void *var);
|
void *car_get_var_ptr(void *var);
|
||||||
|
|
||||||
/* Get and update a CAR_GLOBAL pointing elsewhere in car.global_data*/
|
/* Get and update a CAR_GLOBAL pointing elsewhere in car.global_data*/
|
||||||
void *car_sync_var_ptr(void *var);
|
void *car_sync_var_ptr(void *var);
|
||||||
|
#endif /* ENV_VERSTAGE */
|
||||||
|
|
||||||
/* Get and set a primitive type global variable. */
|
/* Get and set a primitive type global variable. */
|
||||||
#define car_get_var(var) \
|
#define car_get_var(var) \
|
||||||
|
|
|
@ -24,8 +24,23 @@ PHDRS
|
||||||
to_load PT_LOAD;
|
to_load PT_LOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENV_RAMSTAGE || ENV_RMODULE
|
/*
|
||||||
ENTRY(_start)
|
* For CONFIG_SEPARATE_VERSTAGE romstage doesn't have the cache-as-ram setup.
|
||||||
#elif ENV_ROMSTAGE
|
* It only contains the teardown code. The verstage has the cache-as-ram setup
|
||||||
ENTRY(protected_start)
|
* code. Therefore, it needs the protected_start symbol as its entry point.
|
||||||
|
* The romstage entry will be named _start for consistency, but it's likely
|
||||||
|
* to be implemented in the chipset code in order to control the logic flow.
|
||||||
|
*/
|
||||||
|
#if IS_ENABLED(CONFIG_SEPARATE_VERSTAGE)
|
||||||
|
#if ENV_RAMSTAGE || ENV_RMODULE || ENV_ROMSTAGE
|
||||||
|
ENTRY(_start)
|
||||||
|
#elif ENV_VERSTAGE
|
||||||
|
ENTRY(protected_start)
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if ENV_RAMSTAGE || ENV_RMODULE
|
||||||
|
ENTRY(_start)
|
||||||
|
#elif ENV_ROMSTAGE
|
||||||
|
ENTRY(protected_start)
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,8 +22,8 @@
|
||||||
|
|
||||||
#include <rules.h>
|
#include <rules.h>
|
||||||
|
|
||||||
#if ENV_ROMSTAGE
|
#if ENV_ROMSTAGE || ENV_VERSTAGE
|
||||||
/* No .data or .bss in romstage. Cache as ram is handled separately. */
|
/* No .data or .bss sections. Cache as ram is handled separately. */
|
||||||
#define ARCH_STAGE_HAS_DATA_SECTION 0
|
#define ARCH_STAGE_HAS_DATA_SECTION 0
|
||||||
#define ARCH_STAGE_HAS_BSS_SECTION 0
|
#define ARCH_STAGE_HAS_BSS_SECTION 0
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,6 +37,13 @@ SECTIONS
|
||||||
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
|
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
|
||||||
ROMSTAGE(32M, 1M)
|
ROMSTAGE(32M, 1M)
|
||||||
|
|
||||||
|
/* Pull in the cache-as-ram rules. */
|
||||||
|
#include "car.ld"
|
||||||
|
#elif ENV_VERSTAGE
|
||||||
|
/* The 1M size is not allocated. It's just for basic size checking.
|
||||||
|
* Link at 32MiB address and rely on cbfstool to relocate to XIP. */
|
||||||
|
VERSTAGE(32M, 1M)
|
||||||
|
|
||||||
/* Pull in the cache-as-ram rules. */
|
/* Pull in the cache-as-ram rules. */
|
||||||
#include "car.ld"
|
#include "car.ld"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -10,6 +10,7 @@ verstage-y += init.c
|
||||||
verstage-y += printk.c
|
verstage-y += printk.c
|
||||||
verstage-y += vtxprintf.c
|
verstage-y += vtxprintf.c
|
||||||
verstage-y += console.c
|
verstage-y += console.c
|
||||||
|
verstage-y += post.c
|
||||||
verstage-y += die.c
|
verstage-y += die.c
|
||||||
|
|
||||||
romstage-y += vtxprintf.c printk.c
|
romstage-y += vtxprintf.c printk.c
|
||||||
|
|
|
@ -3,5 +3,6 @@ ramstage-y += lapic_cpu_init.c
|
||||||
ramstage-y += secondary.S
|
ramstage-y += secondary.S
|
||||||
romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
|
romstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
|
||||||
ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
|
ramstage-$(CONFIG_UDELAY_LAPIC) += apic_timer.c
|
||||||
|
verstage-y += boot_cpu.c
|
||||||
romstage-y += boot_cpu.c
|
romstage-y += boot_cpu.c
|
||||||
ramstage-y += boot_cpu.c
|
ramstage-y += boot_cpu.c
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
ramstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
|
ramstage-$(CONFIG_UDELAY_TSC) += delay_tsc.c
|
||||||
romstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
|
romstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
|
||||||
|
verstage-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
|
||||||
ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
|
ifeq ($(CONFIG_HAVE_SMI_HANDLER),y)
|
||||||
smm-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
|
smm-$(CONFIG_TSC_CONSTANT_RATE) += delay_tsc.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -19,6 +19,7 @@ ifeq ($(CONFIG_AZALIA_PLUGIN_SUPPORT),y)
|
||||||
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c
|
ramstage-srcs += src/mainboard/$(MAINBOARDDIR)/hda_verb.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
verstage-y += device_romstage.c
|
||||||
romstage-y += device_romstage.c
|
romstage-y += device_romstage.c
|
||||||
romstage-$(CONFIG_PCI) += pci_early.c
|
romstage-$(CONFIG_PCI) += pci_early.c
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
verstage-$(CONFIG_LPC_TPM) += tpm.c
|
||||||
romstage-$(CONFIG_LPC_TPM) += tpm.c
|
romstage-$(CONFIG_LPC_TPM) += tpm.c
|
||||||
ramstage-$(CONFIG_LPC_TPM) += tpm.c
|
ramstage-$(CONFIG_LPC_TPM) += tpm.c
|
||||||
romstage-$(CONFIG_LPC_TPM) += romstage.c
|
romstage-$(CONFIG_LPC_TPM) += romstage.c
|
||||||
|
|
|
@ -11,12 +11,14 @@ smm-$(CONFIG_DEBUG_SMI) += util.c
|
||||||
# be located in the soc/ or cpu/ directories instead of here.
|
# be located in the soc/ or cpu/ directories instead of here.
|
||||||
|
|
||||||
ifeq ($(CONFIG_DRIVERS_UART_8250IO),y)
|
ifeq ($(CONFIG_DRIVERS_UART_8250IO),y)
|
||||||
|
verstage-y += uart8250io.c
|
||||||
romstage-y += uart8250io.c
|
romstage-y += uart8250io.c
|
||||||
ramstage-y += uart8250io.c
|
ramstage-y += uart8250io.c
|
||||||
smm-$(CONFIG_DEBUG_SMI) += uart8250io.c
|
smm-$(CONFIG_DEBUG_SMI) += uart8250io.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(CONFIG_DRIVERS_UART_8250MEM),y)
|
ifeq ($(CONFIG_DRIVERS_UART_8250MEM),y)
|
||||||
|
verstage-y += uart8250mem.c
|
||||||
romstage-y += uart8250mem.c
|
romstage-y += uart8250mem.c
|
||||||
ramstage-y += uart8250mem.c
|
ramstage-y += uart8250mem.c
|
||||||
smm-$(CONFIG_DEBUG_SMI) += uart8250mem.c
|
smm-$(CONFIG_DEBUG_SMI) += uart8250mem.c
|
||||||
|
|
|
@ -88,6 +88,7 @@ endif
|
||||||
|
|
||||||
romstage-y += compute_ip_checksum.c
|
romstage-y += compute_ip_checksum.c
|
||||||
ifeq ($(CONFIG_COMPILER_GCC),y)
|
ifeq ($(CONFIG_COMPILER_GCC),y)
|
||||||
|
verstage-$(CONFIG_ARCH_VERSTAGE_X86_32) += gcc.c
|
||||||
romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c
|
romstage-$(CONFIG_ARCH_ROMSTAGE_X86_32) += gcc.c
|
||||||
ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
|
ramstage-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
|
||||||
smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
|
smm-$(CONFIG_ARCH_RAMSTAGE_X86_32) += gcc.c
|
||||||
|
@ -140,6 +141,7 @@ ramstage-y += imd.c
|
||||||
ramstage-y += hexdump.c
|
ramstage-y += hexdump.c
|
||||||
romstage-y += hexdump.c
|
romstage-y += hexdump.c
|
||||||
|
|
||||||
|
verstage-$(CONFIG_REG_SCRIPT) += reg_script.c
|
||||||
romstage-$(CONFIG_REG_SCRIPT) += reg_script.c
|
romstage-$(CONFIG_REG_SCRIPT) += reg_script.c
|
||||||
ramstage-$(CONFIG_REG_SCRIPT) += reg_script.c
|
ramstage-$(CONFIG_REG_SCRIPT) += reg_script.c
|
||||||
|
|
||||||
|
|
|
@ -125,7 +125,7 @@ config VBOOT_BL31_INDEX
|
||||||
|
|
||||||
config VBOOT_DYNAMIC_WORK_BUFFER
|
config VBOOT_DYNAMIC_WORK_BUFFER
|
||||||
bool "Vboot's work buffer is dynamically allocated."
|
bool "Vboot's work buffer is dynamically allocated."
|
||||||
default y if ARCH_ROMSTAGE_X86_32
|
default y if ARCH_ROMSTAGE_X86_32 && !SEPARATE_VERSTAGE
|
||||||
default n
|
default n
|
||||||
depends on VBOOT_VERIFY_FIRMWARE
|
depends on VBOOT_VERIFY_FIRMWARE
|
||||||
help
|
help
|
||||||
|
|
Loading…
Reference in New Issue