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