blob: f8eb7c0fac833fcb749ba2ae9837275e5667f494 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
* Copyright (c) 2017, Linaro Limited
*/
#ifndef TEE_TA_MANAGER_H
#define TEE_TA_MANAGER_H
#include <kernel/mutex.h>
#include <kernel/tee_common.h>
#include <mm/tee_mmu_types.h>
#include <sys/queue.h>
#include <tee_api_types.h>
#include <tee_api_types.h>
#include <types_ext.h>
#include <user_ta_header.h>
#include <utee_types.h>
/* Magic TEE identity pointer: set when teecore requests a TA close */
#define KERN_IDENTITY ((TEE_Identity *)-1)
/* Operation is initiated by a client (non-secure) app */
#define NSAPP_IDENTITY (NULL)
TAILQ_HEAD(tee_ta_session_head, tee_ta_session);
TAILQ_HEAD(tee_ta_ctx_head, tee_ta_ctx);
struct mobj;
struct param_val {
uint32_t a;
uint32_t b;
};
struct param_mem {
struct mobj *mobj;
size_t size;
size_t offs;
};
struct tee_ta_param {
uint32_t types;
union {
struct param_val val;
struct param_mem mem;
} u[TEE_NUM_PARAMS];
};
struct tee_ta_ctx;
struct user_ta_ctx;
struct pseudo_ta_ctx;
struct thread_svc_regs;
struct tee_ta_ops {
TEE_Result (*enter_open_session)(struct tee_ta_session *s,
struct tee_ta_param *param, TEE_ErrorOrigin *eo);
TEE_Result (*enter_invoke_cmd)(struct tee_ta_session *s, uint32_t cmd,
struct tee_ta_param *param, TEE_ErrorOrigin *eo);
void (*enter_close_session)(struct tee_ta_session *s);
void (*dump_state)(struct tee_ta_ctx *ctx);
void (*dump_ftrace)(struct tee_ta_ctx *ctx);
void (*destroy)(struct tee_ta_ctx *ctx);
uint32_t (*get_instance_id)(struct tee_ta_ctx *ctx);
bool (*handle_svc)(struct thread_svc_regs *regs);
};
#if defined(CFG_TA_GPROF_SUPPORT)
struct sample_buf {
uint32_t nsamples; /* Size of @samples array in uint16_t */
uint32_t offset; /* Passed from user mode */
uint32_t scale; /* Passed from user mode */
uint32_t count; /* Number of samples taken */
bool enabled; /* Sampling enabled? */
uint16_t *samples;
uint64_t usr; /* Total user CPU time for this session */
uint64_t usr_entered; /* When this session last entered user mode */
uint32_t freq; /* @usr divided by @freq is in seconds */
};
#endif
/* Context of a loaded TA */
struct tee_ta_ctx {
TEE_UUID uuid;
const struct tee_ta_ops *ops;
uint32_t flags; /* TA_FLAGS from TA header */
TAILQ_ENTRY(tee_ta_ctx) link;
uint32_t panicked; /* True if TA has panicked, written from asm */
uint32_t panic_code; /* Code supplied for panic */
uint32_t ref_count; /* Reference counter for multi session TA */
bool busy; /* Context is busy and cannot be entered */
bool initializing; /* Context is initializing */
struct condvar busy_cv; /* CV used when context is busy */
};
struct tee_ta_session {
TAILQ_ENTRY(tee_ta_session) link;
TAILQ_ENTRY(tee_ta_session) link_tsd;
uint32_t id; /* Session handle (0 is invalid) */
struct tee_ta_ctx *ctx; /* TA context */
TEE_Identity clnt_id; /* Identify of client */
bool cancel; /* True if TA invocation is cancelled */
bool cancel_mask; /* True if cancel is masked */
TEE_Time cancel_time; /* Time when to cancel the TA invocation */
void *user_ctx; /* Opaque session handle assigned by PTA */
uint32_t ref_count; /* reference counter */
struct condvar refc_cv; /* CV used to wait for ref_count to be 0 */
struct condvar lock_cv; /* CV used to wait for lock */
int lock_thread; /* Id of thread holding the lock */
bool unlink; /* True if session is to be unlinked */
#if defined(CFG_TA_GPROF_SUPPORT)
struct sample_buf *sbuf; /* Profiling data (PC sampling) */
#endif
#if defined(CFG_FTRACE_SUPPORT)
struct ftrace_buf *fbuf; /* ftrace buffer */
#endif
};
/* Registered contexts */
extern struct tee_ta_ctx_head tee_ctxes;
extern struct mutex tee_ta_mutex;
TEE_Result tee_ta_open_session(TEE_ErrorOrigin *err,
struct tee_ta_session **sess,
struct tee_ta_session_head *open_sessions,
const TEE_UUID *uuid,
const TEE_Identity *clnt_id,
uint32_t cancel_req_to,
struct tee_ta_param *param);
TEE_Result tee_ta_invoke_command(TEE_ErrorOrigin *err,
struct tee_ta_session *sess,
const TEE_Identity *clnt_id,
uint32_t cancel_req_to, uint32_t cmd,
struct tee_ta_param *param);
TEE_Result tee_ta_cancel_command(TEE_ErrorOrigin *err,
struct tee_ta_session *sess,
const TEE_Identity *clnt_id);
bool tee_ta_session_is_cancelled(struct tee_ta_session *s, TEE_Time *curr_time);
/*-----------------------------------------------------------------------------
* Function called to close a TA.
* Parameters:
* id - The session id (in)
* Returns:
* TEE_Result
*---------------------------------------------------------------------------*/
TEE_Result tee_ta_close_session(struct tee_ta_session *sess,
struct tee_ta_session_head *open_sessions,
const TEE_Identity *clnt_id);
TEE_Result tee_ta_get_current_session(struct tee_ta_session **sess);
void tee_ta_push_current_session(struct tee_ta_session *sess);
struct tee_ta_session *tee_ta_pop_current_session(void);
struct tee_ta_session *tee_ta_get_calling_session(void);
struct tee_ta_session *tee_ta_find_session(uint32_t id,
struct tee_ta_session_head *open_sessions);
struct tee_ta_session *tee_ta_get_session(uint32_t id, bool exclusive,
struct tee_ta_session_head *open_sessions);
void tee_ta_put_session(struct tee_ta_session *sess);
#if defined(CFG_TA_GPROF_SUPPORT)
void tee_ta_update_session_utime_suspend(void);
void tee_ta_update_session_utime_resume(void);
void tee_ta_gprof_sample_pc(vaddr_t pc);
#else
static inline void tee_ta_update_session_utime_suspend(void) {}
static inline void tee_ta_update_session_utime_resume(void) {}
static inline void tee_ta_gprof_sample_pc(vaddr_t pc __unused) {}
#endif
#if defined(CFG_FTRACE_SUPPORT)
void tee_ta_ftrace_update_times_suspend(void);
void tee_ta_ftrace_update_times_resume(void);
#else
static inline void tee_ta_ftrace_update_times_suspend(void) {}
static inline void tee_ta_ftrace_update_times_resume(void) {}
#endif
#endif