blob: 7df128b629d8f47745814f3615b6de7719c81b8f [file] [log] [blame]
Zelalem Aweke50a30562021-07-09 15:32:21 -05001/*
Soby Mathew319fb082022-03-22 13:58:52 +00002 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
Zelalem Aweke50a30562021-07-09 15:32:21 -05003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7
8#include <common/debug.h>
9#include <plat/common/platform.h>
Soby Mathew319fb082022-03-22 13:58:52 +000010#include <services/rmmd_svc.h>
Zelalem Aweke50a30562021-07-09 15:32:21 -050011#include <services/trp/platform_trp.h>
12
13#include <platform_def.h>
14#include "trp_private.h"
15
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +000016/* Parameters received from the previous image */
17static unsigned int trp_boot_abi_version;
18static uintptr_t trp_shared_region_start;
19
Zelalem Aweke50a30562021-07-09 15:32:21 -050020/*******************************************************************************
21 * Per cpu data structure to populate parameters for an SMC in C code and use
22 * a pointer to this structure in assembler code to populate x0-x7
23 ******************************************************************************/
24static trp_args_t trp_smc_args[PLATFORM_CORE_COUNT];
25
26/*******************************************************************************
27 * Set the arguments for SMC call
28 ******************************************************************************/
29static trp_args_t *set_smc_args(uint64_t arg0,
30 uint64_t arg1,
31 uint64_t arg2,
32 uint64_t arg3,
33 uint64_t arg4,
34 uint64_t arg5,
35 uint64_t arg6,
36 uint64_t arg7)
37{
38 uint32_t linear_id;
39 trp_args_t *pcpu_smc_args;
40
41 /*
42 * Return to Secure Monitor by raising an SMC. The results of the
43 * service are passed as an arguments to the SMC
44 */
45 linear_id = plat_my_core_pos();
46 pcpu_smc_args = &trp_smc_args[linear_id];
47 write_trp_arg(pcpu_smc_args, TRP_ARG0, arg0);
48 write_trp_arg(pcpu_smc_args, TRP_ARG1, arg1);
49 write_trp_arg(pcpu_smc_args, TRP_ARG2, arg2);
50 write_trp_arg(pcpu_smc_args, TRP_ARG3, arg3);
51 write_trp_arg(pcpu_smc_args, TRP_ARG4, arg4);
52 write_trp_arg(pcpu_smc_args, TRP_ARG5, arg5);
53 write_trp_arg(pcpu_smc_args, TRP_ARG6, arg6);
54 write_trp_arg(pcpu_smc_args, TRP_ARG7, arg7);
55
56 return pcpu_smc_args;
57}
58
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +000059/*
60 * Abort the boot process with the reason given in err.
61 */
62__dead2 static void trp_boot_abort(uint64_t err)
63{
64 (void)trp_smc(set_smc_args(RMM_BOOT_COMPLETE, err, 0, 0, 0, 0, 0, 0));
65 panic();
66}
67
Zelalem Aweke50a30562021-07-09 15:32:21 -050068/*******************************************************************************
69 * Setup function for TRP.
70 ******************************************************************************/
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +000071void trp_setup(uint64_t x0,
72 uint64_t x1,
73 uint64_t x2,
74 uint64_t x3)
Zelalem Aweke50a30562021-07-09 15:32:21 -050075{
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +000076 /*
77 * Validate boot parameters.
78 *
79 * According to the Boot Interface ABI v.0.1, the
80 * parameters recived from EL3 are:
81 * x0: CPUID (verified earlier so not used)
82 * x1: Boot Interface version
83 * x2: PLATFORM_CORE_COUNT
84 * x3: Pointer to the shared memory area.
85 */
86
87 (void)x0;
88
89 if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
90 trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
91 }
92
93 if ((void *)x3 == NULL) {
94 trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
95 }
96
97 if (x2 > TRP_PLATFORM_CORE_COUNT) {
98 trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
99 }
100
101 trp_boot_abi_version = x1;
102 trp_shared_region_start = x3;
103 flush_dcache_range((uintptr_t)&trp_boot_abi_version,
104 sizeof(trp_boot_abi_version));
105 flush_dcache_range((uintptr_t)&trp_shared_region_start,
106 sizeof(trp_shared_region_start));
107
Zelalem Aweke50a30562021-07-09 15:32:21 -0500108 /* Perform early platform-specific setup */
109 trp_early_platform_setup();
110}
111
112/* Main function for TRP */
113void trp_main(void)
114{
115 NOTICE("TRP: %s\n", version_string);
116 NOTICE("TRP: %s\n", build_message);
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +0000117 NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
118 TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
Zelalem Aweke50a30562021-07-09 15:32:21 -0500119 INFO("TRP: Memory base : 0x%lx\n", (unsigned long)RMM_BASE);
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +0000120 INFO("TRP: Base address for the shared region : 0x%lx\n",
121 (unsigned long)trp_shared_region_start);
Zelalem Aweke50a30562021-07-09 15:32:21 -0500122 INFO("TRP: Total size : 0x%lx bytes\n", (unsigned long)(RMM_END
123 - RMM_BASE));
Javier Almansa Sobrino8c980a42021-11-24 18:37:37 +0000124 INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
125 TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
126 TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
Zelalem Aweke50a30562021-07-09 15:32:21 -0500127}
128
129/*******************************************************************************
130 * Returning RMI version back to Normal World
131 ******************************************************************************/
132static trp_args_t *trp_ret_rmi_version(void)
133{
134 VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
135 RMI_ABI_VERSION_MINOR);
Soby Mathew319fb082022-03-22 13:58:52 +0000136 return set_smc_args(RMMD_RMI_REQ_COMPLETE, RMI_ABI_VERSION,
Zelalem Aweke50a30562021-07-09 15:32:21 -0500137 0, 0, 0, 0, 0, 0);
138}
139
140/*******************************************************************************
141 * Transitioning granule of NON-SECURE type to REALM type
142 ******************************************************************************/
143static trp_args_t *trp_asc_mark_realm(unsigned long long x1)
144{
145 unsigned long long ret;
146
147 VERBOSE("Delegating granule 0x%llx\n", x1);
Soby Mathew319fb082022-03-22 13:58:52 +0000148 ret = trp_smc(set_smc_args(RMMD_GTSI_DELEGATE, x1, 0, 0, 0, 0, 0, 0));
Zelalem Aweke50a30562021-07-09 15:32:21 -0500149
150 if (ret != 0ULL) {
151 ERROR("Granule transition from NON-SECURE type to REALM type "
152 "failed 0x%llx\n", ret);
153 }
Soby Mathew319fb082022-03-22 13:58:52 +0000154 return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
Zelalem Aweke50a30562021-07-09 15:32:21 -0500155}
156
157/*******************************************************************************
158 * Transitioning granule of REALM type to NON-SECURE type
159 ******************************************************************************/
160static trp_args_t *trp_asc_mark_nonsecure(unsigned long long x1)
161{
162 unsigned long long ret;
163
164 VERBOSE("Undelegating granule 0x%llx\n", x1);
Soby Mathew319fb082022-03-22 13:58:52 +0000165 ret = trp_smc(set_smc_args(RMMD_GTSI_UNDELEGATE, x1, 0, 0, 0, 0, 0, 0));
Zelalem Aweke50a30562021-07-09 15:32:21 -0500166
167 if (ret != 0ULL) {
168 ERROR("Granule transition from REALM type to NON-SECURE type "
169 "failed 0x%llx\n", ret);
170 }
Soby Mathew319fb082022-03-22 13:58:52 +0000171 return set_smc_args(RMMD_RMI_REQ_COMPLETE, ret, 0, 0, 0, 0, 0, 0);
Zelalem Aweke50a30562021-07-09 15:32:21 -0500172}
173
174/*******************************************************************************
175 * Main RMI SMC handler function
176 ******************************************************************************/
177trp_args_t *trp_rmi_handler(unsigned long fid, unsigned long long x1)
178{
179 switch (fid) {
180 case RMI_RMM_REQ_VERSION:
181 return trp_ret_rmi_version();
182 case RMI_RMM_GRANULE_DELEGATE:
183 return trp_asc_mark_realm(x1);
184 case RMI_RMM_GRANULE_UNDELEGATE:
185 return trp_asc_mark_nonsecure(x1);
186 default:
187 ERROR("Invalid SMC code to %s, FID %lu\n", __func__, fid);
188 }
189 return set_smc_args(SMC_UNK, 0, 0, 0, 0, 0, 0, 0);
190}