xref: /rk3399_ARM-atf/plat/arm/common/plat_arm_sip_svc.c (revision 6873088c2cd6983025b6777d4c3bde912eade571)
17a2130b4SMadhukar Pappireddy /*
2*6873088cSJ-Alves  * Copyright (c) 2023-2024, Arm Limited. All rights reserved.
37a2130b4SMadhukar Pappireddy  *
47a2130b4SMadhukar Pappireddy  * SPDX-License-Identifier: BSD-3-Clause
57a2130b4SMadhukar Pappireddy  */
67a2130b4SMadhukar Pappireddy 
77a2130b4SMadhukar Pappireddy #include <stdint.h>
8*6873088cSJ-Alves #include <errno.h>
97a2130b4SMadhukar Pappireddy 
107a2130b4SMadhukar Pappireddy #include <common/debug.h>
117a2130b4SMadhukar Pappireddy #include <common/runtime_svc.h>
127a2130b4SMadhukar Pappireddy 
137a2130b4SMadhukar Pappireddy #include <plat/arm/common/arm_sip_svc.h>
147a2130b4SMadhukar Pappireddy #include <plat/common/platform.h>
157a2130b4SMadhukar Pappireddy 
16*6873088cSJ-Alves #if ENABLE_RME && SPMD_SPM_AT_SEL2
17*6873088cSJ-Alves #include <lib/gpt_rme/gpt_rme.h>
18*6873088cSJ-Alves #endif
19*6873088cSJ-Alves 
207a2130b4SMadhukar Pappireddy #if ENABLE_SPMD_LP
217a2130b4SMadhukar Pappireddy #include <services/el3_spmd_logical_sp.h>
227a2130b4SMadhukar Pappireddy #endif
237a2130b4SMadhukar Pappireddy 
24*6873088cSJ-Alves #if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
25*6873088cSJ-Alves static uint64_t plat_protect_memory(bool protect,
26*6873088cSJ-Alves 				    bool secure_origin,
27*6873088cSJ-Alves 				    const uint64_t base,
28*6873088cSJ-Alves 				    const size_t size,
29*6873088cSJ-Alves 				    void *handle)
30*6873088cSJ-Alves {
31*6873088cSJ-Alves 	uint64_t ret = SMC_INVALID_PARAM;
32*6873088cSJ-Alves 	uint64_t last_updated = 0;
33*6873088cSJ-Alves 
34*6873088cSJ-Alves 	if (!secure_origin) {
35*6873088cSJ-Alves 		SMC_RET1(handle, SMC_UNK);
36*6873088cSJ-Alves 		/* Shall not be reached. */
37*6873088cSJ-Alves 	}
38*6873088cSJ-Alves 
39*6873088cSJ-Alves 	if ((base % PAGE_SIZE_4KB) != 0U &&
40*6873088cSJ-Alves 	    (size % PAGE_SIZE_4KB) != 0U) {
41*6873088cSJ-Alves 		VERBOSE("Base address must be aligned to 4k.\n");
42*6873088cSJ-Alves 		SMC_RET1(handle, SMC_INVALID_PARAM);
43*6873088cSJ-Alves 		/* Shall not be reached. */
44*6873088cSJ-Alves 	}
45*6873088cSJ-Alves 
46*6873088cSJ-Alves 	if ((ULONG_MAX - base) < size) {
47*6873088cSJ-Alves 		VERBOSE("Base + Size results in overflow.\n");
48*6873088cSJ-Alves 		SMC_RET1(handle, SMC_INVALID_PARAM);
49*6873088cSJ-Alves 		/* Shall not be reached. */
50*6873088cSJ-Alves 	}
51*6873088cSJ-Alves 
52*6873088cSJ-Alves 	for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) {
53*6873088cSJ-Alves 		/*
54*6873088cSJ-Alves 		 * If protect is true, add memory to secure PAS.
55*6873088cSJ-Alves 		 * Else unprotect it, making part of non-secure PAS.
56*6873088cSJ-Alves 		 */
57*6873088cSJ-Alves 		ret = protect
58*6873088cSJ-Alves 			? gpt_delegate_pas(it, PAGE_SIZE_4KB,
59*6873088cSJ-Alves 					   SMC_FROM_SECURE)
60*6873088cSJ-Alves 			: gpt_undelegate_pas(it, PAGE_SIZE_4KB,
61*6873088cSJ-Alves 					     SMC_FROM_SECURE);
62*6873088cSJ-Alves 
63*6873088cSJ-Alves 		switch (ret) {
64*6873088cSJ-Alves 		case 0:
65*6873088cSJ-Alves 			last_updated = it;
66*6873088cSJ-Alves 			break;
67*6873088cSJ-Alves 		case -EINVAL:
68*6873088cSJ-Alves 			SMC_RET2(handle, SMC_INVALID_PARAM, last_updated);
69*6873088cSJ-Alves 			break; /* Shall not be reached. */
70*6873088cSJ-Alves 		case -EPERM:
71*6873088cSJ-Alves 			SMC_RET2(handle, SMC_DENIED, last_updated);
72*6873088cSJ-Alves 			break; /* Shall not be reached. */
73*6873088cSJ-Alves 		default:
74*6873088cSJ-Alves 			ERROR("Unexpected return\n");
75*6873088cSJ-Alves 			panic();
76*6873088cSJ-Alves 		}
77*6873088cSJ-Alves 	}
78*6873088cSJ-Alves 
79*6873088cSJ-Alves 	SMC_RET1(handle, SMC_OK);
80*6873088cSJ-Alves }
81*6873088cSJ-Alves #endif /* ENABLE_RME  && SPMD_SPM_AT_SEL2 */
82*6873088cSJ-Alves 
837a2130b4SMadhukar Pappireddy uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
847a2130b4SMadhukar Pappireddy 				u_register_t x1,
857a2130b4SMadhukar Pappireddy 				u_register_t x2,
867a2130b4SMadhukar Pappireddy 				u_register_t x3,
877a2130b4SMadhukar Pappireddy 				u_register_t x4,
887a2130b4SMadhukar Pappireddy 				void *cookie,
897a2130b4SMadhukar Pappireddy 				void *handle,
907a2130b4SMadhukar Pappireddy 				u_register_t flags)
917a2130b4SMadhukar Pappireddy {
9220324013SMadhukar Pappireddy 	bool secure_origin;
9320324013SMadhukar Pappireddy 
9420324013SMadhukar Pappireddy 	/* Determine which security state this SMC originated from */
9520324013SMadhukar Pappireddy 	secure_origin = is_caller_secure(flags);
96*6873088cSJ-Alves 	(void) secure_origin;
9720324013SMadhukar Pappireddy 
9820324013SMadhukar Pappireddy 	switch (smc_fid) {
99*6873088cSJ-Alves #if PLAT_TEST_SPM
10020324013SMadhukar Pappireddy 	case ARM_SIP_SET_INTERRUPT_PENDING:
10120324013SMadhukar Pappireddy 		if (!secure_origin) {
10220324013SMadhukar Pappireddy 			SMC_RET1(handle, SMC_UNK);
10320324013SMadhukar Pappireddy 		}
10420324013SMadhukar Pappireddy 
10520324013SMadhukar Pappireddy 		VERBOSE("SiP Call- Set interrupt pending %d\n", (uint32_t)x1);
10620324013SMadhukar Pappireddy 		plat_ic_set_interrupt_pending(x1);
10720324013SMadhukar Pappireddy 
10820324013SMadhukar Pappireddy 		SMC_RET1(handle, SMC_OK);
10920324013SMadhukar Pappireddy 		break; /* Not reached */
11020324013SMadhukar Pappireddy #endif
11120324013SMadhukar Pappireddy 
112*6873088cSJ-Alves #if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
113*6873088cSJ-Alves 	case PLAT_PROTECT_MEM_SMC64:
114*6873088cSJ-Alves 		INFO("Sip Call - Protect memory\n");
115*6873088cSJ-Alves 		return plat_protect_memory(true, secure_origin, x1, x2, handle);
116*6873088cSJ-Alves 		break;
117*6873088cSJ-Alves 	case PLAT_UNPROTECT_MEM_SMC64:
118*6873088cSJ-Alves 		INFO("Sip Call - Unprotect memory\n");
119*6873088cSJ-Alves 		return plat_protect_memory(false, secure_origin, x1, x2, handle);
120*6873088cSJ-Alves 		break;
121*6873088cSJ-Alves #endif
122*6873088cSJ-Alves 	}
123*6873088cSJ-Alves 
1247a2130b4SMadhukar Pappireddy #if ENABLE_SPMD_LP
1257a2130b4SMadhukar Pappireddy 	return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
1267a2130b4SMadhukar Pappireddy 				cookie, handle, flags);
1277a2130b4SMadhukar Pappireddy #else
1287a2130b4SMadhukar Pappireddy 	WARN("Unimplemented ARM SiP Service Call: 0x%x\n", smc_fid);
1297a2130b4SMadhukar Pappireddy 	SMC_RET1(handle, SMC_UNK);
1307a2130b4SMadhukar Pappireddy #endif
1317a2130b4SMadhukar Pappireddy }
132