blob: 3532bebe58b6dafa9f494548e86e5f972284d4ad [file] [log] [blame]
Varun Wadekar3d4e6a52015-03-13 14:01:03 +05301/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/*******************************************************************************
32 * This is the Secure Payload Dispatcher (SPD). The dispatcher is meant to be a
33 * plug-in component to the Secure Monitor, registered as a runtime service. The
34 * SPD is expected to be a functional extension of the Secure Payload (SP) that
35 * executes in Secure EL1. The Secure Monitor will delegate all SMCs targeting
36 * the Trusted OS/Applications range to the dispatcher. The SPD will either
37 * handle the request locally or delegate it to the Secure Payload. It is also
38 * responsible for initialising and maintaining communication with the SP.
39 ******************************************************************************/
40#include <arch_helpers.h>
41#include <assert.h>
42#include <bl_common.h>
43#include <bl31.h>
44#include <context_mgmt.h>
45#include <debug.h>
46#include <errno.h>
47#include <platform.h>
48#include <runtime_svc.h>
49#include <stddef.h>
50#include <tlk.h>
51#include <uuid.h>
52#include "tlkd_private.h"
53
54extern const spd_pm_ops_t tlkd_pm_ops;
55
56/*******************************************************************************
57 * Array to keep track of per-cpu Secure Payload state
58 ******************************************************************************/
59static tlk_context_t tlk_ctx;
60
61/* TLK UID: RFC-4122 compliant UUID (version-5, sha-1) */
62DEFINE_SVC_UUID(tlk_uuid,
63 0xbd11e9c9, 0x2bba, 0x52ee, 0xb1, 0x72,
64 0x46, 0x1f, 0xba, 0x97, 0x7f, 0x63);
65
66int32_t tlkd_init(void);
67
Varun Wadekar3d4e6a52015-03-13 14:01:03 +053068/*******************************************************************************
69 * Secure Payload Dispatcher setup. The SPD finds out the SP entrypoint and type
70 * (aarch32/aarch64) if not already known and initialises the context for entry
71 * into the SP for its initialisation.
72 ******************************************************************************/
73int32_t tlkd_setup(void)
74{
75 entry_point_info_t *tlk_ep_info;
76
77 /*
78 * Get information about the Secure Payload (BL32) image. Its
79 * absence is a critical failure.
80 */
81 tlk_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
82 if (!tlk_ep_info) {
83 WARN("No SP provided. Booting device without SP"
84 " initialization. SMC`s destined for SP"
85 " will return SMC_UNK\n");
86 return 1;
87 }
88
89 /*
90 * If there's no valid entry point for SP, we return a non-zero value
91 * signalling failure initializing the service. We bail out without
92 * registering any handlers
93 */
94 if (!tlk_ep_info->pc)
95 return 1;
96
97 /*
98 * Inspect the SP image's SPSR and determine it's execution state
99 * i.e whether AArch32 or AArch64.
100 */
101 tlkd_init_tlk_ep_state(tlk_ep_info,
102 (tlk_ep_info->spsr >> MODE_RW_SHIFT) & MODE_RW_MASK,
103 tlk_ep_info->pc,
104 &tlk_ctx);
105
106 /*
107 * All TLK SPD initialization done. Now register our init function
108 * with BL31 for deferred invocation
109 */
110 bl31_register_bl32_init(&tlkd_init);
111
112 return 0;
113}
114
115/*******************************************************************************
116 * This function passes control to the Secure Payload image (BL32) for the first
117 * time on the primary cpu after a cold boot. It assumes that a valid secure
118 * context has already been created by tlkd_setup() which can be directly
119 * used. This function performs a synchronous entry into the Secure payload.
120 * The SP passes control back to this routine through a SMC.
121 ******************************************************************************/
122int32_t tlkd_init(void)
123{
124 uint64_t mpidr = read_mpidr();
125 entry_point_info_t *tlk_entry_point;
126
127 /*
128 * Get information about the Secure Payload (BL32) image. Its
129 * absence is a critical failure.
130 */
131 tlk_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
132 assert(tlk_entry_point);
133
134 cm_init_context(mpidr, tlk_entry_point);
135
136 /*
137 * Arrange for an entry into the test secure payload.
138 */
139 return tlkd_synchronous_sp_entry(&tlk_ctx);
140}
141
142/*******************************************************************************
143 * This function is responsible for handling all SMCs in the Trusted OS/App
144 * range from the non-secure state as defined in the SMC Calling Convention
145 * Document. It is also responsible for communicating with the Secure payload
146 * to delegate work and return results back to the non-secure state. Lastly it
147 * will also return any information that the secure payload needs to do the
148 * work assigned to it.
149 ******************************************************************************/
150uint64_t tlkd_smc_handler(uint32_t smc_fid,
151 uint64_t x1,
152 uint64_t x2,
153 uint64_t x3,
154 uint64_t x4,
155 void *cookie,
156 void *handle,
157 uint64_t flags)
158{
Varun Wadekara97535f2015-03-13 14:19:11 +0530159 cpu_context_t *ns_cpu_context;
Varun Wadekarebfeae92015-04-02 14:57:47 +0530160 gp_regs_t *gp_regs;
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530161 uint32_t ns;
Varun Wadekarebfeae92015-04-02 14:57:47 +0530162 uint64_t par;
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530163
164 /* Passing a NULL context is a critical programming error */
165 assert(handle);
166
Varun Wadekarb539b6c2015-03-13 15:18:20 +0530167 /* These SMCs are only supported by CPU0 */
168 if ((read_mpidr() & MPIDR_CPU_MASK) != 0)
169 SMC_RET1(handle, SMC_UNK);
170
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530171 /* Determine which security state this SMC originated from */
172 ns = is_caller_non_secure(flags);
173
174 switch (smc_fid) {
175
176 /*
Varun Wadekar968c0292015-03-13 15:10:54 +0530177 * This function ID is used by SP to indicate that it was
178 * preempted by a non-secure world IRQ.
179 */
180 case TLK_PREEMPTED:
181
182 if (ns)
183 SMC_RET1(handle, SMC_UNK);
184
185 assert(handle == cm_get_context(SECURE));
186 cm_el1_sysregs_context_save(SECURE);
187
188 /* Get a reference to the non-secure context */
189 ns_cpu_context = cm_get_context(NON_SECURE);
190 assert(ns_cpu_context);
191
192 /*
193 * Restore non-secure state. There is no need to save the
194 * secure system register context since the SP was supposed
195 * to preserve it during S-EL1 interrupt handling.
196 */
197 cm_el1_sysregs_context_restore(NON_SECURE);
198 cm_set_next_eret_context(NON_SECURE);
199
Varun Wadekarebfeae92015-04-02 14:57:47 +0530200 SMC_RET1(ns_cpu_context, x1);
Varun Wadekar968c0292015-03-13 15:10:54 +0530201
202 /*
203 * Request from non secure world to resume the preempted
204 * Standard SMC call.
205 */
206 case TLK_RESUME_FID:
207
208 /* RESUME should be invoked only by normal world */
209 if (!ns)
210 SMC_RET1(handle, SMC_UNK);
211
212 /*
213 * This is a resume request from the non-secure client.
214 * save the non-secure state and send the request to
215 * the secure payload.
216 */
217 assert(handle == cm_get_context(NON_SECURE));
218
219 /* Check if we are already preempted before resume */
220 if (!get_std_smc_active_flag(tlk_ctx.state))
221 SMC_RET1(handle, SMC_UNK);
222
223 cm_el1_sysregs_context_save(NON_SECURE);
224
225 /*
226 * We are done stashing the non-secure context. Ask the
227 * secure payload to do the work now.
228 */
229
230 /* We just need to return to the preempted point in
231 * SP and the execution will resume as normal.
232 */
233 cm_el1_sysregs_context_restore(SECURE);
234 cm_set_next_eret_context(SECURE);
235 SMC_RET0(handle);
236
237 /*
Varun Wadekara97535f2015-03-13 14:19:11 +0530238 * This is a request from the non-secure context to:
239 *
240 * a. register shared memory with the SP for storing it's
241 * activity logs.
242 * b. register shared memory with the SP for passing args
243 * required for maintaining sessions with the Trusted
244 * Applications.
Varun Wadekarb539b6c2015-03-13 15:18:20 +0530245 * c. open/close sessions
246 * d. issue commands to the Trusted Apps
Varun Wadekara97535f2015-03-13 14:19:11 +0530247 */
248 case TLK_REGISTER_LOGBUF:
249 case TLK_REGISTER_REQBUF:
Varun Wadekarb539b6c2015-03-13 15:18:20 +0530250 case TLK_OPEN_TA_SESSION:
251 case TLK_CLOSE_TA_SESSION:
252 case TLK_TA_LAUNCH_OP:
253 case TLK_TA_SEND_EVENT:
254
Varun Wadekarebfeae92015-04-02 14:57:47 +0530255 if (!ns)
Varun Wadekara97535f2015-03-13 14:19:11 +0530256 SMC_RET1(handle, SMC_UNK);
257
258 /*
259 * This is a fresh request from the non-secure client.
260 * The parameters are in x1 and x2. Figure out which
261 * registers need to be preserved, save the non-secure
262 * state and send the request to the secure payload.
263 */
264 assert(handle == cm_get_context(NON_SECURE));
265
266 /* Check if we are already preempted */
267 if (get_std_smc_active_flag(tlk_ctx.state))
268 SMC_RET1(handle, SMC_UNK);
269
270 cm_el1_sysregs_context_save(NON_SECURE);
271
272 /*
273 * Verify if there is a valid context to use.
274 */
275 assert(&tlk_ctx.cpu_ctx == cm_get_context(SECURE));
276
277 /*
278 * Mark the SP state as active.
279 */
280 set_std_smc_active_flag(tlk_ctx.state);
281
Varun Wadekara97535f2015-03-13 14:19:11 +0530282 /*
283 * We are done stashing the non-secure context. Ask the
284 * secure payload to do the work now.
285 */
286 cm_el1_sysregs_context_restore(SECURE);
287 cm_set_next_eret_context(SECURE);
Varun Wadekarebfeae92015-04-02 14:57:47 +0530288
289 /*
290 * TLK is a 32-bit Trusted OS and so expects the SMC
291 * arguments via r0-r7. TLK expects the monitor frame
292 * registers to be 64-bits long. Hence, we pass x0 in
293 * r0-r1, x1 in r2-r3, x3 in r4-r5 and x4 in r6-r7.
294 *
295 * As smc_fid is a uint32 value, r1 contains 0.
296 */
297 gp_regs = get_gpregs_ctx(&tlk_ctx.cpu_ctx);
298 write_ctx_reg(gp_regs, CTX_GPREG_X4, (uint32_t)x2);
299 write_ctx_reg(gp_regs, CTX_GPREG_X5, (uint32_t)(x2 >> 32));
300 write_ctx_reg(gp_regs, CTX_GPREG_X6, (uint32_t)x3);
301 write_ctx_reg(gp_regs, CTX_GPREG_X7, (uint32_t)(x3 >> 32));
302 SMC_RET4(&tlk_ctx.cpu_ctx, smc_fid, 0, (uint32_t)x1,
303 (uint32_t)(x1 >> 32));
Varun Wadekara97535f2015-03-13 14:19:11 +0530304
305 /*
Varun Wadekarebfeae92015-04-02 14:57:47 +0530306 * Translate NS/EL1-S virtual addresses.
307 *
308 * x1 = virtual address
309 * x3 = type (NS/S)
310 *
311 * Returns PA:lo in r0, PA:hi in r1.
Varun Wadekar97625e32015-03-13 14:59:03 +0530312 */
313 case TLK_VA_TRANSLATE:
Varun Wadekarebfeae92015-04-02 14:57:47 +0530314
315 /* Should be invoked only by secure world */
316 if (ns)
Varun Wadekar97625e32015-03-13 14:59:03 +0530317 SMC_RET1(handle, SMC_UNK);
318
Varun Wadekarebfeae92015-04-02 14:57:47 +0530319 /* NS virtual addresses are 64-bit long */
320 if (x3 & TLK_TRANSLATE_NS_VADDR)
321 x1 = (uint32_t)x1 | (x2 << 32);
Varun Wadekar97625e32015-03-13 14:59:03 +0530322
Varun Wadekarebfeae92015-04-02 14:57:47 +0530323 if (!x1)
324 SMC_RET1(handle, SMC_UNK);
Varun Wadekar97625e32015-03-13 14:59:03 +0530325
Varun Wadekarebfeae92015-04-02 14:57:47 +0530326 /*
327 * TODO: Sanity check x1. This would require platform
328 * support.
329 */
Varun Wadekar97625e32015-03-13 14:59:03 +0530330
Varun Wadekarebfeae92015-04-02 14:57:47 +0530331 /* virtual address and type: ns/s */
332 par = tlkd_va_translate(x1, x3);
333
334 /* return physical address in r0-r1 */
335 SMC_RET4(handle, (uint32_t)par, (uint32_t)(par >> 32), 0, 0);
Varun Wadekar97625e32015-03-13 14:59:03 +0530336
337 /*
Varun Wadekara97535f2015-03-13 14:19:11 +0530338 * This is a request from the SP to mark completion of
339 * a standard function ID.
340 */
341 case TLK_REQUEST_DONE:
Varun Wadekarebfeae92015-04-02 14:57:47 +0530342 if (ns)
Varun Wadekara97535f2015-03-13 14:19:11 +0530343 SMC_RET1(handle, SMC_UNK);
344
345 /*
346 * Mark the SP state as inactive.
347 */
348 clr_std_smc_active_flag(tlk_ctx.state);
349
350 /* Get a reference to the non-secure context */
351 ns_cpu_context = cm_get_context(NON_SECURE);
352 assert(ns_cpu_context);
353
354 /*
355 * This is a request completion SMC and we must switch to
356 * the non-secure world to pass the result.
357 */
358 cm_el1_sysregs_context_save(SECURE);
359
360 /*
361 * We are done stashing the secure context. Switch to the
362 * non-secure context and return the result.
363 */
364 cm_el1_sysregs_context_restore(NON_SECURE);
365 cm_set_next_eret_context(NON_SECURE);
Varun Wadekarebfeae92015-04-02 14:57:47 +0530366 SMC_RET1(ns_cpu_context, x1);
Varun Wadekara97535f2015-03-13 14:19:11 +0530367
368 /*
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530369 * This function ID is used only by the SP to indicate it has
370 * finished initialising itself after a cold boot
371 */
372 case TLK_ENTRY_DONE:
Varun Wadekarebfeae92015-04-02 14:57:47 +0530373 if (ns)
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530374 SMC_RET1(handle, SMC_UNK);
375
376 /*
377 * SP has been successfully initialized. Register power
378 * managemnt hooks with PSCI
379 */
380 psci_register_spd_pm_hook(&tlkd_pm_ops);
381
382 /*
383 * TLK reports completion. The SPD must have initiated
384 * the original request through a synchronous entry
385 * into the SP. Jump back to the original C runtime
386 * context.
387 */
Varun Wadekarebfeae92015-04-02 14:57:47 +0530388 tlkd_synchronous_sp_exit(&tlk_ctx, x1);
Varun Wadekar3d4e6a52015-03-13 14:01:03 +0530389
390 /*
391 * Return the number of service function IDs implemented to
392 * provide service to non-secure
393 */
394 case TOS_CALL_COUNT:
395 SMC_RET1(handle, TLK_NUM_FID);
396
397 /*
398 * Return TLK's UID to the caller
399 */
400 case TOS_UID:
401 SMC_UUID_RET(handle, tlk_uuid);
402
403 /*
404 * Return the version of current implementation
405 */
406 case TOS_CALL_VERSION:
407 SMC_RET2(handle, TLK_VERSION_MAJOR, TLK_VERSION_MINOR);
408
409 default:
410 break;
411 }
412
413 SMC_RET1(handle, SMC_UNK);
414}
415
416/* Define a SPD runtime service descriptor for fast SMC calls */
417DECLARE_RT_SVC(
418 tlkd_tos_fast,
419
420 OEN_TOS_START,
421 OEN_TOS_END,
422 SMC_TYPE_FAST,
423 tlkd_setup,
424 tlkd_smc_handler
425);
426
427/* Define a SPD runtime service descriptor for standard SMC calls */
428DECLARE_RT_SVC(
429 tlkd_tos_std,
430
431 OEN_TOS_START,
432 OEN_TOS_END,
433 SMC_TYPE_STD,
434 NULL,
435 tlkd_smc_handler
436);
Varun Wadekarb539b6c2015-03-13 15:18:20 +0530437
438/* Define a SPD runtime service descriptor for fast SMC calls */
439DECLARE_RT_SVC(
440 tlkd_tap_fast,
441
442 OEN_TAP_START,
443 OEN_TAP_END,
444 SMC_TYPE_FAST,
445 NULL,
446 tlkd_smc_handler
447);
448
449/* Define a SPD runtime service descriptor for standard SMC calls */
450DECLARE_RT_SVC(
451 tlkd_tap_std,
452
453 OEN_TAP_START,
454 OEN_TAP_END,
455 SMC_TYPE_STD,
456 NULL,
457 tlkd_smc_handler
458);