xref: /arm-trusted-firmware/services/std_svc/rmmd/trp/trp_main.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <common/debug.h>
8*91f16700Schasinglulu #include <plat/common/platform.h>
9*91f16700Schasinglulu #include <services/rmm_core_manifest.h>
10*91f16700Schasinglulu #include <services/rmmd_svc.h>
11*91f16700Schasinglulu #include <services/trp/platform_trp.h>
12*91f16700Schasinglulu #include <trp_helpers.h>
13*91f16700Schasinglulu #include "trp_private.h"
14*91f16700Schasinglulu 
15*91f16700Schasinglulu #include <platform_def.h>
16*91f16700Schasinglulu 
17*91f16700Schasinglulu /* Parameters received from the previous image */
18*91f16700Schasinglulu static unsigned int trp_boot_abi_version;
19*91f16700Schasinglulu static uintptr_t trp_shared_region_start;
20*91f16700Schasinglulu 
21*91f16700Schasinglulu /* Parameters received from boot manifest */
22*91f16700Schasinglulu uint32_t trp_boot_manifest_version;
23*91f16700Schasinglulu 
24*91f16700Schasinglulu /*******************************************************************************
25*91f16700Schasinglulu  * Setup function for TRP.
26*91f16700Schasinglulu  ******************************************************************************/
27*91f16700Schasinglulu void trp_setup(uint64_t x0,
28*91f16700Schasinglulu 	       uint64_t x1,
29*91f16700Schasinglulu 	       uint64_t x2,
30*91f16700Schasinglulu 	       uint64_t x3)
31*91f16700Schasinglulu {
32*91f16700Schasinglulu 	/*
33*91f16700Schasinglulu 	 * Validate boot parameters
34*91f16700Schasinglulu 	 *
35*91f16700Schasinglulu 	 * According to the Boot Interface ABI v.0.1,
36*91f16700Schasinglulu 	 * the parameters received from EL3 are:
37*91f16700Schasinglulu 	 * x0: CPUID (verified earlier, so not used)
38*91f16700Schasinglulu 	 * x1: Boot Interface version
39*91f16700Schasinglulu 	 * x2: PLATFORM_CORE_COUNT
40*91f16700Schasinglulu 	 * x3: Pointer to the shared memory area.
41*91f16700Schasinglulu 	 */
42*91f16700Schasinglulu 
43*91f16700Schasinglulu 	(void)x0;
44*91f16700Schasinglulu 
45*91f16700Schasinglulu 	if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
46*91f16700Schasinglulu 		trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
47*91f16700Schasinglulu 	}
48*91f16700Schasinglulu 
49*91f16700Schasinglulu 	if ((void *)x3 == NULL) {
50*91f16700Schasinglulu 		trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
51*91f16700Schasinglulu 	}
52*91f16700Schasinglulu 
53*91f16700Schasinglulu 	if (x2 > TRP_PLATFORM_CORE_COUNT) {
54*91f16700Schasinglulu 		trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
55*91f16700Schasinglulu 	}
56*91f16700Schasinglulu 
57*91f16700Schasinglulu 	trp_boot_abi_version = x1;
58*91f16700Schasinglulu 	trp_shared_region_start = x3;
59*91f16700Schasinglulu 	flush_dcache_range((uintptr_t)&trp_boot_abi_version,
60*91f16700Schasinglulu 			   sizeof(trp_boot_abi_version));
61*91f16700Schasinglulu 	flush_dcache_range((uintptr_t)&trp_shared_region_start,
62*91f16700Schasinglulu 			   sizeof(trp_shared_region_start));
63*91f16700Schasinglulu 
64*91f16700Schasinglulu 	/* Perform early platform-specific setup */
65*91f16700Schasinglulu 	trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
66*91f16700Schasinglulu }
67*91f16700Schasinglulu 
68*91f16700Schasinglulu int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
69*91f16700Schasinglulu 			       uint64_t x2, uint64_t x3)
70*91f16700Schasinglulu {
71*91f16700Schasinglulu 	/*
72*91f16700Schasinglulu 	 * Validate boot parameters for warm boot
73*91f16700Schasinglulu 	 *
74*91f16700Schasinglulu 	 * According to the Boot Interface ABI v.0.1, the parameters
75*91f16700Schasinglulu 	 * received from EL3 during warm boot are:
76*91f16700Schasinglulu 	 *
77*91f16700Schasinglulu 	 * x0: CPUID (verified earlier so not used here)
78*91f16700Schasinglulu 	 * [x1:x3]: RES0
79*91f16700Schasinglulu 	 */
80*91f16700Schasinglulu 
81*91f16700Schasinglulu 	(void)x0;
82*91f16700Schasinglulu 
83*91f16700Schasinglulu 	return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN;
84*91f16700Schasinglulu }
85*91f16700Schasinglulu 
86*91f16700Schasinglulu /* Main function for TRP */
87*91f16700Schasinglulu void trp_main(void)
88*91f16700Schasinglulu {
89*91f16700Schasinglulu 	NOTICE("TRP: %s\n", version_string);
90*91f16700Schasinglulu 	NOTICE("TRP: %s\n", build_message);
91*91f16700Schasinglulu 	NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
92*91f16700Schasinglulu 		TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
93*91f16700Schasinglulu 	NOTICE("TRP: Boot Manifest Version: v.%u.%u\n",
94*91f16700Schasinglulu 		RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
95*91f16700Schasinglulu 		RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
96*91f16700Schasinglulu 	INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE);
97*91f16700Schasinglulu 	INFO("TRP: Shared region base address: 0x%lx\n",
98*91f16700Schasinglulu 			(unsigned long)trp_shared_region_start);
99*91f16700Schasinglulu 	INFO("TRP: Total size: 0x%lx bytes\n",
100*91f16700Schasinglulu 			(unsigned long)(RMM_END - RMM_BASE));
101*91f16700Schasinglulu 	INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
102*91f16700Schasinglulu 		TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
103*91f16700Schasinglulu 		TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
104*91f16700Schasinglulu }
105*91f16700Schasinglulu 
106*91f16700Schasinglulu /*******************************************************************************
107*91f16700Schasinglulu  * Returning RMI version back to Normal World
108*91f16700Schasinglulu  ******************************************************************************/
109*91f16700Schasinglulu static void trp_ret_rmi_version(unsigned long long rmi_version,
110*91f16700Schasinglulu 				struct trp_smc_result *smc_ret)
111*91f16700Schasinglulu {
112*91f16700Schasinglulu 	if (rmi_version != RMI_ABI_VERSION) {
113*91f16700Schasinglulu 		smc_ret->x[0] = RMI_ERROR_INPUT;
114*91f16700Schasinglulu 	} else {
115*91f16700Schasinglulu 		smc_ret->x[0] = RMI_SUCCESS;
116*91f16700Schasinglulu 	}
117*91f16700Schasinglulu 	VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
118*91f16700Schasinglulu 					  RMI_ABI_VERSION_MINOR);
119*91f16700Schasinglulu 	smc_ret->x[1] = RMI_ABI_VERSION;
120*91f16700Schasinglulu 	smc_ret->x[2] = RMI_ABI_VERSION;
121*91f16700Schasinglulu }
122*91f16700Schasinglulu 
123*91f16700Schasinglulu /*******************************************************************************
124*91f16700Schasinglulu  * Transitioning granule of NON-SECURE type to REALM type
125*91f16700Schasinglulu  ******************************************************************************/
126*91f16700Schasinglulu static void trp_asc_mark_realm(unsigned long long x1,
127*91f16700Schasinglulu 				struct trp_smc_result *smc_ret)
128*91f16700Schasinglulu {
129*91f16700Schasinglulu 	VERBOSE("Delegating granule 0x%llx\n", x1);
130*91f16700Schasinglulu 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
131*91f16700Schasinglulu 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
132*91f16700Schasinglulu 
133*91f16700Schasinglulu 	if (smc_ret->x[0] != 0ULL) {
134*91f16700Schasinglulu 		ERROR("Granule transition from NON-SECURE type to REALM type "
135*91f16700Schasinglulu 			"failed 0x%llx\n", smc_ret->x[0]);
136*91f16700Schasinglulu 	}
137*91f16700Schasinglulu }
138*91f16700Schasinglulu 
139*91f16700Schasinglulu /*******************************************************************************
140*91f16700Schasinglulu  * Transitioning granule of REALM type to NON-SECURE type
141*91f16700Schasinglulu  ******************************************************************************/
142*91f16700Schasinglulu static void trp_asc_mark_nonsecure(unsigned long long x1,
143*91f16700Schasinglulu 				   struct trp_smc_result *smc_ret)
144*91f16700Schasinglulu {
145*91f16700Schasinglulu 	VERBOSE("Undelegating granule 0x%llx\n", x1);
146*91f16700Schasinglulu 	smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
147*91f16700Schasinglulu 						0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
148*91f16700Schasinglulu 
149*91f16700Schasinglulu 	if (smc_ret->x[0] != 0ULL) {
150*91f16700Schasinglulu 		ERROR("Granule transition from REALM type to NON-SECURE type "
151*91f16700Schasinglulu 			"failed 0x%llx\n", smc_ret->x[0]);
152*91f16700Schasinglulu 	}
153*91f16700Schasinglulu }
154*91f16700Schasinglulu 
155*91f16700Schasinglulu /*******************************************************************************
156*91f16700Schasinglulu  * Main RMI SMC handler function
157*91f16700Schasinglulu  ******************************************************************************/
158*91f16700Schasinglulu void trp_rmi_handler(unsigned long fid,
159*91f16700Schasinglulu 		     unsigned long long x1, unsigned long long x2,
160*91f16700Schasinglulu 		     unsigned long long x3, unsigned long long x4,
161*91f16700Schasinglulu 		     unsigned long long x5, unsigned long long x6,
162*91f16700Schasinglulu 		     struct trp_smc_result *smc_ret)
163*91f16700Schasinglulu {
164*91f16700Schasinglulu 	/* Not used in the current implementation */
165*91f16700Schasinglulu 	(void)x2;
166*91f16700Schasinglulu 	(void)x3;
167*91f16700Schasinglulu 	(void)x4;
168*91f16700Schasinglulu 	(void)x5;
169*91f16700Schasinglulu 	(void)x6;
170*91f16700Schasinglulu 
171*91f16700Schasinglulu 	switch (fid) {
172*91f16700Schasinglulu 	case RMI_RMM_REQ_VERSION:
173*91f16700Schasinglulu 		trp_ret_rmi_version(x1, smc_ret);
174*91f16700Schasinglulu 		break;
175*91f16700Schasinglulu 	case RMI_RMM_GRANULE_DELEGATE:
176*91f16700Schasinglulu 		trp_asc_mark_realm(x1, smc_ret);
177*91f16700Schasinglulu 		break;
178*91f16700Schasinglulu 	case RMI_RMM_GRANULE_UNDELEGATE:
179*91f16700Schasinglulu 		trp_asc_mark_nonsecure(x1, smc_ret);
180*91f16700Schasinglulu 		break;
181*91f16700Schasinglulu 	default:
182*91f16700Schasinglulu 		ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
183*91f16700Schasinglulu 		smc_ret->x[0] = SMC_UNK;
184*91f16700Schasinglulu 	}
185*91f16700Schasinglulu }
186