150a3056aSZelalem Aweke /* 2*319fb084SSoby Mathew * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved. 350a3056aSZelalem Aweke * 450a3056aSZelalem Aweke * SPDX-License-Identifier: BSD-3-Clause 550a3056aSZelalem Aweke */ 650a3056aSZelalem Aweke 750a3056aSZelalem Aweke 850a3056aSZelalem Aweke #include <common/debug.h> 950a3056aSZelalem Aweke #include <plat/common/platform.h> 10*319fb084SSoby Mathew #include <services/rmmd_svc.h> 1150a3056aSZelalem Aweke #include <services/trp/platform_trp.h> 1250a3056aSZelalem Aweke 1350a3056aSZelalem Aweke #include <platform_def.h> 1450a3056aSZelalem Aweke #include "trp_private.h" 1550a3056aSZelalem Aweke 1650a3056aSZelalem Aweke /******************************************************************************* 1750a3056aSZelalem Aweke * Per cpu data structure to populate parameters for an SMC in C code and use 1850a3056aSZelalem Aweke * a pointer to this structure in assembler code to populate x0-x7 1950a3056aSZelalem Aweke ******************************************************************************/ 2050a3056aSZelalem Aweke static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT]; 2150a3056aSZelalem Aweke 2250a3056aSZelalem Aweke /******************************************************************************* 2350a3056aSZelalem Aweke * Set the arguments for SMC call 2450a3056aSZelalem Aweke ******************************************************************************/ 2550a3056aSZelalem Aweke static trp_args_t *set_smc_args(uint64_t arg0, 2650a3056aSZelalem Aweke uint64_t arg1, 2750a3056aSZelalem Aweke uint64_t arg2, 2850a3056aSZelalem Aweke uint64_t arg3, 2950a3056aSZelalem Aweke uint64_t arg4, 3050a3056aSZelalem Aweke uint64_t arg5, 3150a3056aSZelalem Aweke uint64_t arg6, 3250a3056aSZelalem Aweke uint64_t arg7) 3350a3056aSZelalem Aweke { 3450a3056aSZelalem Aweke uint32_t linear_id; 3550a3056aSZelalem Aweke trp_args_t *pcpu_smc_args; 3650a3056aSZelalem Aweke 3750a3056aSZelalem Aweke /* 3850a3056aSZelalem Aweke * Return to Secure Monitor by raising an SMC. The results of the 3950a3056aSZelalem Aweke * service are passed as an arguments to the SMC 4050a3056aSZelalem Aweke */ 4150a3056aSZelalem Aweke linear_id = plat_my_core_pos(); 4250a3056aSZelalem Aweke pcpu_smc_args = &trp_smc_args[linear_id]; 4350a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0); 4450a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1); 4550a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2); 4650a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3); 4750a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4); 4850a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5); 4950a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6); 5050a3056aSZelalem Aweke write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7); 5150a3056aSZelalem Aweke 5250a3056aSZelalem Aweke return pcpu_smc_args; 5350a3056aSZelalem Aweke } 5450a3056aSZelalem Aweke 5550a3056aSZelalem Aweke /******************************************************************************* 5650a3056aSZelalem Aweke * Setup function for TRP. 5750a3056aSZelalem Aweke ******************************************************************************/ 5850a3056aSZelalem Aweke void trp_setup(void) 5950a3056aSZelalem Aweke { 6050a3056aSZelalem Aweke /* Perform early platform-specific setup */ 6150a3056aSZelalem Aweke trp_early_platform_setup(); 6250a3056aSZelalem Aweke } 6350a3056aSZelalem Aweke 6450a3056aSZelalem Aweke /* Main function for TRP */ 6550a3056aSZelalem Aweke void trp_main(void) 6650a3056aSZelalem Aweke { 6750a3056aSZelalem Aweke NOTICE("TRP: %s\n", version_string); 6850a3056aSZelalem Aweke NOTICE("TRP: %s\n", build_message); 6950a3056aSZelalem Aweke INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE); 7050a3056aSZelalem Aweke INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END 7150a3056aSZelalem Aweke - RMM_BASE)); 7250a3056aSZelalem Aweke } 7350a3056aSZelalem Aweke 7450a3056aSZelalem Aweke /******************************************************************************* 7550a3056aSZelalem Aweke * Returning RMI version back to Normal World 7650a3056aSZelalem Aweke ******************************************************************************/ 7750a3056aSZelalem Aweke static trp_args_t *trp_ret_rmi_version(void) 7850a3056aSZelalem Aweke { 7950a3056aSZelalem Aweke VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR, 8050a3056aSZelalem Aweke RMI_ABI_VERSION_MINOR); 81*319fb084SSoby Mathew return set_smc_args(RMMD_RMI_REQ_COMPLETE, RMI_ABI_VERSION, 8250a3056aSZelalem Aweke 0, 0, 0, 0, 0, 0); 8350a3056aSZelalem Aweke } 8450a3056aSZelalem Aweke 8550a3056aSZelalem Aweke /******************************************************************************* 8650a3056aSZelalem Aweke * Transitioning granule of NON-SECURE type to REALM type 8750a3056aSZelalem Aweke ******************************************************************************/ 8850a3056aSZelalem Aweke static trp_args_t *trp_asc_mark_realm(unsigned long long x1) 8950a3056aSZelalem Aweke { 9050a3056aSZelalem Aweke unsigned long long ret; 9150a3056aSZelalem Aweke 9250a3056aSZelalem Aweke VERBOSE("Delegating granule 0x%llx\n", x1); 93*319fb084SSoby Mathew ret = trp_smc(set_smc_args(RMMD_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0)); 9450a3056aSZelalem Aweke 9550a3056aSZelalem Aweke if (ret != 0ULL) { 9650a3056aSZelalem Aweke ERROR("Granule transition from NON-SECURE type to REALM type " 9750a3056aSZelalem Aweke "failed 0x%llx\n", ret); 9850a3056aSZelalem Aweke } 99*319fb084SSoby Mathew return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 10050a3056aSZelalem Aweke } 10150a3056aSZelalem Aweke 10250a3056aSZelalem Aweke /******************************************************************************* 10350a3056aSZelalem Aweke * Transitioning granule of REALM type to NON-SECURE type 10450a3056aSZelalem Aweke ******************************************************************************/ 10550a3056aSZelalem Aweke static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1) 10650a3056aSZelalem Aweke { 10750a3056aSZelalem Aweke unsigned long long ret; 10850a3056aSZelalem Aweke 10950a3056aSZelalem Aweke VERBOSE("Undelegating granule 0x%llx\n", x1); 110*319fb084SSoby Mathew ret = trp_smc(set_smc_args(RMMD_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0)); 11150a3056aSZelalem Aweke 11250a3056aSZelalem Aweke if (ret != 0ULL) { 11350a3056aSZelalem Aweke ERROR("Granule transition from REALM type to NON-SECURE type " 11450a3056aSZelalem Aweke "failed 0x%llx\n", ret); 11550a3056aSZelalem Aweke } 116*319fb084SSoby Mathew return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0); 11750a3056aSZelalem Aweke } 11850a3056aSZelalem Aweke 11950a3056aSZelalem Aweke /******************************************************************************* 12050a3056aSZelalem Aweke * Main RMI SMC handler function 12150a3056aSZelalem Aweke ******************************************************************************/ 12250a3056aSZelalem Aweke trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1) 12350a3056aSZelalem Aweke { 12450a3056aSZelalem Aweke switch (fid) { 12550a3056aSZelalem Aweke case RMI_RMM_REQ_VERSION: 12650a3056aSZelalem Aweke return trp_ret_rmi_version(); 12750a3056aSZelalem Aweke case RMI_RMM_GRANULE_DELEGATE: 12850a3056aSZelalem Aweke return trp_asc_mark_realm(x1); 12950a3056aSZelalem Aweke case RMI_RMM_GRANULE_UNDELEGATE: 13050a3056aSZelalem Aweke return trp_asc_mark_nonsecure(x1); 13150a3056aSZelalem Aweke default: 13250a3056aSZelalem Aweke ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid); 13350a3056aSZelalem Aweke } 13450a3056aSZelalem Aweke return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0); 13550a3056aSZelalem Aweke } 136