xref: /arm-trusted-firmware/plat/arm/common/arm_sip_svc.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <stdint.h>
8*91f16700Schasinglulu 
9*91f16700Schasinglulu #include <common/debug.h>
10*91f16700Schasinglulu #include <common/runtime_svc.h>
11*91f16700Schasinglulu #include <drivers/arm/ethosn.h>
12*91f16700Schasinglulu #include <lib/debugfs.h>
13*91f16700Schasinglulu #include <lib/pmf/pmf.h>
14*91f16700Schasinglulu #include <plat/arm/common/arm_sip_svc.h>
15*91f16700Schasinglulu #include <plat/arm/common/plat_arm.h>
16*91f16700Schasinglulu #include <tools_share/uuid.h>
17*91f16700Schasinglulu 
18*91f16700Schasinglulu /* ARM SiP Service UUID */
19*91f16700Schasinglulu DEFINE_SVC_UUID2(arm_sip_svc_uid,
20*91f16700Schasinglulu 	0x556d75e2, 0x6033, 0xb54b, 0xb5, 0x75,
21*91f16700Schasinglulu 	0x62, 0x79, 0xfd, 0x11, 0x37, 0xff);
22*91f16700Schasinglulu 
23*91f16700Schasinglulu static int arm_sip_setup(void)
24*91f16700Schasinglulu {
25*91f16700Schasinglulu 	if (pmf_setup() != 0) {
26*91f16700Schasinglulu 		return 1;
27*91f16700Schasinglulu 	}
28*91f16700Schasinglulu 
29*91f16700Schasinglulu #if USE_DEBUGFS
30*91f16700Schasinglulu 
31*91f16700Schasinglulu 	if (debugfs_smc_setup() != 0) {
32*91f16700Schasinglulu 		return 1;
33*91f16700Schasinglulu 	}
34*91f16700Schasinglulu 
35*91f16700Schasinglulu #endif /* USE_DEBUGFS */
36*91f16700Schasinglulu 
37*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER
38*91f16700Schasinglulu 
39*91f16700Schasinglulu 	if (ethosn_smc_setup() != 0) {
40*91f16700Schasinglulu 		return 1;
41*91f16700Schasinglulu 	}
42*91f16700Schasinglulu 
43*91f16700Schasinglulu #endif /* ETHOSN_NPU_DRIVER */
44*91f16700Schasinglulu 
45*91f16700Schasinglulu 	return 0;
46*91f16700Schasinglulu }
47*91f16700Schasinglulu 
48*91f16700Schasinglulu /*
49*91f16700Schasinglulu  * This function handles ARM defined SiP Calls
50*91f16700Schasinglulu  */
51*91f16700Schasinglulu static uintptr_t arm_sip_handler(unsigned int smc_fid,
52*91f16700Schasinglulu 			u_register_t x1,
53*91f16700Schasinglulu 			u_register_t x2,
54*91f16700Schasinglulu 			u_register_t x3,
55*91f16700Schasinglulu 			u_register_t x4,
56*91f16700Schasinglulu 			void *cookie,
57*91f16700Schasinglulu 			void *handle,
58*91f16700Schasinglulu 			u_register_t flags)
59*91f16700Schasinglulu {
60*91f16700Schasinglulu 	int call_count = 0;
61*91f16700Schasinglulu 
62*91f16700Schasinglulu #if ENABLE_PMF
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	/*
65*91f16700Schasinglulu 	 * Dispatch PMF calls to PMF SMC handler and return its return
66*91f16700Schasinglulu 	 * value
67*91f16700Schasinglulu 	 */
68*91f16700Schasinglulu 	if (is_pmf_fid(smc_fid)) {
69*91f16700Schasinglulu 		return pmf_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
70*91f16700Schasinglulu 				handle, flags);
71*91f16700Schasinglulu 	}
72*91f16700Schasinglulu 
73*91f16700Schasinglulu #endif /* ENABLE_PMF */
74*91f16700Schasinglulu 
75*91f16700Schasinglulu #if USE_DEBUGFS
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 	if (is_debugfs_fid(smc_fid)) {
78*91f16700Schasinglulu 		return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
79*91f16700Schasinglulu 					   handle, flags);
80*91f16700Schasinglulu 	}
81*91f16700Schasinglulu 
82*91f16700Schasinglulu #endif /* USE_DEBUGFS */
83*91f16700Schasinglulu 
84*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER
85*91f16700Schasinglulu 
86*91f16700Schasinglulu 	if (is_ethosn_fid(smc_fid)) {
87*91f16700Schasinglulu 		return ethosn_smc_handler(smc_fid, x1, x2, x3, x4, cookie,
88*91f16700Schasinglulu 					  handle, flags);
89*91f16700Schasinglulu 	}
90*91f16700Schasinglulu 
91*91f16700Schasinglulu #endif /* ETHOSN_NPU_DRIVER */
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	switch (smc_fid) {
94*91f16700Schasinglulu 	case ARM_SIP_SVC_EXE_STATE_SWITCH: {
95*91f16700Schasinglulu 		/* Execution state can be switched only if EL3 is AArch64 */
96*91f16700Schasinglulu #ifdef __aarch64__
97*91f16700Schasinglulu 		/* Allow calls from non-secure only */
98*91f16700Schasinglulu 		if (!is_caller_non_secure(flags))
99*91f16700Schasinglulu 			SMC_RET1(handle, STATE_SW_E_DENIED);
100*91f16700Schasinglulu 
101*91f16700Schasinglulu 		/*
102*91f16700Schasinglulu 		 * Pointers used in execution state switch are all 32 bits wide
103*91f16700Schasinglulu 		 */
104*91f16700Schasinglulu 		return (uintptr_t) arm_execution_state_switch(smc_fid,
105*91f16700Schasinglulu 				(uint32_t) x1, (uint32_t) x2, (uint32_t) x3,
106*91f16700Schasinglulu 				(uint32_t) x4, handle);
107*91f16700Schasinglulu #else
108*91f16700Schasinglulu 		/* State switch denied */
109*91f16700Schasinglulu 		SMC_RET1(handle, STATE_SW_E_DENIED);
110*91f16700Schasinglulu #endif /* __aarch64__ */
111*91f16700Schasinglulu 		}
112*91f16700Schasinglulu 
113*91f16700Schasinglulu 	case ARM_SIP_SVC_CALL_COUNT:
114*91f16700Schasinglulu 		/* PMF calls */
115*91f16700Schasinglulu 		call_count += PMF_NUM_SMC_CALLS;
116*91f16700Schasinglulu 
117*91f16700Schasinglulu #if ETHOSN_NPU_DRIVER
118*91f16700Schasinglulu 		/* ETHOSN calls */
119*91f16700Schasinglulu 		call_count += ETHOSN_NUM_SMC_CALLS;
120*91f16700Schasinglulu #endif          /* ETHOSN_NPU_DRIVER */
121*91f16700Schasinglulu 
122*91f16700Schasinglulu 		/* State switch call */
123*91f16700Schasinglulu 		call_count += 1;
124*91f16700Schasinglulu 
125*91f16700Schasinglulu 		SMC_RET1(handle, call_count);
126*91f16700Schasinglulu 
127*91f16700Schasinglulu 	case ARM_SIP_SVC_UID:
128*91f16700Schasinglulu 		/* Return UID to the caller */
129*91f16700Schasinglulu 		SMC_UUID_RET(handle, arm_sip_svc_uid);
130*91f16700Schasinglulu 
131*91f16700Schasinglulu 	case ARM_SIP_SVC_VERSION:
132*91f16700Schasinglulu 		/* Return the version of current implementation */
133*91f16700Schasinglulu 		SMC_RET2(handle, ARM_SIP_SVC_VERSION_MAJOR, ARM_SIP_SVC_VERSION_MINOR);
134*91f16700Schasinglulu 
135*91f16700Schasinglulu 	default:
136*91f16700Schasinglulu 		break;
137*91f16700Schasinglulu 	}
138*91f16700Schasinglulu 
139*91f16700Schasinglulu 	/*
140*91f16700Schasinglulu 	 * Fall back to allow Arm platform specific handler.
141*91f16700Schasinglulu 	 * TODO: Refactor needed to move out generic handlers from this file and
142*91f16700Schasinglulu 	 * only keep Arm Platform specific handlers here.
143*91f16700Schasinglulu 	 */
144*91f16700Schasinglulu 	return plat_arm_sip_handler(smc_fid, x1, x2, x3, x4,
145*91f16700Schasinglulu 					cookie, handle, flags);
146*91f16700Schasinglulu }
147*91f16700Schasinglulu 
148*91f16700Schasinglulu 
149*91f16700Schasinglulu /* Define a runtime service descriptor for fast SMC calls */
150*91f16700Schasinglulu DECLARE_RT_SVC(
151*91f16700Schasinglulu 	arm_sip_svc,
152*91f16700Schasinglulu 	OEN_SIP_START,
153*91f16700Schasinglulu 	OEN_SIP_END,
154*91f16700Schasinglulu 	SMC_TYPE_FAST,
155*91f16700Schasinglulu 	arm_sip_setup,
156*91f16700Schasinglulu 	arm_sip_handler
157*91f16700Schasinglulu );
158