xref: /rk3399_ARM-atf/services/std_svc/rmmd/trp/trp_main.c (revision 758ccb802d4f2a5fe55ec936a21ad4ae8cbd7b4f)
150a3056aSZelalem Aweke /*
2*758ccb80SChris Kay  * Copyright (c) 2021-2024, Arm Limited and Contributors. All rights reserved.
350a3056aSZelalem Aweke  *
450a3056aSZelalem Aweke  * SPDX-License-Identifier: BSD-3-Clause
550a3056aSZelalem Aweke  */
650a3056aSZelalem Aweke 
7*758ccb80SChris Kay #include <common/build_message.h>
850a3056aSZelalem Aweke #include <common/debug.h>
950a3056aSZelalem Aweke #include <plat/common/platform.h>
101d0ca40eSJavier Almansa Sobrino #include <services/rmm_core_manifest.h>
11319fb084SSoby Mathew #include <services/rmmd_svc.h>
1250a3056aSZelalem Aweke #include <services/trp/platform_trp.h>
131d0ca40eSJavier Almansa Sobrino #include <trp_helpers.h>
141d0ca40eSJavier Almansa Sobrino #include "trp_private.h"
1550a3056aSZelalem Aweke 
1650a3056aSZelalem Aweke #include <platform_def.h>
1750a3056aSZelalem Aweke 
188c980a4aSJavier Almansa Sobrino /* Parameters received from the previous image */
198c980a4aSJavier Almansa Sobrino static unsigned int trp_boot_abi_version;
208c980a4aSJavier Almansa Sobrino static uintptr_t trp_shared_region_start;
218c980a4aSJavier Almansa Sobrino 
221d0ca40eSJavier Almansa Sobrino /* Parameters received from boot manifest */
231d0ca40eSJavier Almansa Sobrino uint32_t trp_boot_manifest_version;
248c980a4aSJavier Almansa Sobrino 
2550a3056aSZelalem Aweke /*******************************************************************************
2650a3056aSZelalem Aweke  * Setup function for TRP.
2750a3056aSZelalem Aweke  ******************************************************************************/
288c980a4aSJavier Almansa Sobrino void trp_setup(uint64_t x0,
298c980a4aSJavier Almansa Sobrino 	       uint64_t x1,
308c980a4aSJavier Almansa Sobrino 	       uint64_t x2,
318c980a4aSJavier Almansa Sobrino 	       uint64_t x3)
3250a3056aSZelalem Aweke {
338c980a4aSJavier Almansa Sobrino 	/*
34b96253dbSAlexeiFedorov 	 * Validate boot parameters
358c980a4aSJavier Almansa Sobrino 	 *
36b96253dbSAlexeiFedorov 	 * According to the Boot Interface ABI v.0.1,
37b96253dbSAlexeiFedorov 	 * the parameters received from EL3 are:
38b96253dbSAlexeiFedorov 	 * x0: CPUID (verified earlier, so not used)
398c980a4aSJavier Almansa Sobrino 	 * x1: Boot Interface version
408c980a4aSJavier Almansa Sobrino 	 * x2: PLATFORM_CORE_COUNT
418c980a4aSJavier Almansa Sobrino 	 * x3: Pointer to the shared memory area.
428c980a4aSJavier Almansa Sobrino 	 */
438c980a4aSJavier Almansa Sobrino 
448c980a4aSJavier Almansa Sobrino 	(void)x0;
458c980a4aSJavier Almansa Sobrino 
468c980a4aSJavier Almansa Sobrino 	if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
478c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
488c980a4aSJavier Almansa Sobrino 	}
498c980a4aSJavier Almansa Sobrino 
508c980a4aSJavier Almansa Sobrino 	if ((void *)x3 == NULL) {
518c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
528c980a4aSJavier Almansa Sobrino 	}
538c980a4aSJavier Almansa Sobrino 
548c980a4aSJavier Almansa Sobrino 	if (x2 > TRP_PLATFORM_CORE_COUNT) {
558c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
568c980a4aSJavier Almansa Sobrino 	}
578c980a4aSJavier Almansa Sobrino 
588c980a4aSJavier Almansa Sobrino 	trp_boot_abi_version = x1;
598c980a4aSJavier Almansa Sobrino 	trp_shared_region_start = x3;
608c980a4aSJavier Almansa Sobrino 	flush_dcache_range((uintptr_t)&trp_boot_abi_version,
618c980a4aSJavier Almansa Sobrino 			   sizeof(trp_boot_abi_version));
628c980a4aSJavier Almansa Sobrino 	flush_dcache_range((uintptr_t)&trp_shared_region_start,
638c980a4aSJavier Almansa Sobrino 			   sizeof(trp_shared_region_start));
648c980a4aSJavier Almansa Sobrino 
6550a3056aSZelalem Aweke 	/* Perform early platform-specific setup */
66a97bfa5fSAlexeiFedorov 	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
6750a3056aSZelalem Aweke }
6850a3056aSZelalem Aweke 
69dc0ca64eSJavier Almansa Sobrino int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
70dc0ca64eSJavier Almansa Sobrino 			       uint64_t x2, uint64_t x3)
71dc0ca64eSJavier Almansa Sobrino {
72dc0ca64eSJavier Almansa Sobrino 	/*
73dc0ca64eSJavier Almansa Sobrino 	 * Validate boot parameters for warm boot
74dc0ca64eSJavier Almansa Sobrino 	 *
75dc0ca64eSJavier Almansa Sobrino 	 * According to the Boot Interface ABI v.0.1, the parameters
76dc0ca64eSJavier Almansa Sobrino 	 * received from EL3 during warm boot are:
77dc0ca64eSJavier Almansa Sobrino 	 *
78dc0ca64eSJavier Almansa Sobrino 	 * x0: CPUID (verified earlier so not used here)
79dc0ca64eSJavier Almansa Sobrino 	 * [x1:x3]: RES0
80dc0ca64eSJavier Almansa Sobrino 	 */
81dc0ca64eSJavier Almansa Sobrino 
82dc0ca64eSJavier Almansa Sobrino 	(void)x0;
83dc0ca64eSJavier Almansa Sobrino 
84dc0ca64eSJavier Almansa Sobrino 	return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN;
85dc0ca64eSJavier Almansa Sobrino }
86dc0ca64eSJavier Almansa Sobrino 
8750a3056aSZelalem Aweke /* Main function for TRP */
8850a3056aSZelalem Aweke void trp_main(void)
8950a3056aSZelalem Aweke {
90*758ccb80SChris Kay 	NOTICE("TRP: %s\n", build_version_string);
9150a3056aSZelalem Aweke 	NOTICE("TRP: %s\n", build_message);
928c980a4aSJavier Almansa Sobrino 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
938c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
941d0ca40eSJavier Almansa Sobrino 	NOTICE("TRP: Boot Manifest Version: v.%u.%u\n",
951d0ca40eSJavier Almansa Sobrino 		RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
961d0ca40eSJavier Almansa Sobrino 		RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
9750a3056aSZelalem Aweke 	INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE);
98b96253dbSAlexeiFedorov 	INFO("TRP: Shared region base address: 0x%lx\n",
998c980a4aSJavier Almansa Sobrino 			(unsigned long)trp_shared_region_start);
100b96253dbSAlexeiFedorov 	INFO("TRP: Total size: 0x%lx bytes\n",
101b96253dbSAlexeiFedorov 			(unsigned long)(RMM_END - RMM_BASE));
1028c980a4aSJavier Almansa Sobrino 	INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
1038c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
1048c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
10550a3056aSZelalem Aweke }
10650a3056aSZelalem Aweke 
10750a3056aSZelalem Aweke /*******************************************************************************
10850a3056aSZelalem Aweke  * Returning RMI version back to Normal World
10950a3056aSZelalem Aweke  ******************************************************************************/
110ade6000fSShruti Gupta static void trp_ret_rmi_version(unsigned long long rmi_version,
111ade6000fSShruti Gupta 				struct trp_smc_result *smc_ret)
11250a3056aSZelalem Aweke {
113ade6000fSShruti Gupta 	if (rmi_version != RMI_ABI_VERSION) {
114ade6000fSShruti Gupta 		smc_ret->x[0] = RMI_ERROR_INPUT;
115ade6000fSShruti Gupta 	} else {
116ade6000fSShruti Gupta 		smc_ret->x[0] = RMI_SUCCESS;
117ade6000fSShruti Gupta 	}
11850a3056aSZelalem Aweke 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
11950a3056aSZelalem Aweke 					  RMI_ABI_VERSION_MINOR);
120ade6000fSShruti Gupta 	smc_ret->x[1] = RMI_ABI_VERSION;
121ade6000fSShruti Gupta 	smc_ret->x[2] = RMI_ABI_VERSION;
12250a3056aSZelalem Aweke }
12350a3056aSZelalem Aweke 
12450a3056aSZelalem Aweke /*******************************************************************************
12550a3056aSZelalem Aweke  * Transitioning granule of NON-SECURE type to REALM type
12650a3056aSZelalem Aweke  ******************************************************************************/
127b96253dbSAlexeiFedorov static void trp_asc_mark_realm(unsigned long long x1,
128b96253dbSAlexeiFedorov 				struct trp_smc_result *smc_ret)
12950a3056aSZelalem Aweke {
13050a3056aSZelalem Aweke 	VERBOSE("Delegating granule 0x%llx\n", x1);
131b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
132b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
13350a3056aSZelalem Aweke 
134b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
13550a3056aSZelalem Aweke 		ERROR("Granule transition from NON-SECURE type to REALM type "
136b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
13750a3056aSZelalem Aweke 	}
13850a3056aSZelalem Aweke }
13950a3056aSZelalem Aweke 
14050a3056aSZelalem Aweke /*******************************************************************************
14150a3056aSZelalem Aweke  * Transitioning granule of REALM type to NON-SECURE type
14250a3056aSZelalem Aweke  ******************************************************************************/
143b96253dbSAlexeiFedorov static void trp_asc_mark_nonsecure(unsigned long long x1,
144b96253dbSAlexeiFedorov 				   struct trp_smc_result *smc_ret)
14550a3056aSZelalem Aweke {
14650a3056aSZelalem Aweke 	VERBOSE("Undelegating granule 0x%llx\n", x1);
147b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
148b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
14950a3056aSZelalem Aweke 
150b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
15150a3056aSZelalem Aweke 		ERROR("Granule transition from REALM type to NON-SECURE type "
152b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
15350a3056aSZelalem Aweke 	}
15450a3056aSZelalem Aweke }
15550a3056aSZelalem Aweke 
15650a3056aSZelalem Aweke /*******************************************************************************
15750a3056aSZelalem Aweke  * Main RMI SMC handler function
15850a3056aSZelalem Aweke  ******************************************************************************/
159b96253dbSAlexeiFedorov void trp_rmi_handler(unsigned long fid,
160b96253dbSAlexeiFedorov 		     unsigned long long x1, unsigned long long x2,
161b96253dbSAlexeiFedorov 		     unsigned long long x3, unsigned long long x4,
162b96253dbSAlexeiFedorov 		     unsigned long long x5, unsigned long long x6,
163b96253dbSAlexeiFedorov 		     struct trp_smc_result *smc_ret)
16450a3056aSZelalem Aweke {
165b96253dbSAlexeiFedorov 	/* Not used in the current implementation */
166b96253dbSAlexeiFedorov 	(void)x2;
167b96253dbSAlexeiFedorov 	(void)x3;
168b96253dbSAlexeiFedorov 	(void)x4;
169b96253dbSAlexeiFedorov 	(void)x5;
170b96253dbSAlexeiFedorov 	(void)x6;
171b96253dbSAlexeiFedorov 
17250a3056aSZelalem Aweke 	switch (fid) {
17350a3056aSZelalem Aweke 	case RMI_RMM_REQ_VERSION:
174ade6000fSShruti Gupta 		trp_ret_rmi_version(x1, smc_ret);
175b96253dbSAlexeiFedorov 		break;
17650a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_DELEGATE:
177b96253dbSAlexeiFedorov 		trp_asc_mark_realm(x1, smc_ret);
178b96253dbSAlexeiFedorov 		break;
17950a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_UNDELEGATE:
180b96253dbSAlexeiFedorov 		trp_asc_mark_nonsecure(x1, smc_ret);
181b96253dbSAlexeiFedorov 		break;
18250a3056aSZelalem Aweke 	default:
183b96253dbSAlexeiFedorov 		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
184b96253dbSAlexeiFedorov 		smc_ret->x[0] = SMC_UNK;
18550a3056aSZelalem Aweke 	}
18650a3056aSZelalem Aweke }
187