xref: /rk3399_ARM-atf/services/std_svc/rmmd/trp/trp_main.c (revision a97bfa5ff18b2682e3b9c528cbd5fb16ceec3393)
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 */
65*a97bfa5fSAlexeiFedorov 	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  ******************************************************************************/
109b96253dbSAlexeiFedorov static void trp_ret_rmi_version(struct trp_smc_result *smc_ret)
11050a3056aSZelalem Aweke {
11150a3056aSZelalem Aweke 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
11250a3056aSZelalem Aweke 					  RMI_ABI_VERSION_MINOR);
113b96253dbSAlexeiFedorov 	smc_ret->x[0] = RMI_ABI_VERSION;
11450a3056aSZelalem Aweke }
11550a3056aSZelalem Aweke 
11650a3056aSZelalem Aweke /*******************************************************************************
11750a3056aSZelalem Aweke  * Transitioning granule of NON-SECURE type to REALM type
11850a3056aSZelalem Aweke  ******************************************************************************/
119b96253dbSAlexeiFedorov static void trp_asc_mark_realm(unsigned long long x1,
120b96253dbSAlexeiFedorov 				struct trp_smc_result *smc_ret)
12150a3056aSZelalem Aweke {
12250a3056aSZelalem Aweke 	VERBOSE("Delegating granule 0x%llx\n", x1);
123b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
124b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
12550a3056aSZelalem Aweke 
126b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
12750a3056aSZelalem Aweke 		ERROR("Granule transition from NON-SECURE type to REALM type "
128b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
12950a3056aSZelalem Aweke 	}
13050a3056aSZelalem Aweke }
13150a3056aSZelalem Aweke 
13250a3056aSZelalem Aweke /*******************************************************************************
13350a3056aSZelalem Aweke  * Transitioning granule of REALM type to NON-SECURE type
13450a3056aSZelalem Aweke  ******************************************************************************/
135b96253dbSAlexeiFedorov static void trp_asc_mark_nonsecure(unsigned long long x1,
136b96253dbSAlexeiFedorov 				   struct trp_smc_result *smc_ret)
13750a3056aSZelalem Aweke {
13850a3056aSZelalem Aweke 	VERBOSE("Undelegating granule 0x%llx\n", x1);
139b96253dbSAlexeiFedorov 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
140b96253dbSAlexeiFedorov 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
14150a3056aSZelalem Aweke 
142b96253dbSAlexeiFedorov 	if (smc_ret->x[0] != 0ULL) {
14350a3056aSZelalem Aweke 		ERROR("Granule transition from REALM type to NON-SECURE type "
144b96253dbSAlexeiFedorov 			"failed 0x%llx\n", smc_ret->x[0]);
14550a3056aSZelalem Aweke 	}
14650a3056aSZelalem Aweke }
14750a3056aSZelalem Aweke 
14850a3056aSZelalem Aweke /*******************************************************************************
14950a3056aSZelalem Aweke  * Main RMI SMC handler function
15050a3056aSZelalem Aweke  ******************************************************************************/
151b96253dbSAlexeiFedorov void trp_rmi_handler(unsigned long fid,
152b96253dbSAlexeiFedorov 		     unsigned long long x1, unsigned long long x2,
153b96253dbSAlexeiFedorov 		     unsigned long long x3, unsigned long long x4,
154b96253dbSAlexeiFedorov 		     unsigned long long x5, unsigned long long x6,
155b96253dbSAlexeiFedorov 		     struct trp_smc_result *smc_ret)
15650a3056aSZelalem Aweke {
157b96253dbSAlexeiFedorov 	/* Not used in the current implementation */
158b96253dbSAlexeiFedorov 	(void)x2;
159b96253dbSAlexeiFedorov 	(void)x3;
160b96253dbSAlexeiFedorov 	(void)x4;
161b96253dbSAlexeiFedorov 	(void)x5;
162b96253dbSAlexeiFedorov 	(void)x6;
163b96253dbSAlexeiFedorov 
16450a3056aSZelalem Aweke 	switch (fid) {
16550a3056aSZelalem Aweke 	case RMI_RMM_REQ_VERSION:
166b96253dbSAlexeiFedorov 		trp_ret_rmi_version(smc_ret);
167b96253dbSAlexeiFedorov 		break;
16850a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_DELEGATE:
169b96253dbSAlexeiFedorov 		trp_asc_mark_realm(x1, smc_ret);
170b96253dbSAlexeiFedorov 		break;
17150a3056aSZelalem Aweke 	case RMI_RMM_GRANULE_UNDELEGATE:
172b96253dbSAlexeiFedorov 		trp_asc_mark_nonsecure(x1, smc_ret);
173b96253dbSAlexeiFedorov 		break;
17450a3056aSZelalem Aweke 	default:
175b96253dbSAlexeiFedorov 		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
176b96253dbSAlexeiFedorov 		smc_ret->x[0] = SMC_UNK;
17750a3056aSZelalem Aweke 	}
17850a3056aSZelalem Aweke }
179