Message ID | 20190130035935.235565-21-sjg@chromium.org |
---|---|
State | Superseded |
Delegated to: | Bin Meng |
Headers | show |
Series | x86: Add support for booting from TPL | expand |
Hi Simon, On Wed, Jan 30, 2019 at 12:00 PM Simon Glass <sjg@chromium.org> wrote: > > When a previous phase of U-Boot has run we need to adjust the init of > subsequent states to avoid messing up the CPU state. > > Add a new version of the start logic for SPL, when it boots from TPL > (start_from tpl.c) and a new version for U-Boot when it boots from SPL. > > Signed-off-by: Simon Glass <sjg@chromium.org> > --- > > arch/x86/Makefile | 12 ++++++ > arch/x86/cpu/Makefile | 15 +++++++- > arch/x86/cpu/start_from_spl.S | 71 +++++++++++++++++++++++++++++++++++ > arch/x86/cpu/start_from_tpl.S | 50 ++++++++++++++++++++++++ > 4 files changed, 147 insertions(+), 1 deletion(-) > create mode 100644 arch/x86/cpu/start_from_spl.S > create mode 100644 arch/x86/cpu/start_from_tpl.S > > diff --git a/arch/x86/Makefile b/arch/x86/Makefile > index fec14847cc..9fd6cf2d3b 100644 > --- a/arch/x86/Makefile > +++ b/arch/x86/Makefile > @@ -4,9 +4,21 @@ ifeq ($(CONFIG_EFI_APP),) > ifdef CONFIG_$(SPL_)X86_64 > head-y := arch/x86/cpu/start64.o > else > +ifeq ($(CONFIG_$(SPL_TPL_)X86_16BIT_INIT),y) > head-y := arch/x86/cpu/start.o > +else > +ifndef CONFIG_SPL > +head-y := arch/x86/cpu/start.o > +else > +ifdef CONFIG_SPL_BUILD > +head-y = arch/x86/cpu/start_from_tpl.o > +else > +head-y = arch/x86/cpu/start_from_spl.o > +endif > +endif > endif > endif > +endif # EFI > > head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/start16.o > head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/resetvec.o > diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile > index 54668aab24..85fd5e616e 100644 > --- a/arch/x86/cpu/Makefile > +++ b/arch/x86/cpu/Makefile > @@ -9,9 +9,22 @@ > ifeq ($(CONFIG_$(SPL_)X86_64),y) > extra-y = start64.o > else > +ifeq ($(CONFIG_$(SPL_TPL_)X86_16BIT_INIT),y) > extra-y = start.o > +else > +ifndef CONFIG_SPL > +extra-y = start.o > +else > +ifdef CONFIG_SPL_BUILD > +extra-y = start_from_tpl.o > +else > +extra-y = start_from_spl.o > endif > -extra-$(CONFIG_$(SPL_)X86_16BIT_INIT) += resetvec.o start16.o > +endif > +endif > +endif > + > +extra-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += resetvec.o start16.o > > obj-y += cpu.o cpu_x86.o > > diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S Is it possible to consolidate start_from_spl.S and start_from_tpl.S into one file, to save some duplicates? > new file mode 100644 > index 0000000000..4d4e5d0758 > --- /dev/null > +++ b/arch/x86/cpu/start_from_spl.S > @@ -0,0 +1,71 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * 32-bit x86 Startup Code when running from SPL > + * > + * Copyright 2018 Google, Inc > + * Written by Simon Glass <sjg@chromium.org> > + */ > + > +#include <config.h> > + > +.section .text.start > +.code32 > +.globl _start > +.type _start, @function > +_start: > + /* Set up memory using the existing stack */ > + movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE - 4), %eax > +#ifdef CONFIG_DCACHE_RAM_MRC_VAR_SIZE > + subl $CONFIG_DCACHE_RAM_MRC_VAR_SIZE, %eax > +#endif > + /* > + * We don't subject CONFIG_DCACHE_RAM_MRC_VAR_SIZE since memory is > + * already set up. This has the happy side-effect of putting gd in a > + * new place separate from SPL, so the memset() in > + * board_init_f_init_reserve() does not cause any problems (otherwise > + * it would zero out the gd and crash) > + */ > + call board_init_f_alloc_reserve > + mov %eax, %esp > + > + call board_init_f_init_reserve > + > + xorl %eax, %eax > + call board_init_f > + call board_init_f_r > + > + /* Should not return here */ > + jmp . > + > +.globl board_init_f_r_trampoline > +.type board_init_f_r_trampoline, @function > +board_init_f_r_trampoline: > + /* > + * SPL has been executed and SDRAM has been initialised, U-Boot code > + * has been copied into RAM, BSS has been cleared and relocation > + * adjustments have been made. It is now time to jump into the in-RAM > + * copy of U-Boot > + * > + * %eax = Address of top of new stack > + */ > + > + /* Stack grows down from top of SDRAM */ > + movl %eax, %esp > + > + /* Re-enter U-Boot by calling board_init_f_r() */ > + call board_init_f_r > + > +die: > + hlt > + jmp die > + hlt > + > + .align 4 > +_dt_ucode_base_size: > + /* These next two fields are filled in by binman */ > +.globl ucode_base > +ucode_base: /* Declared in microcode.h */ > + .long 0 /* microcode base */ > +.globl ucode_size > +ucode_size: /* Declared in microcode.h */ > + .long 0 /* microcode size */ > diff --git a/arch/x86/cpu/start_from_tpl.S b/arch/x86/cpu/start_from_tpl.S > new file mode 100644 > index 0000000000..e27f39eddf > --- /dev/null > +++ b/arch/x86/cpu/start_from_tpl.S > @@ -0,0 +1,50 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * 32-bit x86 Startup Code when running from SPL > + * > + * Copyright 2018 Google, Inc > + * Written by Simon Glass <sjg@chromium.org> > + */ > + > +#include <config.h> > + > +.section .text.start > +.code32 > +.globl _start > +.type _start, @function > +_start: > + /* Set up memory using the existing stack */ > + mov %esp, %eax > + call board_init_f_alloc_reserve > + mov %eax, %esp > + > + call board_init_f_init_reserve > + missing "xorl %eax, %eax" here > + call board_init_f > + call board_init_f_r > + > + /* Should not return here */ > + jmp . > + > +.globl board_init_f_r_trampoline > +.type board_init_f_r_trampoline, @function > +board_init_f_r_trampoline: > + /* > + * SPL has been executed and SDRAM has been initialised, U-Boot code TPL? > + * has been copied into RAM, BSS has been cleared and relocation > + * adjustments have been made. It is now time to jump into the in-RAM > + * copy of U-Boot > + * > + * %eax = Address of top of new stack > + */ > + > + /* Stack grows down from top of SDRAM */ > + movl %eax, %esp > + > + /* Re-enter U-Boot by calling board_init_f_r() */ > + call board_init_f_r > + > +die: > + hlt > + jmp die > + hlt > -- Regards, Bin
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index fec14847cc..9fd6cf2d3b 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -4,9 +4,21 @@ ifeq ($(CONFIG_EFI_APP),) ifdef CONFIG_$(SPL_)X86_64 head-y := arch/x86/cpu/start64.o else +ifeq ($(CONFIG_$(SPL_TPL_)X86_16BIT_INIT),y) head-y := arch/x86/cpu/start.o +else +ifndef CONFIG_SPL +head-y := arch/x86/cpu/start.o +else +ifdef CONFIG_SPL_BUILD +head-y = arch/x86/cpu/start_from_tpl.o +else +head-y = arch/x86/cpu/start_from_spl.o +endif +endif endif endif +endif # EFI head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/start16.o head-$(CONFIG_$(SPL_)X86_16BIT_INIT) += arch/x86/cpu/resetvec.o diff --git a/arch/x86/cpu/Makefile b/arch/x86/cpu/Makefile index 54668aab24..85fd5e616e 100644 --- a/arch/x86/cpu/Makefile +++ b/arch/x86/cpu/Makefile @@ -9,9 +9,22 @@ ifeq ($(CONFIG_$(SPL_)X86_64),y) extra-y = start64.o else +ifeq ($(CONFIG_$(SPL_TPL_)X86_16BIT_INIT),y) extra-y = start.o +else +ifndef CONFIG_SPL +extra-y = start.o +else +ifdef CONFIG_SPL_BUILD +extra-y = start_from_tpl.o +else +extra-y = start_from_spl.o endif -extra-$(CONFIG_$(SPL_)X86_16BIT_INIT) += resetvec.o start16.o +endif +endif +endif + +extra-$(CONFIG_$(SPL_TPL_)X86_16BIT_INIT) += resetvec.o start16.o obj-y += cpu.o cpu_x86.o diff --git a/arch/x86/cpu/start_from_spl.S b/arch/x86/cpu/start_from_spl.S new file mode 100644 index 0000000000..4d4e5d0758 --- /dev/null +++ b/arch/x86/cpu/start_from_spl.S @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * 32-bit x86 Startup Code when running from SPL + * + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <config.h> + +.section .text.start +.code32 +.globl _start +.type _start, @function +_start: + /* Set up memory using the existing stack */ + movl $(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE - 4), %eax +#ifdef CONFIG_DCACHE_RAM_MRC_VAR_SIZE + subl $CONFIG_DCACHE_RAM_MRC_VAR_SIZE, %eax +#endif + /* + * We don't subject CONFIG_DCACHE_RAM_MRC_VAR_SIZE since memory is + * already set up. This has the happy side-effect of putting gd in a + * new place separate from SPL, so the memset() in + * board_init_f_init_reserve() does not cause any problems (otherwise + * it would zero out the gd and crash) + */ + call board_init_f_alloc_reserve + mov %eax, %esp + + call board_init_f_init_reserve + + xorl %eax, %eax + call board_init_f + call board_init_f_r + + /* Should not return here */ + jmp . + +.globl board_init_f_r_trampoline +.type board_init_f_r_trampoline, @function +board_init_f_r_trampoline: + /* + * SPL has been executed and SDRAM has been initialised, U-Boot code + * has been copied into RAM, BSS has been cleared and relocation + * adjustments have been made. It is now time to jump into the in-RAM + * copy of U-Boot + * + * %eax = Address of top of new stack + */ + + /* Stack grows down from top of SDRAM */ + movl %eax, %esp + + /* Re-enter U-Boot by calling board_init_f_r() */ + call board_init_f_r + +die: + hlt + jmp die + hlt + + .align 4 +_dt_ucode_base_size: + /* These next two fields are filled in by binman */ +.globl ucode_base +ucode_base: /* Declared in microcode.h */ + .long 0 /* microcode base */ +.globl ucode_size +ucode_size: /* Declared in microcode.h */ + .long 0 /* microcode size */ diff --git a/arch/x86/cpu/start_from_tpl.S b/arch/x86/cpu/start_from_tpl.S new file mode 100644 index 0000000000..e27f39eddf --- /dev/null +++ b/arch/x86/cpu/start_from_tpl.S @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * 32-bit x86 Startup Code when running from SPL + * + * Copyright 2018 Google, Inc + * Written by Simon Glass <sjg@chromium.org> + */ + +#include <config.h> + +.section .text.start +.code32 +.globl _start +.type _start, @function +_start: + /* Set up memory using the existing stack */ + mov %esp, %eax + call board_init_f_alloc_reserve + mov %eax, %esp + + call board_init_f_init_reserve + + call board_init_f + call board_init_f_r + + /* Should not return here */ + jmp . + +.globl board_init_f_r_trampoline +.type board_init_f_r_trampoline, @function +board_init_f_r_trampoline: + /* + * SPL has been executed and SDRAM has been initialised, U-Boot code + * has been copied into RAM, BSS has been cleared and relocation + * adjustments have been made. It is now time to jump into the in-RAM + * copy of U-Boot + * + * %eax = Address of top of new stack + */ + + /* Stack grows down from top of SDRAM */ + movl %eax, %esp + + /* Re-enter U-Boot by calling board_init_f_r() */ + call board_init_f_r + +die: + hlt + jmp die + hlt
When a previous phase of U-Boot has run we need to adjust the init of subsequent states to avoid messing up the CPU state. Add a new version of the start logic for SPL, when it boots from TPL (start_from tpl.c) and a new version for U-Boot when it boots from SPL. Signed-off-by: Simon Glass <sjg@chromium.org> --- arch/x86/Makefile | 12 ++++++ arch/x86/cpu/Makefile | 15 +++++++- arch/x86/cpu/start_from_spl.S | 71 +++++++++++++++++++++++++++++++++++ arch/x86/cpu/start_from_tpl.S | 50 ++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 arch/x86/cpu/start_from_spl.S create mode 100644 arch/x86/cpu/start_from_tpl.S