11bb92983SJerome Forissier /* SPDX-License-Identifier: BSD-2-Clause */
2b0104773SPascal Brand /*
3b0104773SPascal Brand * Copyright (c) 2014, STMicroelectronics International N.V.
4cb0b5954SJens Wiklander * Copyright (c) 2017, Linaro Limited
536bb435fSBalint Dobszay * Copyright (c) 2020, Arm Limited
6b0104773SPascal Brand */
7b0104773SPascal Brand
8fbe66cf8SEtienne Carriere #ifndef __KERNEL_TEE_TA_MANAGER_H
9fbe66cf8SEtienne Carriere #define __KERNEL_TEE_TA_MANAGER_H
10b0104773SPascal Brand
11ce332a51SJens Wiklander #include <assert.h>
121936dfc7SJens Wiklander #include <kernel/mutex.h>
131936dfc7SJens Wiklander #include <kernel/tee_common.h>
1400b3b9a2SJens Wiklander #include <kernel/ts_manager.h>
151936dfc7SJens Wiklander #include <mm/tee_mmu_types.h>
160795afd0SJens Wiklander #include <sys/queue.h>
17bc420748SJens Wiklander #include <tee_api_types.h>
181936dfc7SJens Wiklander #include <types_ext.h>
190795afd0SJens Wiklander #include <user_ta_header.h>
201936dfc7SJens Wiklander #include <utee_types.h>
21b0104773SPascal Brand
2260699957SPascal Brand /* Magic TEE identity pointer: set when teecore requests a TA close */
2360699957SPascal Brand #define KERN_IDENTITY ((TEE_Identity *)-1)
2460699957SPascal Brand /* Operation is initiated by a client (non-secure) app */
2560699957SPascal Brand #define NSAPP_IDENTITY (NULL)
2660699957SPascal Brand
270795afd0SJens Wiklander TAILQ_HEAD(tee_ta_session_head, tee_ta_session);
280795afd0SJens Wiklander TAILQ_HEAD(tee_ta_ctx_head, tee_ta_ctx);
290795afd0SJens Wiklander
300dcfa568SJens Wiklander struct mobj;
310dcfa568SJens Wiklander
320dcfa568SJens Wiklander struct param_val {
330dcfa568SJens Wiklander uint32_t a;
340dcfa568SJens Wiklander uint32_t b;
350dcfa568SJens Wiklander };
360dcfa568SJens Wiklander
370dcfa568SJens Wiklander struct param_mem {
380dcfa568SJens Wiklander struct mobj *mobj;
390dcfa568SJens Wiklander size_t size;
400dcfa568SJens Wiklander size_t offs;
410dcfa568SJens Wiklander };
420dcfa568SJens Wiklander
430795afd0SJens Wiklander struct tee_ta_param {
440795afd0SJens Wiklander uint32_t types;
450dcfa568SJens Wiklander union {
460dcfa568SJens Wiklander struct param_val val;
470dcfa568SJens Wiklander struct param_mem mem;
480dcfa568SJens Wiklander } u[TEE_NUM_PARAMS];
490795afd0SJens Wiklander };
500795afd0SJens Wiklander
510795afd0SJens Wiklander struct user_ta_ctx;
520795afd0SJens Wiklander
53883c4be3SJerome Forissier #if defined(CFG_TA_GPROF_SUPPORT)
54883c4be3SJerome Forissier struct sample_buf {
55883c4be3SJerome Forissier uint32_t nsamples; /* Size of @samples array in uint16_t */
56883c4be3SJerome Forissier uint32_t offset; /* Passed from user mode */
57883c4be3SJerome Forissier uint32_t scale; /* Passed from user mode */
58883c4be3SJerome Forissier uint32_t count; /* Number of samples taken */
59883c4be3SJerome Forissier bool enabled; /* Sampling enabled? */
60883c4be3SJerome Forissier uint16_t *samples;
61883c4be3SJerome Forissier uint64_t usr; /* Total user CPU time for this session */
62883c4be3SJerome Forissier uint64_t usr_entered; /* When this session last entered user mode */
63883c4be3SJerome Forissier uint32_t freq; /* @usr divided by @freq is in seconds */
64883c4be3SJerome Forissier };
65883c4be3SJerome Forissier #endif
66883c4be3SJerome Forissier
670795afd0SJens Wiklander /* Context of a loaded TA */
680795afd0SJens Wiklander struct tee_ta_ctx {
690795afd0SJens Wiklander uint32_t flags; /* TA_FLAGS from TA header */
700795afd0SJens Wiklander TAILQ_ENTRY(tee_ta_ctx) link;
713560d990SJens Wiklander struct ts_ctx ts_ctx;
720795afd0SJens Wiklander uint32_t panicked; /* True if TA has panicked, written from asm */
730795afd0SJens Wiklander uint32_t panic_code; /* Code supplied for panic */
740795afd0SJens Wiklander uint32_t ref_count; /* Reference counter for multi session TA */
75d1911a85SJens Wiklander bool busy; /* Context is busy and cannot be entered */
76*fee55718SEtienne Carriere bool is_initializing; /* Context initialization is not completed */
77c10e3fa9SJens Wiklander bool is_releasing; /* Context is about to be released */
780795afd0SJens Wiklander struct condvar busy_cv; /* CV used when context is busy */
790795afd0SJens Wiklander };
800795afd0SJens Wiklander
810795afd0SJens Wiklander struct tee_ta_session {
820795afd0SJens Wiklander TAILQ_ENTRY(tee_ta_session) link;
8300b3b9a2SJens Wiklander struct ts_session ts_sess;
8499164a05SJerome Forissier uint32_t id; /* Session handle (0 is invalid) */
850795afd0SJens Wiklander TEE_Identity clnt_id; /* Identify of client */
8682061b8dSJens Wiklander struct tee_ta_param *param;
8782061b8dSJens Wiklander TEE_ErrorOrigin err_origin;
889dde212dSEtienne Carriere bool cancel; /* True if TA invocation is cancelled */
890795afd0SJens Wiklander bool cancel_mask; /* True if cancel is masked */
909dde212dSEtienne Carriere TEE_Time cancel_time; /* Time when to cancel the TA invocation */
910795afd0SJens Wiklander uint32_t ref_count; /* reference counter */
920795afd0SJens Wiklander struct condvar refc_cv; /* CV used to wait for ref_count to be 0 */
930795afd0SJens Wiklander struct condvar lock_cv; /* CV used to wait for lock */
94f86aa9e1SJerome Forissier short int lock_thread; /* Id of thread holding the lock */
950795afd0SJens Wiklander bool unlink; /* True if session is to be unlinked */
960795afd0SJens Wiklander };
970795afd0SJens Wiklander
986fde6f02SJerome Forissier /* Registered contexts */
996fde6f02SJerome Forissier extern struct tee_ta_ctx_head tee_ctxes;
1006fde6f02SJerome Forissier
1016fde6f02SJerome Forissier extern struct mutex tee_ta_mutex;
102f0ab1c64SJens Wiklander extern struct condvar tee_ta_init_cv;
10388885202SJens Wiklander
104b0104773SPascal Brand TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err,
105b0104773SPascal Brand struct tee_ta_session **sess,
106b0104773SPascal Brand struct tee_ta_session_head *open_sessions,
107b0104773SPascal Brand const TEE_UUID *uuid,
108b0104773SPascal Brand const TEE_Identity *clnt_id,
109b0104773SPascal Brand uint32_t cancel_req_to,
110b0104773SPascal Brand struct tee_ta_param *param);
111b0104773SPascal Brand
112b0104773SPascal Brand TEE_Result tee_ta_invoke_command(TEE_ErrorOrigin *err,
113b0104773SPascal Brand struct tee_ta_session *sess,
11460699957SPascal Brand const TEE_Identity *clnt_id,
115b0104773SPascal Brand uint32_t cancel_req_to, uint32_t cmd,
116b0104773SPascal Brand struct tee_ta_param *param);
117b0104773SPascal Brand
118b0104773SPascal Brand TEE_Result tee_ta_cancel_command(TEE_ErrorOrigin *err,
11960699957SPascal Brand struct tee_ta_session *sess,
12060699957SPascal Brand const TEE_Identity *clnt_id);
121b0104773SPascal Brand
12263dc8d4aSJens Wiklander bool tee_ta_session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time);
12363dc8d4aSJens Wiklander
124b0104773SPascal Brand /*-----------------------------------------------------------------------------
125b0104773SPascal Brand * Function called to close a TA.
126b0104773SPascal Brand * Parameters:
127b0104773SPascal Brand * id - The session id (in)
128b0104773SPascal Brand * Returns:
129b0104773SPascal Brand * TEE_Result
130b0104773SPascal Brand *---------------------------------------------------------------------------*/
131096cbcddSJean-Michel Delorme TEE_Result tee_ta_close_session(struct tee_ta_session *sess,
13260699957SPascal Brand struct tee_ta_session_head *open_sessions,
13360699957SPascal Brand const TEE_Identity *clnt_id);
134b0104773SPascal Brand
135b0104773SPascal Brand
13670126febSJens Wiklander
13799164a05SJerome Forissier struct tee_ta_session *tee_ta_find_session(uint32_t id,
13899164a05SJerome Forissier struct tee_ta_session_head *open_sessions);
13999164a05SJerome Forissier
140b666b6f2SJens Wiklander struct tee_ta_session *tee_ta_get_session(uint32_t id, bool exclusive,
141b666b6f2SJens Wiklander struct tee_ta_session_head *open_sessions);
142b666b6f2SJens Wiklander
143b666b6f2SJens Wiklander void tee_ta_put_session(struct tee_ta_session *sess);
144b0104773SPascal Brand
1451df107b6SSumit Garg #if defined(CFG_TA_GPROF_SUPPORT)
146883c4be3SJerome Forissier void tee_ta_update_session_utime_suspend(void);
147883c4be3SJerome Forissier void tee_ta_update_session_utime_resume(void);
1481df107b6SSumit Garg void tee_ta_gprof_sample_pc(vaddr_t pc);
149883c4be3SJerome Forissier #else
tee_ta_update_session_utime_suspend(void)150883c4be3SJerome Forissier static inline void tee_ta_update_session_utime_suspend(void) {}
tee_ta_update_session_utime_resume(void)151883c4be3SJerome Forissier static inline void tee_ta_update_session_utime_resume(void) {}
tee_ta_gprof_sample_pc(vaddr_t pc __unused)152f5df167cSSumit Garg static inline void tee_ta_gprof_sample_pc(vaddr_t pc __unused) {}
153f5df167cSSumit Garg #endif
154099918f6SSumit Garg #if defined(CFG_FTRACE_SUPPORT)
1551df107b6SSumit Garg void tee_ta_ftrace_update_times_suspend(void);
1561df107b6SSumit Garg void tee_ta_ftrace_update_times_resume(void);
1571df107b6SSumit Garg #else
tee_ta_ftrace_update_times_suspend(void)1581df107b6SSumit Garg static inline void tee_ta_ftrace_update_times_suspend(void) {}
tee_ta_ftrace_update_times_resume(void)1591df107b6SSumit Garg static inline void tee_ta_ftrace_update_times_resume(void) {}
1601df107b6SSumit Garg #endif
161883c4be3SJerome Forissier
162ce332a51SJens Wiklander bool is_ta_ctx(struct ts_ctx *ctx);
163ce332a51SJens Wiklander
164521aacf1SEtienne Carriere struct tee_ta_session *to_ta_session(struct ts_session *sess);
16500b3b9a2SJens Wiklander
to_ta_ctx(struct ts_ctx * ctx)1660a75d408SJens Wiklander static inline struct tee_ta_ctx *__noprof to_ta_ctx(struct ts_ctx *ctx)
1673560d990SJens Wiklander {
168ce332a51SJens Wiklander assert(is_ta_ctx(ctx));
1693560d990SJens Wiklander return container_of(ctx, struct tee_ta_ctx, ts_ctx);
1703560d990SJens Wiklander }
171cb94c145SWeizhao Jiang
172cb94c145SWeizhao Jiang #if defined(CFG_TA_STATS)
173c11218ebSClement Faure TEE_Result tee_ta_instance_stats(void *buff, size_t *buff_size);
174cb94c145SWeizhao Jiang #endif
175cb94c145SWeizhao Jiang
176b0104773SPascal Brand #endif
177