blob: a82966e7729f1c4c555ad68f0c473889c2e8d84c [file] [log] [blame]
Zelalem Awekec8bc23e2021-07-09 15:32:21 -05001/*
Sona Mathewa4223962025-03-31 17:12:41 -05002 * Copyright (c) 2021-2025, Arm Limited and Contributors. All rights reserved.
Zelalem Awekec8bc23e2021-07-09 15:32:21 -05003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Chris Kay99b5b2e2024-03-08 16:08:31 +00007#include <common/build_message.h>
Zelalem Awekec8bc23e2021-07-09 15:32:21 -05008#include <common/debug.h>
9#include <plat/common/platform.h>
Javier Almansa Sobrino4165e842022-04-25 17:18:15 +010010#include <services/rmm_core_manifest.h>
Soby Mathew68ea9542022-03-22 13:58:52 +000011#include <services/rmmd_svc.h>
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050012#include <services/trp/platform_trp.h>
Javier Almansa Sobrino4165e842022-04-25 17:18:15 +010013#include <trp_helpers.h>
14#include "trp_private.h"
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050015
16#include <platform_def.h>
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050017
Sona Mathewa4223962025-03-31 17:12:41 -050018#define RMI_ERROR_REALM 2U
19#define RMI_ERROR_NOT_SUPPORTED 6U
20
21#define DIR_BIT_SHIFT 0x8
22#define KEYSET_SHIFT 0xC
23#define STREAM_ID_MASK 0xFF
24#define STREAM_ID_SHIFT 0x0
25#define SUBSTREAM_MASK 0x7
26#define SUBSTREAM_SHIFT 0x8
27
28#define KEY_SET 0x0
29#define DIR_VAL 0x0
30#define SUBSTREAM_VAL 0x1
31#define STREAM_ID 0x1
32
33#define ENCODE_STREAM_INFO(key, dir, substream, stream_id) \
34 (((key & 0x1) << KEYSET_SHIFT) | \
35 ((dir & 0x1) << DIR_BIT_SHIFT) | \
36 ((substream && SUBSTREAM_MASK) << SUBSTREAM_SHIFT) | \
37 ((stream_id && STREAM_ID_MASK) << STREAM_ID_SHIFT))
38
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000039/* Parameters received from the previous image */
40static unsigned int trp_boot_abi_version;
41static uintptr_t trp_shared_region_start;
42
Javier Almansa Sobrino4165e842022-04-25 17:18:15 +010043/* Parameters received from boot manifest */
44uint32_t trp_boot_manifest_version;
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000045
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050046/*******************************************************************************
47 * Setup function for TRP.
48 ******************************************************************************/
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000049void trp_setup(uint64_t x0,
50 uint64_t x1,
51 uint64_t x2,
52 uint64_t x3)
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050053{
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000054 /*
AlexeiFedorovf9044ab2022-11-24 13:42:44 +000055 * Validate boot parameters
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000056 *
AlexeiFedorovf9044ab2022-11-24 13:42:44 +000057 * According to the Boot Interface ABI v.0.1,
58 * the parameters received from EL3 are:
59 * x0: CPUID (verified earlier, so not used)
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +000060 * x1: Boot Interface version
61 * x2: PLATFORM_CORE_COUNT
62 * x3: Pointer to the shared memory area.
63 */
64
65 (void)x0;
66
67 if (TRP_RMM_EL3_VERSION_GET_MAJOR(x1) != TRP_RMM_EL3_ABI_VERS_MAJOR) {
68 trp_boot_abort(E_RMM_BOOT_VERSION_MISMATCH);
69 }
70
71 if ((void *)x3 == NULL) {
72 trp_boot_abort(E_RMM_BOOT_INVALID_SHARED_BUFFER);
73 }
74
75 if (x2 > TRP_PLATFORM_CORE_COUNT) {
76 trp_boot_abort(E_RMM_BOOT_CPUS_OUT_OF_RANGE);
77 }
78
79 trp_boot_abi_version = x1;
80 trp_shared_region_start = x3;
81 flush_dcache_range((uintptr_t)&trp_boot_abi_version,
82 sizeof(trp_boot_abi_version));
83 flush_dcache_range((uintptr_t)&trp_shared_region_start,
84 sizeof(trp_shared_region_start));
85
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050086 /* Perform early platform-specific setup */
AlexeiFedorov8e754f92022-12-14 17:28:11 +000087 trp_early_platform_setup((struct rmm_manifest *)trp_shared_region_start);
Zelalem Awekec8bc23e2021-07-09 15:32:21 -050088}
89
Javier Almansa Sobrino04a6f2f2022-12-01 17:20:45 +000090int trp_validate_warmboot_args(uint64_t x0, uint64_t x1,
91 uint64_t x2, uint64_t x3)
92{
93 /*
94 * Validate boot parameters for warm boot
95 *
96 * According to the Boot Interface ABI v.0.1, the parameters
97 * received from EL3 during warm boot are:
98 *
99 * x0: CPUID (verified earlier so not used here)
100 * [x1:x3]: RES0
101 */
102
103 (void)x0;
104
105 return ((x1 | x2 | x3) == 0UL) ? 0 : E_RMM_BOOT_UNKNOWN;
106}
107
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500108/* Main function for TRP */
109void trp_main(void)
110{
Chris Kay99b5b2e2024-03-08 16:08:31 +0000111 NOTICE("TRP: %s\n", build_version_string);
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500112 NOTICE("TRP: %s\n", build_message);
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +0000113 NOTICE("TRP: Supported RMM-EL3 Interface ABI: v.%u.%u\n",
114 TRP_RMM_EL3_ABI_VERS_MAJOR, TRP_RMM_EL3_ABI_VERS_MINOR);
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000115 NOTICE("TRP: Boot Manifest Version: v.%u.%u\n",
Javier Almansa Sobrino4165e842022-04-25 17:18:15 +0100116 RMMD_GET_MANIFEST_VERSION_MAJOR(trp_boot_manifest_version),
117 RMMD_GET_MANIFEST_VERSION_MINOR(trp_boot_manifest_version));
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000118 INFO("TRP: Memory base: 0x%lx\n", (unsigned long)RMM_BASE);
119 INFO("TRP: Shared region base address: 0x%lx\n",
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +0000120 (unsigned long)trp_shared_region_start);
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000121 INFO("TRP: Total size: 0x%lx bytes\n",
122 (unsigned long)(RMM_END - RMM_BASE));
Javier Almansa Sobrino7176a772021-11-24 18:37:37 +0000123 INFO("TRP: RMM-EL3 Interface ABI reported by EL3: v.%u.%u\n",
124 TRP_RMM_EL3_VERSION_GET_MAJOR(trp_boot_abi_version),
125 TRP_RMM_EL3_VERSION_GET_MINOR(trp_boot_abi_version));
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500126}
127
128/*******************************************************************************
129 * Returning RMI version back to Normal World
130 ******************************************************************************/
Shruti Gupta23c87332023-10-26 12:01:28 +0100131static void trp_ret_rmi_version(unsigned long long rmi_version,
132 struct trp_smc_result *smc_ret)
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500133{
Shruti Gupta23c87332023-10-26 12:01:28 +0100134 if (rmi_version != RMI_ABI_VERSION) {
135 smc_ret->x[0] = RMI_ERROR_INPUT;
136 } else {
137 smc_ret->x[0] = RMI_SUCCESS;
138 }
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500139 VERBOSE("RMM version is %u.%u\n", RMI_ABI_VERSION_MAJOR,
140 RMI_ABI_VERSION_MINOR);
Shruti Gupta23c87332023-10-26 12:01:28 +0100141 smc_ret->x[1] = RMI_ABI_VERSION;
142 smc_ret->x[2] = RMI_ABI_VERSION;
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500143}
144
145/*******************************************************************************
146 * Transitioning granule of NON-SECURE type to REALM type
147 ******************************************************************************/
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000148static void trp_asc_mark_realm(unsigned long long x1,
149 struct trp_smc_result *smc_ret)
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500150{
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500151 VERBOSE("Delegating granule 0x%llx\n", x1);
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000152 smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_DELEGATE, x1,
Sona Mathewa4223962025-03-31 17:12:41 -0500153 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500154
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000155 if (smc_ret->x[0] != 0ULL) {
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500156 ERROR("Granule transition from NON-SECURE type to REALM type "
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000157 "failed 0x%llx\n", smc_ret->x[0]);
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500158 }
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500159}
160
161/*******************************************************************************
162 * Transitioning granule of REALM type to NON-SECURE type
163 ******************************************************************************/
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000164static void trp_asc_mark_nonsecure(unsigned long long x1,
165 struct trp_smc_result *smc_ret)
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500166{
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500167 VERBOSE("Undelegating granule 0x%llx\n", x1);
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000168 smc_ret->x[0] = trp_smc(set_smc_args(RMM_GTSI_UNDELEGATE, x1,
Sona Mathewa4223962025-03-31 17:12:41 -0500169 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500170
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000171 if (smc_ret->x[0] != 0ULL) {
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500172 ERROR("Granule transition from REALM type to NON-SECURE type "
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000173 "failed 0x%llx\n", smc_ret->x[0]);
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500174 }
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500175}
176
177/*******************************************************************************
Sona Mathewa4223962025-03-31 17:12:41 -0500178 * Test the IDE Key management interface
179 ******************************************************************************/
180static void trp_ide_keymgmt_interface_fn(unsigned long long x1, unsigned long long x2,
181 struct trp_smc_result *smc_ret)
182{
183 uint64_t ecam_address = 0U, rp_id = 0U, ide_stream_info;
184 uint64_t keyqw0, keyqw1, keyqw2, keyqw3;
185 uint64_t ifvqw0, ifvqw1;
186 int return_value;
187
188#if RMMD_ENABLE_IDE_KEY_PROG
189 trp_get_test_rootport(&ecam_address, &rp_id);
190#endif /* RMMD_ENABLE_IDE_KEY_PROG */
191 /*
192 * Dummy values for testing:
193 * Key set = 0x0
194 * Dir = 0x0
195 * Substream = 0x1
196 * Stream ID = 0x1
197 */
198 ide_stream_info = ENCODE_STREAM_INFO(KEY_SET, DIR_VAL, SUBSTREAM_VAL, STREAM_ID);
199
200 /* Dummy key and IV values for testing */
201 keyqw0 = 0xA1B2C3D4E5F60708;
202 keyqw1 = 0x1122334455667788;
203 keyqw2 = 0xDEADBEEFCAFEBABE;
204 keyqw3 = 0x1234567890ABCDEF;
205 ifvqw0 = 0xABCDEF0123456789;
206 ifvqw1 = 0x9876543210FEDCBA;
207
208 return_value = trp_smc(set_smc_args(RMM_IDE_KEY_PROG, ecam_address, rp_id,
209 ide_stream_info, keyqw0, keyqw1, keyqw2, keyqw3, ifvqw0,
210 ifvqw1, 0UL, 0UL));
211
212 INFO("return value from RMM_IDE_KEY_PROG = %d\n", return_value);
213
214 return_value = trp_smc(set_smc_args(RMM_IDE_KEY_SET_GO, ecam_address, rp_id,
215 ide_stream_info, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
216
217 INFO("return value from RMM_IDE_KEY_SET_GO = %d\n", return_value);
218
219 return_value = trp_smc(set_smc_args(RMM_IDE_KEY_SET_STOP, ecam_address, rp_id,
220 ide_stream_info, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
221
222 INFO("return value from RMM_IDE_KEY_SET_STOP = %d\n", return_value);
223
224 return_value = trp_smc(set_smc_args(RMM_IDE_KM_PULL_RESPONSE, ecam_address, rp_id,
225 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL, 0UL));
226
227 INFO("return value from RMM_IDE_KEY_SET_STOP = %d\n", return_value);
228
229 smc_ret->x[0] = RMI_ERROR_NOT_SUPPORTED;
230
231}
232
233/*******************************************************************************
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500234 * Main RMI SMC handler function
235 ******************************************************************************/
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000236void trp_rmi_handler(unsigned long fid,
237 unsigned long long x1, unsigned long long x2,
238 unsigned long long x3, unsigned long long x4,
239 unsigned long long x5, unsigned long long x6,
240 struct trp_smc_result *smc_ret)
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500241{
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000242 /* Not used in the current implementation */
243 (void)x2;
244 (void)x3;
245 (void)x4;
246 (void)x5;
247 (void)x6;
248
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500249 switch (fid) {
250 case RMI_RMM_REQ_VERSION:
Shruti Gupta23c87332023-10-26 12:01:28 +0100251 trp_ret_rmi_version(x1, smc_ret);
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000252 break;
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500253 case RMI_RMM_GRANULE_DELEGATE:
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000254 trp_asc_mark_realm(x1, smc_ret);
255 break;
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500256 case RMI_RMM_GRANULE_UNDELEGATE:
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000257 trp_asc_mark_nonsecure(x1, smc_ret);
258 break;
Sona Mathewa4223962025-03-31 17:12:41 -0500259 case RMI_RMM_PDEV_CREATE:
260 trp_ide_keymgmt_interface_fn(x1, x2, smc_ret);
261 break;
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500262 default:
AlexeiFedorovf9044ab2022-11-24 13:42:44 +0000263 ERROR("Invalid SMC code to %s, FID %lx\n", __func__, fid);
264 smc_ret->x[0] = SMC_UNK;
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500265 }
Zelalem Awekec8bc23e2021-07-09 15:32:21 -0500266}