xref: /rk3399_ARM-atf/plat/arm/common/plat_arm_sip_svc.c (revision 430f246e58d146949d399d72294f56403672bee0)
1 /*
2  * Copyright (c) 2023-2026, Arm Limited. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <stdint.h>
8 #include <errno.h>
9 
10 #include <arch_features.h>
11 #include <common/debug.h>
12 #include <common/runtime_svc.h>
13 
14 #include <plat/arm/common/arm_sip_svc.h>
15 #include <plat/common/platform.h>
16 
17 #if SPMD_SPM_AT_SEL2
18 #include <lib/gpt_rme/gpt_rme.h>
19 #endif
20 
21 #if ENABLE_SPMD_LP
22 #include <services/el3_spmd_logical_sp.h>
23 #endif
24 
25 #if (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
plat_protect_memory(bool protect,bool secure_origin,const uint64_t base,const size_t size,void * handle)26 static uint64_t plat_protect_memory(bool protect,
27 				    bool secure_origin,
28 				    const uint64_t base,
29 				    const size_t size,
30 				    void *handle)
31 {
32 	uint64_t ret = SMC_INVALID_PARAM;
33 	uint64_t last_updated = 0;
34 	uint64_t granule_count;
35 
36 	if (!is_feat_rme_supported()) {
37 		SMC_RET1(handle, SMC_UNK);
38 	}
39 
40 	if (!secure_origin) {
41 		SMC_RET1(handle, SMC_UNK);
42 		/* Shall not be reached. */
43 	}
44 
45 	if ((base % PAGE_SIZE_4KB) != 0U &&
46 	    (size % PAGE_SIZE_4KB) != 0U) {
47 		VERBOSE("Base address must be aligned to 4k.\n");
48 		SMC_RET1(handle, SMC_INVALID_PARAM);
49 		/* Shall not be reached. */
50 	}
51 
52 	if ((ULONG_MAX - base) < size) {
53 		VERBOSE("Base + Size results in overflow.\n");
54 		SMC_RET1(handle, SMC_INVALID_PARAM);
55 		/* Shall not be reached. */
56 	}
57 
58 	for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) {
59 		/*
60 		 * If protect is true, add memory to secure PAS.
61 		 * Else unprotect it, making part of non-secure PAS.
62 		 */
63 		granule_count = 1;
64 
65 		if (protect) {
66 			ret = gpt_transition_pas(it, &granule_count,
67 						 GPT_GPI_SECURE,
68 						 SMC_FROM_SECURE);
69 		} else {
70 			ret = gpt_transition_pas(it, &granule_count, GPT_GPI_NS,
71 						 SMC_FROM_SECURE);
72 		}
73 
74 		switch (ret) {
75 		case 0:
76 			last_updated = it;
77 			break;
78 		case -EINVAL:
79 			SMC_RET2(handle, SMC_INVALID_PARAM, last_updated);
80 			break; /* Shall not be reached. */
81 		case -EPERM:
82 			SMC_RET2(handle, SMC_DENIED, last_updated);
83 			break; /* Shall not be reached. */
84 		default:
85 			ERROR("Unexpected return\n");
86 			panic();
87 		}
88 	}
89 
90 	SMC_RET1(handle, SMC_OK);
91 }
92 #endif /* SPMD_SPM_AT_SEL2 */
93 
plat_arm_sip_handler(uint32_t smc_fid,u_register_t x1,u_register_t x2,u_register_t x3,u_register_t x4,void * cookie,void * handle,u_register_t flags)94 uintptr_t plat_arm_sip_handler(uint32_t smc_fid,
95 				u_register_t x1,
96 				u_register_t x2,
97 				u_register_t x3,
98 				u_register_t x4,
99 				void *cookie,
100 				void *handle,
101 				u_register_t flags)
102 {
103 	bool secure_origin;
104 
105 	/* Determine which security state this SMC originated from */
106 	secure_origin = is_caller_secure(flags);
107 	(void) secure_origin;
108 
109 	switch (smc_fid) {
110 #if PLAT_TEST_SPM
111 	case ARM_SIP_SET_INTERRUPT_PENDING:
112 		if (!secure_origin) {
113 			SMC_RET1(handle, SMC_UNK);
114 		}
115 
116 		VERBOSE("SiP Call- Set interrupt pending %d\n", (uint32_t)x1);
117 		plat_ic_set_interrupt_pending(x1);
118 
119 		SMC_RET1(handle, SMC_OK);
120 		break; /* Not reached */
121 #endif
122 
123 #if (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
124 	case PLAT_PROTECT_MEM_SMC64:
125 		VERBOSE("Sip Call - Protect memory\n");
126 		return plat_protect_memory(true, secure_origin, x1, x2, handle);
127 		break;
128 	case PLAT_UNPROTECT_MEM_SMC64:
129 		VERBOSE("Sip Call - Unprotect memory\n");
130 		return plat_protect_memory(false, secure_origin, x1, x2, handle);
131 		break;
132 #endif
133 	}
134 
135 #if ENABLE_SPMD_LP
136 	return plat_spmd_logical_sp_smc_handler(smc_fid, x1, x2, x3, x4,
137 				cookie, handle, flags);
138 #else
139 	WARN("Unimplemented ARM SiP Service Call: 0x%x\n", smc_fid);
140 	SMC_RET1(handle, SMC_UNK);
141 #endif
142 }
143