zephyr/arch/arm/include/cortex_m/tz_ns.h
Huifeng Zhang df41deac1c arch: arm: Remove aarch32 directory
It doesn't make sense to keep the aarch32 directory in the
'arch/arm/core' directory as the aarch64 has been moved out.

This commit introduces the following major changes.

  1. Move all directories and files in 'arch/arm/core/aarch32' to
    'arch/arm/core' and remove the 'arch/arm/core/aarch32' directory.
  2. Move all directories and files in 'arch/include/aarch32' to
    'arch/include' and remove the 'arch/include/aarch32' directory.
  3. Remove the nested including in the 'arch/include/kernel_arch_func.h'
    and 'arch/include/offsets_short_arch.h' header files.
  4. Change the path string which is influenced by the changement 1
    and 2.

Signed-off-by: Huifeng Zhang <Huifeng.Zhang@arm.com>
2023-09-13 10:08:05 +01:00

143 lines
4.6 KiB
C

/*
* Copyright (c) 2020 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief TrustZone API for use in nonsecure firmware
*
* TrustZone API for Cortex-M CPUs implementing the Security Extension.
* The following API can be used by the nonsecure firmware to interact with the
* secure firmware.
*/
#ifndef ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_
#define ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_
#ifdef _ASMLANGUAGE
/* nothing */
#else
/**
* @brief Macro for "sandwiching" a function call (@p name) between two other
* calls
*
* This macro should be called via @ref __TZ_WRAP_FUNC.
*
* This macro creates the function body of an "outer" function which behaves
* exactly like the wrapped function (@p name), except that the preface function
* is called before, and the postface function afterwards.
*
* @param preface The function to call first. Must have no parameters and no
* return value.
* @param name The main function, i.e. the function to wrap. This function
* will receive the arguments, and its return value will be
* returned.
* @param postface The function to call last. Must have no parameters and no
* return value.
* @param store_lr The assembly instruction for storing away the LR value
* before the functions are called. This instruction must leave
* r0-r3 unmodified.
* @param load_lr The assembly instruction for restoring the LR value after
* the functions have been called. This instruction must leave
* r0-r3 unmodified.
*/
#define __TZ_WRAP_FUNC_RAW(preface, name, postface, store_lr, load_lr) \
__asm__ volatile( \
".global "#preface"; .type "#preface", %function"); \
__asm__ volatile( \
".global "#name"; .type "#name", %function"); \
__asm__ volatile( \
".global "#postface"; .type "#postface", %function"); \
__asm__ volatile( \
store_lr "\n\t" \
"push {r0-r3}\n\t" \
"bl " #preface "\n\t" \
"pop {r0-r3}\n\t" \
"bl " #name " \n\t" \
"push {r0-r3}\n\t" \
"bl " #postface "\n\t" \
"pop {r0-r3}\n\t" \
load_lr "\n\t" \
::);
/**
* @brief Macro for "sandwiching" a function call (@p name) in two other calls
*
* @pre The wrapped function MUST not pass arguments or return values via
* the stack. I.e. the arguments and return values must each fit within 4
* words, after accounting for alignment.
* Since nothing is passed on the stack, the stack can safely be used to
* store LR.
*
* Usage example:
*
* int foo(char *arg); // Implemented elsewhere.
* int __attribute__((naked)) foo_wrapped(char *arg)
* {
* __TZ_WRAP_FUNC(bar, foo, baz)
* }
*
* is equivalent to
*
* int foo(char *arg); // Implemented elsewhere.
* int foo_wrapped(char *arg)
* {
* bar();
* int res = foo(arg);
* baz();
* return res;
* }
*
* @note __attribute__((naked)) is not mandatory, but without it, GCC gives a
* warning for functions with a return value. It also reduces flash use.
*
* See @ref __TZ_WRAP_FUNC_RAW for more information.
*/
#define __TZ_WRAP_FUNC(preface, name, postface) \
__TZ_WRAP_FUNC_RAW(preface, name, postface, "push {r4, lr}", \
"pop {r4, pc}")
#ifdef CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS
/**
* @brief Create a thread safe wrapper function for a non-secure entry function
*
* This locks the scheduler before calling the function by wrapping the NS entry
* function in @ref k_sched_lock / @ref k_sched_unlock, using
* @ref __TZ_WRAP_FUNC.
*
* In non-secure code:
*
* int foo(char *arg); // Declaration of entry function.
* TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(foo_safe, int, foo, char *arg)
*
* Usage in non-secure code:
*
* int ret = foo_safe("my arg");
*
* If NS entry functions are called without such a wrapper, and a thread switch
* happens while execution is in the secure binary, the app will possibly crash
* upon returning to the non-secure binary.
*
* @param ret The return type of the NS entry function.
* @param name The desired name of the safe function. This assumes there is a
* corresponding NS entry function called nsc_name.
* @param ... The rest of the signature of the function. This must be the same
* signature as the corresponding NS entry function.
*/
#define TZ_THREAD_SAFE_NONSECURE_ENTRY_FUNC(name, ret, nsc_name, ...) \
ret __attribute__((naked)) name(__VA_ARGS__) \
{ \
__TZ_WRAP_FUNC(k_sched_lock, nsc_name, k_sched_unlock); \
}
#endif /* CONFIG_ARM_FIRMWARE_USES_SECURE_ENTRY_FUNCS */
#endif /* _ASMLANGUAGE */
#endif /* ZEPHYR_ARCH_ARM_INCLUDE_AARCH32_CORTEX_M_TZ_NS_H_ */