/*
 * 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) \
	do { \
		__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" \
			::); \
	} while (false)

/**
 * @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_ */
