1 /* 2 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 8 #include <common/debug.h> 9 #include <plat/common/platform.h> 10 #include <services/rmm_core_manifest.h> 11 #include <services/rmmd_svc.h> 12 #include <services/trp/platform_trp.h> 13 #include <trp_helpers.h> 14 #include "trp_private.h" 15 16 #include <platform_def.h> 17 18 /* Parameters received from the previous image */ 19 static unsigned int trp_boot_abi_version; 20 static uintptr_t trp_shared_region_start; 21 22 /* Parameters received from boot manifest */ 23 uint32_t trp_boot_manifest_version; 24 25 /******************************************************************************* 26 * Setup function for TRP. 27 ******************************************************************************/ 28 void trp_setup(uint64_t x0, 29 uint64_t x1, 30 uint64_t x2, 31 uint64_t x3) 32 { 33 /* 34 * Validate boot parameters. 35 * 36 * According to the Boot Interface ABI v.0.1, the 37 * parameters recived from EL3 are: 38 * x0: CPUID (verified earlier so not used) 39 * x1: Boot Interface version 40 * x2: PLATFORM_CORE_COUNT 41 * x3: Pointer to the shared memory area. 42 */ 43 44 (void)x0; 45 46 if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) { 47 trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH); 48 } 49 50 if ((void *)x3 == NULL) { 51 trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER); 52 } 53 54 if (x2 > TRP_PLATFORM_CORE_COUNT) { 55 trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE); 56 } 57 58 trp_boot_abi_version = x1; 59 trp_shared_region_start = x3; 60 flush_dcache_range((uintptr_t)&trp_boot_abi_version, 61 sizeof(trp_boot_abi_version)); 62 flush_dcache_range((uintptr_t)&trp_shared_region_start, 63 sizeof(trp_shared_region_start)); 64 65 /* Perform early platform-specific setup */ 66 trp_early_platform_setup((rmm_manifest_t *)trp_shared_region_start); 67 } 68 69 /* Main function for TRP */ 70 void trp_main(void) 71 { 72 NOTICE("TRP: %s\n", version_string); 73 NOTICE("TRP: %s\n", build_message); 74 NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n", 75 TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR); 76 NOTICE("TRP: Boot Manifest Version : v.%u.%u\n", 77 RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version), 78 RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version)); 79 INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); 80 INFO("TRP: Base address for the shared region : 0x%lx\n", 81 (unsigned long)trp_shared_region_start); 82 INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END 83 - RMM_BASE)); 84 INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n", 85 TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version), 86 TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version)); 87 } 88 89 /******************************************************************************* 90 * Returning RMI version back to Normal World 91 ******************************************************************************/ 92 static trp_args_t *trp_ret_rmi_version(void) 93 { 94 VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR, 95 RMI_ABI_VERSION_MINOR); 96 return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION, 97 0, 0, 0, 0, 0, 0); 98 } 99 100 /******************************************************************************* 101 * Transitioning granule of NON-SECURE type to REALM type 102 ******************************************************************************/ 103 static trp_args_t *trp_asc_mark_realm(unsigned long long x1) 104 { 105 unsigned long long ret; 106 107 VERBOSE("Delegating granule 0x%llx\n", x1); 108 ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0)); 109 110 if (ret != 0ULL) { 111 ERROR("Granule transition from NON-SECURE type to REALM type " 112 "failed 0x%llx\n", ret); 113 } 114 return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 115 } 116 117 /******************************************************************************* 118 * Transitioning granule of REALM type to NON-SECURE type 119 ******************************************************************************/ 120 static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1) 121 { 122 unsigned long long ret; 123 124 VERBOSE("Undelegating granule 0x%llx\n", x1); 125 ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0)); 126 127 if (ret != 0ULL) { 128 ERROR("Granule transition from REALM type to NON-SECURE type " 129 "failed 0x%llx\n", ret); 130 } 131 return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 132 } 133 134 /******************************************************************************* 135 * Main RMI SMC handler function 136 ******************************************************************************/ 137 trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) 138 { 139 switch (fid) { 140 case RMI_RMM_REQ_VERSION: 141 return trp_ret_rmi_version(); 142 case RMI_RMM_GRANULE_DELEGATE: 143 return trp_asc_mark_realm(x1); 144 case RMI_RMM_GRANULE_UNDELEGATE: 145 return trp_asc_mark_nonsecure(x1); 146 default: 147 ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); 148 } 149 return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); 150 } 151