xref: /linux/arch/arm/mach-at91/sam_secure.c (revision c71572aa544ca64cbd2ff2052c79bc7e3573baed)
10c9fd821SClément Léger // SPDX-License-Identifier: GPL-2.0-or-later
20c9fd821SClément Léger /*
30c9fd821SClément Léger  * Copyright (C) 2022, Microchip
40c9fd821SClément Léger  */
50c9fd821SClément Léger 
60c9fd821SClément Léger #include <linux/arm-smccc.h>
70c9fd821SClément Léger #include <linux/of.h>
80c9fd821SClément Léger 
90c9fd821SClément Léger #include "sam_secure.h"
100c9fd821SClément Léger 
110c9fd821SClément Léger static bool optee_available;
120c9fd821SClément Léger 
130c9fd821SClément Léger #define SAM_SIP_SMC_STD_CALL_VAL(func_num) \
140c9fd821SClément Léger 	ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \
150c9fd821SClément Léger 	ARM_SMCCC_OWNER_SIP, (func_num))
160c9fd821SClément Léger 
170c9fd821SClément Léger struct arm_smccc_res sam_smccc_call(u32 fn, u32 arg0, u32 arg1)
180c9fd821SClément Léger {
190c9fd821SClément Léger 	struct arm_smccc_res res = {.a0 = -1};
200c9fd821SClément Léger 
210c9fd821SClément Léger 	if (WARN_ON(!optee_available))
220c9fd821SClément Léger 		return res;
230c9fd821SClément Léger 
240c9fd821SClément Léger 	arm_smccc_smc(SAM_SIP_SMC_STD_CALL_VAL(fn), arg0, arg1, 0, 0, 0, 0, 0,
250c9fd821SClément Léger 		      &res);
260c9fd821SClément Léger 
270c9fd821SClément Léger 	return res;
280c9fd821SClément Léger }
290c9fd821SClément Léger 
30*c71572aaSClément Léger bool sam_linux_is_optee_available(void)
31*c71572aaSClément Léger {
32*c71572aaSClément Léger 	/* If optee has been detected, then we are running in normal world */
33*c71572aaSClément Léger 	return optee_available;
34*c71572aaSClément Léger }
35*c71572aaSClément Léger 
360c9fd821SClément Léger void __init sam_secure_init(void)
370c9fd821SClément Léger {
380c9fd821SClément Léger 	struct device_node *np;
390c9fd821SClément Léger 
400c9fd821SClément Léger 	/*
410c9fd821SClément Léger 	 * We only check that the OP-TEE node is present and available. The
420c9fd821SClément Léger 	 * OP-TEE kernel driver is not needed for the type of interaction made
430c9fd821SClément Léger 	 * with OP-TEE here so the driver's status is not checked.
440c9fd821SClément Léger 	 */
450c9fd821SClément Léger 	np = of_find_node_by_path("/firmware/optee");
460c9fd821SClément Léger 	if (np && of_device_is_available(np))
470c9fd821SClément Léger 		optee_available = true;
480c9fd821SClément Léger 	of_node_put(np);
490c9fd821SClément Léger 
500c9fd821SClément Léger 	if (optee_available)
510c9fd821SClément Léger 		pr_info("Running under OP-TEE firmware\n");
520c9fd821SClément Léger }
53