17a2130b4SMadhukar Pappireddy /*
26873088cSJ-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>
86873088cSJ-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
166873088cSJ-Alves #if ENABLE_RME && SPMD_SPM_AT_SEL2
176873088cSJ-Alves #include <lib/gpt_rme/gpt_rme.h>
186873088cSJ-Alves #endif
196873088cSJ-Alves
207a2130b4SMadhukar Pappireddy #if ENABLE_SPMD_LP
217a2130b4SMadhukar Pappireddy #include <services/el3_spmd_logical_sp.h>
227a2130b4SMadhukar Pappireddy #endif
237a2130b4SMadhukar Pappireddy
246873088cSJ-Alves #if (ENABLE_RME == 1) && (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)256873088cSJ-Alves static uint64_t plat_protect_memory(bool protect,
266873088cSJ-Alves bool secure_origin,
276873088cSJ-Alves const uint64_t base,
286873088cSJ-Alves const size_t size,
296873088cSJ-Alves void *handle)
306873088cSJ-Alves {
316873088cSJ-Alves uint64_t ret = SMC_INVALID_PARAM;
326873088cSJ-Alves uint64_t last_updated = 0;
336873088cSJ-Alves
346873088cSJ-Alves if (!secure_origin) {
356873088cSJ-Alves SMC_RET1(handle, SMC_UNK);
366873088cSJ-Alves /* Shall not be reached. */
376873088cSJ-Alves }
386873088cSJ-Alves
396873088cSJ-Alves if ((base % PAGE_SIZE_4KB) != 0U &&
406873088cSJ-Alves (size % PAGE_SIZE_4KB) != 0U) {
416873088cSJ-Alves VERBOSE("Base address must be aligned to 4k.\n");
426873088cSJ-Alves SMC_RET1(handle, SMC_INVALID_PARAM);
436873088cSJ-Alves /* Shall not be reached. */
446873088cSJ-Alves }
456873088cSJ-Alves
466873088cSJ-Alves if ((ULONG_MAX - base) < size) {
476873088cSJ-Alves VERBOSE("Base + Size results in overflow.\n");
486873088cSJ-Alves SMC_RET1(handle, SMC_INVALID_PARAM);
496873088cSJ-Alves /* Shall not be reached. */
506873088cSJ-Alves }
516873088cSJ-Alves
526873088cSJ-Alves for (uint64_t it = base; it < (base + size); it += PAGE_SIZE_4KB) {
536873088cSJ-Alves /*
546873088cSJ-Alves * If protect is true, add memory to secure PAS.
556873088cSJ-Alves * Else unprotect it, making part of non-secure PAS.
566873088cSJ-Alves */
576873088cSJ-Alves ret = protect
586873088cSJ-Alves ? gpt_delegate_pas(it, PAGE_SIZE_4KB,
596873088cSJ-Alves SMC_FROM_SECURE)
606873088cSJ-Alves : gpt_undelegate_pas(it, PAGE_SIZE_4KB,
616873088cSJ-Alves SMC_FROM_SECURE);
626873088cSJ-Alves
636873088cSJ-Alves switch (ret) {
646873088cSJ-Alves case 0:
656873088cSJ-Alves last_updated = it;
666873088cSJ-Alves break;
676873088cSJ-Alves case -EINVAL:
686873088cSJ-Alves SMC_RET2(handle, SMC_INVALID_PARAM, last_updated);
696873088cSJ-Alves break; /* Shall not be reached. */
706873088cSJ-Alves case -EPERM:
716873088cSJ-Alves SMC_RET2(handle, SMC_DENIED, last_updated);
726873088cSJ-Alves break; /* Shall not be reached. */
736873088cSJ-Alves default:
746873088cSJ-Alves ERROR("Unexpected return\n");
756873088cSJ-Alves panic();
766873088cSJ-Alves }
776873088cSJ-Alves }
786873088cSJ-Alves
796873088cSJ-Alves SMC_RET1(handle, SMC_OK);
806873088cSJ-Alves }
816873088cSJ-Alves #endif /* ENABLE_RME && SPMD_SPM_AT_SEL2 */
826873088cSJ-Alves
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)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);
966873088cSJ-Alves (void) secure_origin;
9720324013SMadhukar Pappireddy
9820324013SMadhukar Pappireddy switch (smc_fid) {
996873088cSJ-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
1126873088cSJ-Alves #if (ENABLE_RME == 1) && (defined(SPD_spmd) && SPMD_SPM_AT_SEL2 == 1)
1136873088cSJ-Alves case PLAT_PROTECT_MEM_SMC64:
114*29872eb3SOlivier Deprez VERBOSE("Sip Call - Protect memory\n");
1156873088cSJ-Alves return plat_protect_memory(true, secure_origin, x1, x2, handle);
1166873088cSJ-Alves break;
1176873088cSJ-Alves case PLAT_UNPROTECT_MEM_SMC64:
118*29872eb3SOlivier Deprez VERBOSE("Sip Call - Unprotect memory\n");
1196873088cSJ-Alves return plat_protect_memory(false, secure_origin, x1, x2, handle);
1206873088cSJ-Alves break;
1216873088cSJ-Alves #endif
1226873088cSJ-Alves }
1236873088cSJ-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