1*50a3056aSZelalem Aweke /* 2*50a3056aSZelalem Aweke * Copyright (c) 2021, Arm Limited and Contributors. All rights reserved. 3*50a3056aSZelalem Aweke * 4*50a3056aSZelalem Aweke * SPDX-License-Identifier: BSD-3-Clause 5*50a3056aSZelalem Aweke */ 6*50a3056aSZelalem Aweke 7*50a3056aSZelalem Aweke 8*50a3056aSZelalem Aweke #include <common/debug.h> 9*50a3056aSZelalem Aweke #include <plat/common/platform.h> 10*50a3056aSZelalem Aweke #include <services/gtsi_svc.h> 11*50a3056aSZelalem Aweke #include <services/rmi_svc.h> 12*50a3056aSZelalem Aweke #include <services/trp/platform_trp.h> 13*50a3056aSZelalem Aweke 14*50a3056aSZelalem Aweke #include <platform_def.h> 15*50a3056aSZelalem Aweke #include "trp_private.h" 16*50a3056aSZelalem Aweke 17*50a3056aSZelalem Aweke /******************************************************************************* 18*50a3056aSZelalem Aweke * Per cpu data structure to populate parameters for an SMC in C code and use 19*50a3056aSZelalem Aweke * a pointer to this structure in assembler code to populate x0-x7 20*50a3056aSZelalem Aweke ******************************************************************************/ 21*50a3056aSZelalem Aweke static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT]; 22*50a3056aSZelalem Aweke 23*50a3056aSZelalem Aweke /******************************************************************************* 24*50a3056aSZelalem Aweke * Set the arguments for SMC call 25*50a3056aSZelalem Aweke ******************************************************************************/ 26*50a3056aSZelalem Aweke static trp_args_t *set_smc_args(uint64_t arg0, 27*50a3056aSZelalem Aweke uint64_t arg1, 28*50a3056aSZelalem Aweke uint64_t arg2, 29*50a3056aSZelalem Aweke uint64_t arg3, 30*50a3056aSZelalem Aweke uint64_t arg4, 31*50a3056aSZelalem Aweke uint64_t arg5, 32*50a3056aSZelalem Aweke uint64_t arg6, 33*50a3056aSZelalem Aweke uint64_t arg7) 34*50a3056aSZelalem Aweke { 35*50a3056aSZelalem Aweke uint32_t linear_id; 36*50a3056aSZelalem Aweke trp_args_t *pcpu_smc_args; 37*50a3056aSZelalem Aweke 38*50a3056aSZelalem Aweke /* 39*50a3056aSZelalem Aweke * Return to Secure Monitor by raising an SMC. The results of the 40*50a3056aSZelalem Aweke * service are passed as an arguments to the SMC 41*50a3056aSZelalem Aweke */ 42*50a3056aSZelalem Aweke linear_id = plat_my_core_pos(); 43*50a3056aSZelalem Aweke pcpu_smc_args = &trp_smc_args[linear_id]; 44*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0); 45*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1); 46*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2); 47*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3); 48*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4); 49*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5); 50*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6); 51*50a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7); 52*50a3056aSZelalem Aweke 53*50a3056aSZelalem Aweke return pcpu_smc_args; 54*50a3056aSZelalem Aweke } 55*50a3056aSZelalem Aweke 56*50a3056aSZelalem Aweke /******************************************************************************* 57*50a3056aSZelalem Aweke * Setup function for TRP. 58*50a3056aSZelalem Aweke ******************************************************************************/ 59*50a3056aSZelalem Aweke void trp_setup(void) 60*50a3056aSZelalem Aweke { 61*50a3056aSZelalem Aweke /* Perform early platform-specific setup */ 62*50a3056aSZelalem Aweke trp_early_platform_setup(); 63*50a3056aSZelalem Aweke } 64*50a3056aSZelalem Aweke 65*50a3056aSZelalem Aweke /* Main function for TRP */ 66*50a3056aSZelalem Aweke void trp_main(void) 67*50a3056aSZelalem Aweke { 68*50a3056aSZelalem Aweke NOTICE("TRP: %s\n", version_string); 69*50a3056aSZelalem Aweke NOTICE("TRP: %s\n", build_message); 70*50a3056aSZelalem Aweke INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); 71*50a3056aSZelalem Aweke INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END 72*50a3056aSZelalem Aweke - RMM_BASE)); 73*50a3056aSZelalem Aweke } 74*50a3056aSZelalem Aweke 75*50a3056aSZelalem Aweke /******************************************************************************* 76*50a3056aSZelalem Aweke * Returning RMI version back to Normal World 77*50a3056aSZelalem Aweke ******************************************************************************/ 78*50a3056aSZelalem Aweke static trp_args_t *trp_ret_rmi_version(void) 79*50a3056aSZelalem Aweke { 80*50a3056aSZelalem Aweke VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR, 81*50a3056aSZelalem Aweke RMI_ABI_VERSION_MINOR); 82*50a3056aSZelalem Aweke return set_smc_args(RMI_RMM_REQ_COMPLETE, RMI_ABI_VERSION, 83*50a3056aSZelalem Aweke 0, 0, 0, 0, 0, 0); 84*50a3056aSZelalem Aweke } 85*50a3056aSZelalem Aweke 86*50a3056aSZelalem Aweke /******************************************************************************* 87*50a3056aSZelalem Aweke * Transitioning granule of NON-SECURE type to REALM type 88*50a3056aSZelalem Aweke ******************************************************************************/ 89*50a3056aSZelalem Aweke static trp_args_t *trp_asc_mark_realm(unsigned long long x1) 90*50a3056aSZelalem Aweke { 91*50a3056aSZelalem Aweke unsigned long long ret; 92*50a3056aSZelalem Aweke 93*50a3056aSZelalem Aweke VERBOSE("Delegating granule 0x%llx\n", x1); 94*50a3056aSZelalem Aweke ret = trp_smc(set_smc_args(SMC_ASC_MARK_REALM, x1, 0, 0, 0, 0, 0, 0)); 95*50a3056aSZelalem Aweke 96*50a3056aSZelalem Aweke if (ret != 0ULL) { 97*50a3056aSZelalem Aweke ERROR("Granule transition from NON-SECURE type to REALM type " 98*50a3056aSZelalem Aweke "failed 0x%llx\n", ret); 99*50a3056aSZelalem Aweke } 100*50a3056aSZelalem Aweke return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 101*50a3056aSZelalem Aweke } 102*50a3056aSZelalem Aweke 103*50a3056aSZelalem Aweke /******************************************************************************* 104*50a3056aSZelalem Aweke * Transitioning granule of REALM type to NON-SECURE type 105*50a3056aSZelalem Aweke ******************************************************************************/ 106*50a3056aSZelalem Aweke static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1) 107*50a3056aSZelalem Aweke { 108*50a3056aSZelalem Aweke unsigned long long ret; 109*50a3056aSZelalem Aweke 110*50a3056aSZelalem Aweke VERBOSE("Undelegating granule 0x%llx\n", x1); 111*50a3056aSZelalem Aweke ret = trp_smc(set_smc_args(SMC_ASC_MARK_NONSECURE, x1, 0, 0, 0, 0, 0, 0)); 112*50a3056aSZelalem Aweke 113*50a3056aSZelalem Aweke if (ret != 0ULL) { 114*50a3056aSZelalem Aweke ERROR("Granule transition from REALM type to NON-SECURE type " 115*50a3056aSZelalem Aweke "failed 0x%llx\n", ret); 116*50a3056aSZelalem Aweke } 117*50a3056aSZelalem Aweke return set_smc_args(RMI_RMM_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 118*50a3056aSZelalem Aweke } 119*50a3056aSZelalem Aweke 120*50a3056aSZelalem Aweke /******************************************************************************* 121*50a3056aSZelalem Aweke * Main RMI SMC handler function 122*50a3056aSZelalem Aweke ******************************************************************************/ 123*50a3056aSZelalem Aweke trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) 124*50a3056aSZelalem Aweke { 125*50a3056aSZelalem Aweke switch (fid) { 126*50a3056aSZelalem Aweke case RMI_RMM_REQ_VERSION: 127*50a3056aSZelalem Aweke return trp_ret_rmi_version(); 128*50a3056aSZelalem Aweke case RMI_RMM_GRANULE_DELEGATE: 129*50a3056aSZelalem Aweke return trp_asc_mark_realm(x1); 130*50a3056aSZelalem Aweke case RMI_RMM_GRANULE_UNDELEGATE: 131*50a3056aSZelalem Aweke return trp_asc_mark_nonsecure(x1); 132*50a3056aSZelalem Aweke default: 133*50a3056aSZelalem Aweke ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); 134*50a3056aSZelalem Aweke } 135*50a3056aSZelalem Aweke return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); 136*50a3056aSZelalem Aweke } 137