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