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 ******************************************************************************/
trp_setup(uint64_t x0,uint64_t x1,uint64_t x2,uint64_t x3)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 /* Main function for TRP */
trp_main(void)70 void trp_main(void)
71 {
72 NOTICE("TRP: %s\n", version_string);
73 NOTICE("TRP: %s\n", build_message);
74 NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
75 TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
76 NOTICE("TRP: Boot Manifest Version : v.%u.%u\n",
77 RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
78 RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
79 INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
80 INFO("TRP: Base address for the shared region : 0x%lx\n",
81 (unsigned long)trp_shared_region_start);
82 INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
83 - RMM_BASE));
84 INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
85 TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
86 TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
87 }
88
89 /*******************************************************************************
90 * Returning RMI version back to Normal World
91 ******************************************************************************/
trp_ret_rmi_version(void)92 static trp_args_t *trp_ret_rmi_version(void)
93 {
94 VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
95 RMI_ABI_VERSION_MINOR);
96 return set_smc_args(RMM_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
97 0, 0, 0, 0, 0, 0);
98 }
99
100 /*******************************************************************************
101 * Transitioning granule of NON-SECURE type to REALM type
102 ******************************************************************************/
trp_asc_mark_realm(unsigned long long x1)103 static trp_args_t *trp_asc_mark_realm(unsigned long long x1)
104 {
105 unsigned long long ret;
106
107 VERBOSE("Delegating granule 0x%llx\n", x1);
108 ret = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
109
110 if (ret != 0ULL) {
111 ERROR("Granule transition from NON-SECURE type to REALM type "
112 "failed 0x%llx\n", ret);
113 }
114 return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
115 }
116
117 /*******************************************************************************
118 * Transitioning granule of REALM type to NON-SECURE type
119 ******************************************************************************/
trp_asc_mark_nonsecure(unsigned long long x1)120 static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1)
121 {
122 unsigned long long ret;
123
124 VERBOSE("Undelegating granule 0x%llx\n", x1);
125 ret = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
126
127 if (ret != 0ULL) {
128 ERROR("Granule transition from REALM type to NON-SECURE type "
129 "failed 0x%llx\n", ret);
130 }
131 return set_smc_args(RMM_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
132 }
133
134 /*******************************************************************************
135 * Main RMI SMC handler function
136 ******************************************************************************/
trp_rmi_handler(unsigned long fid,unsigned long long x1)137 trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1)
138 {
139 switch (fid) {
140 case RMI_RMM_REQ_VERSION:
141 return trp_ret_rmi_version();
142 case RMI_RMM_GRANULE_DELEGATE:
143 return trp_asc_mark_realm(x1);
144 case RMI_RMM_GRANULE_UNDELEGATE:
145 return trp_asc_mark_nonsecure(x1);
146 default:
147 ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid);
148 }
149 return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0);
150 }
151