[U-Boot] [PATCH 1/1] efi_loader: refactor switch to non-secure mode

Alexander Graf agraf at suse.de
Tue Jan 8 13:37:47 UTC 2019



On 30.12.18 15:36, Heinrich Schuchardt wrote:
> Refactor the switch from supervisor to hypervisor to a new function called
> at the beginning of do_bootefi().
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
> ---
> v3
> 	Move weak function to common/bootm.c.
> 	Rename functions.
> 	Add more comments.
> 	Avoid static variable for jump buffer.
> v2
> 	Use weak function with implementation in arch directories
> ---
>  arch/arm/cpu/armv7/Makefile          |  1 +
>  arch/arm/cpu/armv7/exception_level.c | 56 ++++++++++++++++++++++
>  arch/arm/cpu/armv8/Makefile          |  1 +
>  arch/arm/cpu/armv8/exception_level.c | 55 +++++++++++++++++++++
>  cmd/bootefi.c                        | 72 ++--------------------------
>  common/bootm.c                       | 10 ++++
>  include/bootm.h                      |  5 ++
>  7 files changed, 132 insertions(+), 68 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/exception_level.c
>  create mode 100644 arch/arm/cpu/armv8/exception_level.c
> 
> diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
> index 4f4647c90ac..8c955d0d528 100644
> --- a/arch/arm/cpu/armv7/Makefile
> +++ b/arch/arm/cpu/armv7/Makefile
> @@ -14,6 +14,7 @@ obj-$(CONFIG_SYS_ARM_MPU) += mpu_v7r.o
>  
>  ifneq ($(CONFIG_SPL_BUILD),y)
>  obj-$(CONFIG_EFI_LOADER) += sctlr.o
> +obj-$(CONFIG_ARMV7_NONSEC) += exception_level.o
>  endif
>  
>  ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y)
> diff --git a/arch/arm/cpu/armv7/exception_level.c b/arch/arm/cpu/armv7/exception_level.c
> new file mode 100644
> index 00000000000..e116435623f
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/exception_level.c
> @@ -0,0 +1,56 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Switch to non-secure mode
> + *
> + * Copyright (c) 2018 Heinrich Schuchardt
> + *
> + * This module contains the ARMv7 specific code required for leaving the
> + * secure mode before booting an operating system.
> + */
> +
> +#include <common.h>
> +#include <bootm.h>
> +#include <asm/armv7.h>
> +#include <asm/secure.h>
> +#include <asm/setjmp.h>
> +
> +/**
> + * entry_non_secure() - entry point when switching to non-secure mode
> + *
> + * When switching to non-secure mode switch_to_non_secure_mode() calls this
> + * function passing a jump buffer. We use this jump buffer to restoring the

... to restore ...

> + * original stack and register state.
> + *
> + * @non_secure_jmp:	jump buffer for restoring stack and registers
> + */
> +static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
> +{
> +	dcache_enable();
> +	debug("Reached non-secure mode\n");
> +
> +	/* Restore stack and registers saved in switch_to_non_secure_mode() */
> +	longjmp(non_secure_jmp, 1);
> +}
> +
> +/**
> + * switch_to_non_secure_mode() - switch to non-secure mode
> + *
> + * Operating systems are expected to run in non-secure mode. Here we check if

This is not 100% correct. They are not always expected to be executed in
NS mode. This depends on CONFIG_ARMV7_BOOT_SEC_DEFAULT as well as
bootm_boot_mode (in your code even).

So better word this as "Operating Systems may expect to run".

> + * we are running in secure mode and switch to non-secure mode if necessary.
> + */
> +void switch_to_non_secure_mode(void)
> +{
> +	static bool is_nonsec;
> +	struct jmp_buf_data non_secure_jmp;
> +
> +	if (armv7_boot_nonsec() && !is_nonsec) {
> +		if (setjmp(&non_secure_jmp))
> +			return;
> +		dcache_disable();	/* flush cache before switch to HYP */
> +		armv7_init_nonsec();
> +		is_nonsec = true;
> +		secure_ram_addr(_do_nonsec_entry)(entry_non_secure,
> +						  (uintptr_t)&non_secure_jmp,
> +						  0, 0);
> +	}
> +}
> diff --git a/arch/arm/cpu/armv8/Makefile b/arch/arm/cpu/armv8/Makefile
> index 52c8daa0496..8b0b887a696 100644
> --- a/arch/arm/cpu/armv8/Makefile
> +++ b/arch/arm/cpu/armv8/Makefile
> @@ -14,6 +14,7 @@ ifdef CONFIG_SPL_BUILD
>  obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
>  else
>  obj-y	+= exceptions.o
> +obj-y   += exception_level.o

Please use a tab here.

>  endif
>  obj-y	+= cache.o
>  obj-y	+= tlb.o
> diff --git a/arch/arm/cpu/armv8/exception_level.c b/arch/arm/cpu/armv8/exception_level.c
> new file mode 100644
> index 00000000000..245af3f1d4e
> --- /dev/null
> +++ b/arch/arm/cpu/armv8/exception_level.c
> @@ -0,0 +1,55 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Switch to non-secure mode
> + *
> + * Copyright (c) 2018 Heinrich Schuchardt
> + *
> + * This module contains the ARMv8 specific code required to adjust the exception
> + * level before booting an operating system.
> + */
> +
> +#include <common.h>
> +#include <bootm.h>
> +#include <asm/setjmp.h>
> +
> +/**
> + * entry_non_secure() - entry point when switching to non-secure mode
> + *
> + * When switching to non-secure mode switch_to_non_secure_mode() calls this
> + * function passing a jump buffer. We use this jump buffer to restoring the

... restore ...

The rest looks great :). Much cleaner!


Alex


More information about the U-Boot mailing list