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