xref: /rk3399_ARM-atf/services/std_svc/rmmd/trp/trp_main.c (revision ade6000ff0b3aa41d581d5738ce42f5ea4d3b77d)
150a3056aSZelalem Aweke /*
2319fb084SSoby 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 #include <common/debug.h>
850a3056aSZelalem Aweke #include <plat/common/platform.h>
91d0ca40eSJavier Almansa Sobrino #include <services/rmm_core_manifest.h>
10319fb084SSoby Mathew #include <services/rmmd_svc.h>
1150a3056aSZelalem Aweke #include <services/trp/platform_trp.h>
121d0ca40eSJavier Almansa Sobrino #include <trp_helpers.h>
131d0ca40eSJavier Almansa Sobrino #include "trp_private.h"
1450a3056aSZelalem Aweke 
1550a3056aSZelalem Aweke #include <platform_def.h>
1650a3056aSZelalem Aweke 
178c980a4aSJavier Almansa Sobrino /* Parameters received from the previous image */
188c980a4aSJavier Almansa Sobrino static unsigned int trp_boot_abi_version;
198c980a4aSJavier Almansa Sobrino static uintptr_t trp_shared_region_start;
208c980a4aSJavier Almansa Sobrino 
211d0ca40eSJavier Almansa Sobrino /* Parameters received from boot manifest */
221d0ca40eSJavier Almansa Sobrino uint32_t trp_boot_manifest_version;
238c980a4aSJavier Almansa Sobrino 
2450a3056aSZelalem Aweke /*******************************************************************************
2550a3056aSZelalem Aweke  * Setup function for TRP.
2650a3056aSZelalem Aweke  ******************************************************************************/
278c980a4aSJavier Almansa Sobrino void trp_setup(uint64_t x0,
288c980a4aSJavier Almansa Sobrino 	       uint64_t x1,
298c980a4aSJavier Almansa Sobrino 	       uint64_t x2,
308c980a4aSJavier Almansa Sobrino 	       uint64_t x3)
3150a3056aSZelalem Aweke {
328c980a4aSJavier Almansa Sobrino 	/*
33b96253dbSAlexeiFedorov 	 * Validate boot parameters
348c980a4aSJavier Almansa Sobrino 	 *
35b96253dbSAlexeiFedorov 	 * According to the Boot Interface ABI v.0.1,
36b96253dbSAlexeiFedorov 	 * the parameters received from EL3 are:
37b96253dbSAlexeiFedorov 	 * x0: CPUID (verified earlier, so not used)
388c980a4aSJavier Almansa Sobrino 	 * x1: Boot Interface version
398c980a4aSJavier Almansa Sobrino 	 * x2: PLATFORM_CORE_COUNT
408c980a4aSJavier Almansa Sobrino 	 * x3: Pointer to the shared memory area.
418c980a4aSJavier Almansa Sobrino 	 */
428c980a4aSJavier Almansa Sobrino 
438c980a4aSJavier Almansa Sobrino 	(void)x0;
448c980a4aSJavier Almansa Sobrino 
458c980a4aSJavier Almansa Sobrino 	if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
468c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
478c980a4aSJavier Almansa Sobrino 	}
488c980a4aSJavier Almansa Sobrino 
498c980a4aSJavier Almansa Sobrino 	if ((void *)x3 == NULL) {
508c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
518c980a4aSJavier Almansa Sobrino 	}
528c980a4aSJavier Almansa Sobrino 
538c980a4aSJavier Almansa Sobrino 	if (x2 > TRP_PLATFORM_CORE_COUNT) {
548c980a4aSJavier Almansa Sobrino 		trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
558c980a4aSJavier Almansa Sobrino 	}
568c980a4aSJavier Almansa Sobrino 
578c980a4aSJavier Almansa Sobrino 	trp_boot_abi_version = x1;
588c980a4aSJavier Almansa Sobrino 	trp_shared_region_start = x3;
598c980a4aSJavier Almansa Sobrino 	flush_dcache_range((uintptr_t)&trp_boot_abi_version,
608c980a4aSJavier Almansa Sobrino 			   sizeof(trp_boot_abi_version));
618c980a4aSJavier Almansa Sobrino 	flush_dcache_range((uintptr_t)&trp_shared_region_start,
628c980a4aSJavier Almansa Sobrino 			   sizeof(trp_shared_region_start));
638c980a4aSJavier Almansa Sobrino 
6450a3056aSZelalem Aweke 	/* Perform early platform-specific setup */
65a97bfa5fSAlexeiFedorov 	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
6650a3056aSZelalem Aweke }
6750a3056aSZelalem Aweke 
68dc0ca64eSJavier Almansa Sobrino int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
69dc0ca64eSJavier Almansa Sobrino 			       uint64_t x2, uint64_t x3)
70dc0ca64eSJavier Almansa Sobrino {
71dc0ca64eSJavier Almansa Sobrino 	/*
72dc0ca64eSJavier Almansa Sobrino 	 * Validate boot parameters for warm boot
73dc0ca64eSJavier Almansa Sobrino 	 *
74dc0ca64eSJavier Almansa Sobrino 	 * According to the Boot Interface ABI v.0.1, the parameters
75dc0ca64eSJavier Almansa Sobrino 	 * received from EL3 during warm boot are:
76dc0ca64eSJavier Almansa Sobrino 	 *
77dc0ca64eSJavier Almansa Sobrino 	 * x0: CPUID (verified earlier so not used here)
78dc0ca64eSJavier Almansa Sobrino 	 * [x1:x3]: RES0
79dc0ca64eSJavier Almansa Sobrino 	 */
80dc0ca64eSJavier Almansa Sobrino 
81dc0ca64eSJavier Almansa Sobrino 	(void)x0;
82dc0ca64eSJavier Almansa Sobrino 
83dc0ca64eSJavier Almansa Sobrino 	return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN;
84dc0ca64eSJavier Almansa Sobrino }
85dc0ca64eSJavier Almansa Sobrino 
8650a3056aSZelalem Aweke /* Main function for TRP */
8750a3056aSZelalem Aweke void trp_main(void)
8850a3056aSZelalem Aweke {
8950a3056aSZelalem Aweke 	NOTICE("TRP: %s\n", version_string);
9050a3056aSZelalem Aweke 	NOTICE("TRP: %s\n", build_message);
918c980a4aSJavier Almansa Sobrino 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
928c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
931d0ca40eSJavier Almansa Sobrino 	NOTICE("TRP: Boot Manifest Version: v.%u.%u\n",
941d0ca40eSJavier Almansa Sobrino 		RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
951d0ca40eSJavier Almansa Sobrino 		RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
9650a3056aSZelalem Aweke 	INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE);
97b96253dbSAlexeiFedorov 	INFO("TRP: Shared region base address: 0x%lx\n",
988c980a4aSJavier Almansa Sobrino 			(unsigned long)trp_shared_region_start);
99b96253dbSAlexeiFedorov 	INFO("TRP: Total size: 0x%lx bytes\n",
100b96253dbSAlexeiFedorov 			(unsigned long)(RMM_END - RMM_BASE));
1018c980a4aSJavier Almansa Sobrino 	INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
1028c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
1038c980a4aSJavier Almansa Sobrino 		TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
10450a3056aSZelalem Aweke }
10550a3056aSZelalem Aweke 
10650a3056aSZelalem Aweke /*******************************************************************************
10750a3056aSZelalem Aweke  * Returning RMI version back to Normal World
10850a3056aSZelalem Aweke  ******************************************************************************/
109*ade6000fSShruti Gupta static void trp_ret_rmi_version(unsigned long long rmi_version,
110*ade6000fSShruti Gupta 				struct trp_smc_result *smc_ret)
11150a3056aSZelalem Aweke {
112*ade6000fSShruti Gupta 	if (rmi_version != RMI_ABI_VERSION) {
113*ade6000fSShruti Gupta 		smc_ret->x[0] = RMI_ERROR_INPUT;
114*ade6000fSShruti Gupta 	} else {
115*ade6000fSShruti Gupta 		smc_ret->x[0] = RMI_SUCCESS;
116*ade6000fSShruti Gupta 	}
11750a3056aSZelalem Aweke 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
11850a3056aSZelalem Aweke 					  RMI_ABI_VERSION_MINOR);
119*ade6000fSShruti Gupta 	smc_ret->x[1] = RMI_ABI_VERSION;
120*ade6000fSShruti Gupta 	smc_ret->x[2] = RMI_ABI_VERSION;
12150a3056aSZelalem Aweke }
12250a3056aSZelalem Aweke 
12350a3056aSZelalem Aweke /*******************************************************************************
12450a3056aSZelalem Aweke  * Transitioning granule of NON-SECURE type to REALM type
12550a3056aSZelalem Aweke  ******************************************************************************/
126b96253dbSAlexeiFedorov static void trp_asc_mark_realm(unsigned long long x1,
127b96253dbSAlexeiFedorov 				struct trp_smc_result *smc_ret)
12850a3056aSZelalem Aweke {
12950a3056aSZelalem Aweke 	VERBOSE("Delegating granule 0x%llx\n", x1);
130b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
131b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
13250a3056aSZelalem Aweke 
133b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
13450a3056aSZelalem Aweke 		ERROR("Granule transition from NON-SECURE type to REALM type "
135b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
13650a3056aSZelalem Aweke 	}
13750a3056aSZelalem Aweke }
13850a3056aSZelalem Aweke 
13950a3056aSZelalem Aweke /*******************************************************************************
14050a3056aSZelalem Aweke  * Transitioning granule of REALM type to NON-SECURE type
14150a3056aSZelalem Aweke  ******************************************************************************/
142b96253dbSAlexeiFedorov static void trp_asc_mark_nonsecure(unsigned long long x1,
143b96253dbSAlexeiFedorov 				   struct trp_smc_result *smc_ret)
14450a3056aSZelalem Aweke {
14550a3056aSZelalem Aweke 	VERBOSE("Undelegating granule 0x%llx\n", x1);
146b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
147b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
14850a3056aSZelalem Aweke 
149b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
15050a3056aSZelalem Aweke 		ERROR("Granule transition from REALM type to NON-SECURE type "
151b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
15250a3056aSZelalem Aweke 	}
15350a3056aSZelalem Aweke }
15450a3056aSZelalem Aweke 
15550a3056aSZelalem Aweke /*******************************************************************************
15650a3056aSZelalem Aweke  * Main RMI SMC handler function
15750a3056aSZelalem Aweke  ******************************************************************************/
158b96253dbSAlexeiFedorov void trp_rmi_handler(unsigned long fid,
159b96253dbSAlexeiFedorov 		     unsigned long long x1, unsigned long long x2,
160b96253dbSAlexeiFedorov 		     unsigned long long x3, unsigned long long x4,
161b96253dbSAlexeiFedorov 		     unsigned long long x5, unsigned long long x6,
162b96253dbSAlexeiFedorov 		     struct trp_smc_result *smc_ret)
16350a3056aSZelalem Aweke {
164b96253dbSAlexeiFedorov 	/* Not used in the current implementation */
165b96253dbSAlexeiFedorov 	(void)x2;
166b96253dbSAlexeiFedorov 	(void)x3;
167b96253dbSAlexeiFedorov 	(void)x4;
168b96253dbSAlexeiFedorov 	(void)x5;
169b96253dbSAlexeiFedorov 	(void)x6;
170b96253dbSAlexeiFedorov 
17150a3056aSZelalem Aweke 	switch (fid) {
17250a3056aSZelalem Aweke 	case RMI_RMM_REQ_VERSION:
173*ade6000fSShruti Gupta 		trp_ret_rmi_version(x1, smc_ret);
174b96253dbSAlexeiFedorov 		break;
17550a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_DELEGATE:
176b96253dbSAlexeiFedorov 		trp_asc_mark_realm(x1, smc_ret);
177b96253dbSAlexeiFedorov 		break;
17850a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_UNDELEGATE:
179b96253dbSAlexeiFedorov 		trp_asc_mark_nonsecure(x1, smc_ret);
180b96253dbSAlexeiFedorov 		break;
18150a3056aSZelalem Aweke 	default:
182b96253dbSAlexeiFedorov 		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
183b96253dbSAlexeiFedorov 		smc_ret->x[0] = SMC_UNK;
18450a3056aSZelalem Aweke 	}
18550a3056aSZelalem Aweke }
186