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