131b31015Sliushiwei // SPDX-License-Identifier: BSD-2-Clause 231b31015Sliushiwei /* 331b31015Sliushiwei * Copyright (c) 2014, STMicroelectronics International N.V. 431b31015Sliushiwei * Copyright (c) 2022, Linaro Limited. 531b31015Sliushiwei */ 631b31015Sliushiwei #include <compiler.h> 731b31015Sliushiwei #include <link.h> 831b31015Sliushiwei #include <malloc.h> 931b31015Sliushiwei #include <memtag.h> 1031b31015Sliushiwei #include <stdbool.h> 1131b31015Sliushiwei #include <stdlib.h> 1231b31015Sliushiwei #include <string.h> 1331b31015Sliushiwei #include <sys/queue.h> 1431b31015Sliushiwei #include <tee_api.h> 1531b31015Sliushiwei #include <tee_arith_internal.h> 1631b31015Sliushiwei #include <tee_internal_api_extensions.h> 1731b31015Sliushiwei #include <tee_ta_api.h> 1831b31015Sliushiwei #include <user_ta_header.h> 1931b31015Sliushiwei #include <utee_syscalls.h> 2031b31015Sliushiwei #include "tee_api_private.h" 2131b31015Sliushiwei 2231b31015Sliushiwei struct ta_session { 2331b31015Sliushiwei uint32_t session_id; 2431b31015Sliushiwei void *session_ctx; 2531b31015Sliushiwei TAILQ_ENTRY(ta_session) link; 2631b31015Sliushiwei }; 2731b31015Sliushiwei 2831b31015Sliushiwei static TAILQ_HEAD(ta_sessions, ta_session) ta_sessions = 2931b31015Sliushiwei TAILQ_HEAD_INITIALIZER(ta_sessions); 3031b31015Sliushiwei 3131b31015Sliushiwei static bool init_done; 3231b31015Sliushiwei 3331b31015Sliushiwei /* From user_ta_header.c, built within TA */ 3431b31015Sliushiwei extern uint8_t ta_heap[]; 3531b31015Sliushiwei extern const size_t ta_heap_size; 3631b31015Sliushiwei extern struct ta_head ta_head; 3731b31015Sliushiwei 3831b31015Sliushiwei uint32_t ta_param_types; 3931b31015Sliushiwei TEE_Param ta_params[TEE_NUM_PARAMS]; 4031b31015Sliushiwei 4131b31015Sliushiwei struct malloc_ctx *__ta_no_share_malloc_ctx; 4231b31015Sliushiwei 4331b31015Sliushiwei struct __elf_phdr_info __elf_phdr_info; 4431b31015Sliushiwei 4531b31015Sliushiwei struct phdr_info { 4631b31015Sliushiwei struct dl_phdr_info info; 4731b31015Sliushiwei TAILQ_ENTRY(phdr_info) link; 4831b31015Sliushiwei }; 4931b31015Sliushiwei 5031b31015Sliushiwei static TAILQ_HEAD(phdr_info_head, phdr_info) __phdr_info_head = 5131b31015Sliushiwei TAILQ_HEAD_INITIALIZER(__phdr_info_head); 5231b31015Sliushiwei /* 5331b31015Sliushiwei * Keep track of how many modules have been initialized so that subsequent 5431b31015Sliushiwei * dlopen() calls will not run the same initializers again 5531b31015Sliushiwei */ 5631b31015Sliushiwei static size_t _num_mod_init; 5731b31015Sliushiwei 5831b31015Sliushiwei static int _init_iterate_phdr_cb(struct dl_phdr_info *info, 5931b31015Sliushiwei size_t size __unused, void *data) 6031b31015Sliushiwei { 6131b31015Sliushiwei struct phdr_info *qe = NULL; 6231b31015Sliushiwei size_t *count = data; 6331b31015Sliushiwei 6431b31015Sliushiwei qe = malloc(sizeof(*qe)); 6531b31015Sliushiwei if (!qe) { 6631b31015Sliushiwei EMSG("init/fini: out of memory"); 6731b31015Sliushiwei abort(); 6831b31015Sliushiwei } 6931b31015Sliushiwei qe->info = *info; 7031b31015Sliushiwei TAILQ_INSERT_TAIL(&__phdr_info_head, qe, link); 7131b31015Sliushiwei (*count)++; 7231b31015Sliushiwei return 0; 7331b31015Sliushiwei } 7431b31015Sliushiwei 7531b31015Sliushiwei static void _get_fn_array(struct dl_phdr_info *info, Elf_Sword tag_a, 7631b31015Sliushiwei Elf_Sword tag_s, void (***fn)(void), size_t *num_fn) 7731b31015Sliushiwei { 7831b31015Sliushiwei const Elf_Phdr *phdr = NULL; 7931b31015Sliushiwei Elf_Dyn *dyn = NULL; 8031b31015Sliushiwei size_t num_dyn = 0; 8131b31015Sliushiwei size_t i = 0; 8231b31015Sliushiwei size_t j = 0; 8331b31015Sliushiwei 8431b31015Sliushiwei for (i = 0; i < info->dlpi_phnum; i++) { 8531b31015Sliushiwei phdr = info->dlpi_phdr + i; 8631b31015Sliushiwei if (phdr->p_type != PT_DYNAMIC) 8731b31015Sliushiwei continue; 8831b31015Sliushiwei num_dyn = phdr->p_memsz / sizeof(Elf_Dyn); 8931b31015Sliushiwei dyn = (Elf_Dyn *)(phdr->p_vaddr + info->dlpi_addr); 9031b31015Sliushiwei for (j = 0; j < num_dyn; j++) { 9131b31015Sliushiwei if (*fn && *num_fn) 9231b31015Sliushiwei break; 9331b31015Sliushiwei if (dyn->d_tag == DT_NULL) { 9431b31015Sliushiwei break; 9531b31015Sliushiwei } else if (dyn->d_tag == tag_a) { 9631b31015Sliushiwei *fn = (void (**)(void))(dyn->d_un.d_ptr + 9731b31015Sliushiwei info->dlpi_addr); 9831b31015Sliushiwei } else if (dyn->d_tag == tag_s) { 9931b31015Sliushiwei *num_fn = dyn->d_un.d_val / sizeof(Elf_Addr); 10031b31015Sliushiwei } 10131b31015Sliushiwei dyn++; 10231b31015Sliushiwei } 10331b31015Sliushiwei } 10431b31015Sliushiwei } 10531b31015Sliushiwei 10631b31015Sliushiwei void __utee_call_elf_init_fn(void) 10731b31015Sliushiwei { 10831b31015Sliushiwei void (**fn)(void) = NULL; 10931b31015Sliushiwei size_t num_mod = 0; 11031b31015Sliushiwei size_t num_fn = 0; 11131b31015Sliushiwei size_t mod = 0; 11231b31015Sliushiwei size_t i = 0; 11331b31015Sliushiwei struct phdr_info *qe = NULL; 11431b31015Sliushiwei struct phdr_info *qe2 = NULL; 11531b31015Sliushiwei 11631b31015Sliushiwei dl_iterate_phdr(_init_iterate_phdr_cb, &num_mod); 11731b31015Sliushiwei 11831b31015Sliushiwei /* Reverse order: dependencies first */ 11931b31015Sliushiwei TAILQ_FOREACH_REVERSE(qe, &__phdr_info_head, phdr_info_head, link) { 12031b31015Sliushiwei if (mod == num_mod - _num_mod_init) 12131b31015Sliushiwei break; 12231b31015Sliushiwei _get_fn_array(&qe->info, DT_INIT_ARRAY, DT_INIT_ARRAYSZ, &fn, 12331b31015Sliushiwei &num_fn); 12431b31015Sliushiwei for (i = 0; i < num_fn; i++) 12531b31015Sliushiwei fn[i](); 12631b31015Sliushiwei fn = NULL; 12731b31015Sliushiwei num_fn = 0; 12831b31015Sliushiwei mod++; 12931b31015Sliushiwei } 13031b31015Sliushiwei _num_mod_init += mod; 13131b31015Sliushiwei 13231b31015Sliushiwei TAILQ_FOREACH_SAFE(qe, &__phdr_info_head, link, qe2) { 13331b31015Sliushiwei TAILQ_REMOVE(&__phdr_info_head, qe, link); 13431b31015Sliushiwei free(qe); 13531b31015Sliushiwei } 13631b31015Sliushiwei } 13731b31015Sliushiwei 13831b31015Sliushiwei static int _fini_iterate_phdr_cb(struct dl_phdr_info *info, 13931b31015Sliushiwei size_t size __unused, void *data __unused) 14031b31015Sliushiwei { 14131b31015Sliushiwei void (**fn)(void) = NULL; 14231b31015Sliushiwei size_t num_fn = 0; 14331b31015Sliushiwei size_t i = 0; 14431b31015Sliushiwei 14531b31015Sliushiwei _get_fn_array(info, DT_FINI_ARRAY, DT_FINI_ARRAYSZ, &fn, &num_fn); 14631b31015Sliushiwei 14731b31015Sliushiwei for (i = 1; i <= num_fn; i++) 14831b31015Sliushiwei fn[num_fn - i](); 14931b31015Sliushiwei 15031b31015Sliushiwei return 0; 15131b31015Sliushiwei } 15231b31015Sliushiwei 15331b31015Sliushiwei void __utee_call_elf_fini_fn(void) 15431b31015Sliushiwei { 15531b31015Sliushiwei dl_iterate_phdr(_fini_iterate_phdr_cb, NULL); 15631b31015Sliushiwei } 15731b31015Sliushiwei 15831b31015Sliushiwei static unsigned int get_memtag_implementation(void) 15931b31015Sliushiwei { 16031b31015Sliushiwei const char *s = "org.trustedfirmware.optee.cpu.feat_memtag_implemented"; 16131b31015Sliushiwei uint32_t v = 0; 16231b31015Sliushiwei 16331b31015Sliushiwei if (TEE_GetPropertyAsU32(TEE_PROPSET_TEE_IMPLEMENTATION, s, &v)) 16431b31015Sliushiwei return 0; 16531b31015Sliushiwei return v; 16631b31015Sliushiwei } 16731b31015Sliushiwei 16831b31015Sliushiwei static TEE_Result init_instance(void) 16931b31015Sliushiwei { 17031b31015Sliushiwei trace_set_level(tahead_get_trace_level()); 17131b31015Sliushiwei __utee_gprof_init(); 17231b31015Sliushiwei malloc_add_pool(ta_heap, ta_heap_size); 17331b31015Sliushiwei if (__ta_no_share_heap_size) { 17431b31015Sliushiwei __ta_no_share_malloc_ctx = malloc(raw_malloc_get_ctx_size()); 17531b31015Sliushiwei if (__ta_no_share_malloc_ctx) { 17631b31015Sliushiwei raw_malloc_init_ctx(__ta_no_share_malloc_ctx); 17731b31015Sliushiwei raw_malloc_add_pool(__ta_no_share_malloc_ctx, 17831b31015Sliushiwei __ta_no_share_heap, 17931b31015Sliushiwei __ta_no_share_heap_size); 18031b31015Sliushiwei } 18131b31015Sliushiwei } 18231b31015Sliushiwei memtag_init_ops(get_memtag_implementation()); 18331b31015Sliushiwei _TEE_MathAPI_Init(); 18431b31015Sliushiwei __utee_tcb_init(); 18531b31015Sliushiwei __utee_call_elf_init_fn(); 18631b31015Sliushiwei return TA_CreateEntryPoint(); 18731b31015Sliushiwei } 18831b31015Sliushiwei 18931b31015Sliushiwei static void uninit_instance(void) 19031b31015Sliushiwei { 19131b31015Sliushiwei __utee_gprof_fini(); 19231b31015Sliushiwei TA_DestroyEntryPoint(); 19331b31015Sliushiwei __utee_call_elf_fini_fn(); 19431b31015Sliushiwei } 19531b31015Sliushiwei 19631b31015Sliushiwei static void ta_header_save_params(uint32_t param_types, 19731b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS]) 19831b31015Sliushiwei { 19931b31015Sliushiwei ta_param_types = param_types; 20031b31015Sliushiwei 20131b31015Sliushiwei if (params) 20231b31015Sliushiwei memcpy(ta_params, params, sizeof(ta_params)); 20331b31015Sliushiwei else 20431b31015Sliushiwei memset(ta_params, 0, sizeof(ta_params)); 20531b31015Sliushiwei } 20631b31015Sliushiwei 20731b31015Sliushiwei static struct ta_session *ta_header_get_session(uint32_t session_id) 20831b31015Sliushiwei { 20931b31015Sliushiwei struct ta_session *itr; 21031b31015Sliushiwei 21131b31015Sliushiwei TAILQ_FOREACH(itr, &ta_sessions, link) { 21231b31015Sliushiwei if (itr->session_id == session_id) 21331b31015Sliushiwei return itr; 21431b31015Sliushiwei } 21531b31015Sliushiwei return NULL; 21631b31015Sliushiwei } 21731b31015Sliushiwei 21831b31015Sliushiwei static TEE_Result ta_header_add_session(uint32_t session_id) 21931b31015Sliushiwei { 22031b31015Sliushiwei struct ta_session *itr = ta_header_get_session(session_id); 22131b31015Sliushiwei TEE_Result res; 22231b31015Sliushiwei 22331b31015Sliushiwei if (itr) 22431b31015Sliushiwei return TEE_SUCCESS; 22531b31015Sliushiwei 22631b31015Sliushiwei if (!init_done) { 22731b31015Sliushiwei init_done = true; 22831b31015Sliushiwei res = init_instance(); 22931b31015Sliushiwei if (res) 23031b31015Sliushiwei return res; 23131b31015Sliushiwei } 23231b31015Sliushiwei 23331b31015Sliushiwei itr = TEE_Malloc(sizeof(struct ta_session), 23431b31015Sliushiwei TEE_USER_MEM_HINT_NO_FILL_ZERO); 23531b31015Sliushiwei if (!itr) 23631b31015Sliushiwei return TEE_ERROR_OUT_OF_MEMORY; 23731b31015Sliushiwei itr->session_id = session_id; 23831b31015Sliushiwei itr->session_ctx = 0; 23931b31015Sliushiwei TAILQ_INSERT_TAIL(&ta_sessions, itr, link); 24031b31015Sliushiwei 24131b31015Sliushiwei return TEE_SUCCESS; 24231b31015Sliushiwei } 24331b31015Sliushiwei 24431b31015Sliushiwei static void ta_header_remove_session(uint32_t session_id) 24531b31015Sliushiwei { 24631b31015Sliushiwei struct ta_session *itr; 24731b31015Sliushiwei bool keep_alive; 24831b31015Sliushiwei 24931b31015Sliushiwei TAILQ_FOREACH(itr, &ta_sessions, link) { 25031b31015Sliushiwei if (itr->session_id == session_id) { 25131b31015Sliushiwei TAILQ_REMOVE(&ta_sessions, itr, link); 25231b31015Sliushiwei TEE_Free(itr); 25331b31015Sliushiwei 25431b31015Sliushiwei keep_alive = 25531b31015Sliushiwei (ta_head.flags & TA_FLAG_SINGLE_INSTANCE) && 25631b31015Sliushiwei (ta_head.flags & TA_FLAG_INSTANCE_KEEP_ALIVE); 25731b31015Sliushiwei if (TAILQ_EMPTY(&ta_sessions) && !keep_alive) 25831b31015Sliushiwei uninit_instance(); 25931b31015Sliushiwei 26031b31015Sliushiwei return; 26131b31015Sliushiwei } 26231b31015Sliushiwei } 26331b31015Sliushiwei } 26431b31015Sliushiwei 26531b31015Sliushiwei static void to_utee_params(struct utee_params *up, uint32_t param_types, 26631b31015Sliushiwei const TEE_Param params[TEE_NUM_PARAMS]) 26731b31015Sliushiwei { 26831b31015Sliushiwei size_t n = 0; 26931b31015Sliushiwei 27031b31015Sliushiwei up->types = param_types; 27131b31015Sliushiwei for (n = 0; n < TEE_NUM_PARAMS; n++) { 27231b31015Sliushiwei switch (TEE_PARAM_TYPE_GET(param_types, n)) { 27331b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_INPUT: 27431b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_OUTPUT: 27531b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_INOUT: 27631b31015Sliushiwei up->vals[n * 2] = params[n].value.a; 27731b31015Sliushiwei up->vals[n * 2 + 1] = params[n].value.b; 27831b31015Sliushiwei break; 27931b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_INPUT: 28031b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_OUTPUT: 28131b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_INOUT: 28231b31015Sliushiwei up->vals[n * 2] = (uintptr_t)params[n].memref.buffer; 28331b31015Sliushiwei up->vals[n * 2 + 1] = params[n].memref.size; 28431b31015Sliushiwei break; 28531b31015Sliushiwei default: 28631b31015Sliushiwei up->vals[n * 2] = 0; 28731b31015Sliushiwei up->vals[n * 2 + 1] = 0; 28831b31015Sliushiwei break; 28931b31015Sliushiwei } 29031b31015Sliushiwei } 29131b31015Sliushiwei } 29231b31015Sliushiwei 29331b31015Sliushiwei static void from_utee_params(TEE_Param params[TEE_NUM_PARAMS], 29431b31015Sliushiwei uint32_t *param_types, 29531b31015Sliushiwei const struct utee_params *up) 29631b31015Sliushiwei { 29731b31015Sliushiwei size_t n; 29831b31015Sliushiwei uint32_t types = up->types; 29931b31015Sliushiwei 30031b31015Sliushiwei for (n = 0; n < TEE_NUM_PARAMS; n++) { 30131b31015Sliushiwei uintptr_t a = up->vals[n * 2]; 30231b31015Sliushiwei uintptr_t b = up->vals[n * 2 + 1]; 30331b31015Sliushiwei 30431b31015Sliushiwei switch (TEE_PARAM_TYPE_GET(types, n)) { 30531b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_INPUT: 30631b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_OUTPUT: 30731b31015Sliushiwei case TEE_PARAM_TYPE_VALUE_INOUT: 30831b31015Sliushiwei params[n].value.a = a; 30931b31015Sliushiwei params[n].value.b = b; 31031b31015Sliushiwei break; 31131b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_INPUT: 31231b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_OUTPUT: 31331b31015Sliushiwei case TEE_PARAM_TYPE_MEMREF_INOUT: 31431b31015Sliushiwei params[n].memref.buffer = (void *)a; 31531b31015Sliushiwei params[n].memref.size = b; 31631b31015Sliushiwei break; 31731b31015Sliushiwei default: 31831b31015Sliushiwei break; 31931b31015Sliushiwei } 32031b31015Sliushiwei } 32131b31015Sliushiwei 32231b31015Sliushiwei if (param_types) 32331b31015Sliushiwei *param_types = types; 32431b31015Sliushiwei } 32531b31015Sliushiwei 32631b31015Sliushiwei static TEE_Result entry_open_session(unsigned long session_id, 32731b31015Sliushiwei struct utee_params *up) 32831b31015Sliushiwei { 32931b31015Sliushiwei TEE_Result res; 33031b31015Sliushiwei struct ta_session *session; 33131b31015Sliushiwei uint32_t param_types; 33231b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS]; 33331b31015Sliushiwei 33431b31015Sliushiwei res = ta_header_add_session(session_id); 33531b31015Sliushiwei if (res != TEE_SUCCESS) 33631b31015Sliushiwei return res; 33731b31015Sliushiwei 33831b31015Sliushiwei session = ta_header_get_session(session_id); 33931b31015Sliushiwei if (!session) 34031b31015Sliushiwei return TEE_ERROR_BAD_STATE; 34131b31015Sliushiwei 34231b31015Sliushiwei from_utee_params(params, ¶m_types, up); 34331b31015Sliushiwei ta_header_save_params(param_types, params); 34431b31015Sliushiwei 34531b31015Sliushiwei res = TA_OpenSessionEntryPoint(param_types, params, 34631b31015Sliushiwei &session->session_ctx); 34731b31015Sliushiwei 34831b31015Sliushiwei to_utee_params(up, param_types, params); 34931b31015Sliushiwei 35031b31015Sliushiwei if (res != TEE_SUCCESS) 35131b31015Sliushiwei ta_header_remove_session(session_id); 35231b31015Sliushiwei return res; 35331b31015Sliushiwei } 35431b31015Sliushiwei 35531b31015Sliushiwei static TEE_Result entry_close_session(unsigned long session_id) 35631b31015Sliushiwei { 35731b31015Sliushiwei struct ta_session *session = ta_header_get_session(session_id); 35831b31015Sliushiwei 35931b31015Sliushiwei if (!session) 36031b31015Sliushiwei return TEE_ERROR_BAD_STATE; 36131b31015Sliushiwei 36231b31015Sliushiwei TA_CloseSessionEntryPoint(session->session_ctx); 36331b31015Sliushiwei 36431b31015Sliushiwei ta_header_remove_session(session_id); 36531b31015Sliushiwei return TEE_SUCCESS; 36631b31015Sliushiwei } 36731b31015Sliushiwei 36831b31015Sliushiwei static TEE_Result entry_invoke_command(unsigned long session_id, 36931b31015Sliushiwei struct utee_params *up, unsigned long cmd_id) 37031b31015Sliushiwei { 37131b31015Sliushiwei TEE_Result res; 37231b31015Sliushiwei uint32_t param_types; 37331b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS]; 37431b31015Sliushiwei struct ta_session *session = ta_header_get_session(session_id); 37531b31015Sliushiwei 37631b31015Sliushiwei if (!session) 37731b31015Sliushiwei return TEE_ERROR_BAD_STATE; 37831b31015Sliushiwei 37931b31015Sliushiwei from_utee_params(params, ¶m_types, up); 38031b31015Sliushiwei ta_header_save_params(param_types, params); 38131b31015Sliushiwei 38231b31015Sliushiwei res = TA_InvokeCommandEntryPoint(session->session_ctx, cmd_id, 38331b31015Sliushiwei param_types, params); 38431b31015Sliushiwei 38531b31015Sliushiwei to_utee_params(up, param_types, params); 38631b31015Sliushiwei return res; 38731b31015Sliushiwei } 38831b31015Sliushiwei 38931b31015Sliushiwei #if defined(CFG_TA_STATS) 39031b31015Sliushiwei static TEE_Result entry_dump_memstats(unsigned long session_id __unused, 39131b31015Sliushiwei struct utee_params *up) 39231b31015Sliushiwei { 39331b31015Sliushiwei uint32_t param_types = 0; 39431b31015Sliushiwei TEE_Param params[TEE_NUM_PARAMS] = { }; 395*2617f49fSEtienne Carriere struct pta_stats_alloc stats = { }; 39631b31015Sliushiwei 39731b31015Sliushiwei from_utee_params(params, ¶m_types, up); 39831b31015Sliushiwei ta_header_save_params(param_types, params); 39931b31015Sliushiwei 40031b31015Sliushiwei if (TEE_PARAM_TYPES(TEE_PARAM_TYPE_VALUE_OUTPUT, 40131b31015Sliushiwei TEE_PARAM_TYPE_VALUE_OUTPUT, 40231b31015Sliushiwei TEE_PARAM_TYPE_VALUE_OUTPUT, 40331b31015Sliushiwei TEE_PARAM_TYPE_NONE) != param_types) 40431b31015Sliushiwei return TEE_ERROR_BAD_PARAMETERS; 40531b31015Sliushiwei 40631b31015Sliushiwei malloc_get_stats(&stats); 40731b31015Sliushiwei params[0].value.a = stats.allocated; 40831b31015Sliushiwei params[0].value.b = stats.max_allocated; 40931b31015Sliushiwei params[1].value.a = stats.size; 41031b31015Sliushiwei params[1].value.b = stats.num_alloc_fail; 41131b31015Sliushiwei params[2].value.a = stats.biggest_alloc_fail; 41231b31015Sliushiwei params[2].value.b = stats.biggest_alloc_fail_used; 41331b31015Sliushiwei to_utee_params(up, param_types, params); 41431b31015Sliushiwei 41531b31015Sliushiwei return TEE_SUCCESS; 41631b31015Sliushiwei } 41731b31015Sliushiwei #endif 41831b31015Sliushiwei 41931b31015Sliushiwei TEE_Result __utee_entry(unsigned long func, unsigned long session_id, 42031b31015Sliushiwei struct utee_params *up, unsigned long cmd_id) 42131b31015Sliushiwei { 42231b31015Sliushiwei TEE_Result res; 42331b31015Sliushiwei 42431b31015Sliushiwei switch (func) { 42531b31015Sliushiwei case UTEE_ENTRY_FUNC_OPEN_SESSION: 42631b31015Sliushiwei res = entry_open_session(session_id, up); 42731b31015Sliushiwei break; 42831b31015Sliushiwei case UTEE_ENTRY_FUNC_CLOSE_SESSION: 42931b31015Sliushiwei res = entry_close_session(session_id); 43031b31015Sliushiwei break; 43131b31015Sliushiwei case UTEE_ENTRY_FUNC_INVOKE_COMMAND: 43231b31015Sliushiwei res = entry_invoke_command(session_id, up, cmd_id); 43331b31015Sliushiwei break; 43431b31015Sliushiwei #if defined(CFG_TA_STATS) 43531b31015Sliushiwei case UTEE_ENTRY_FUNC_DUMP_MEMSTATS: 43631b31015Sliushiwei res = entry_dump_memstats(session_id, up); 43731b31015Sliushiwei break; 43831b31015Sliushiwei #endif 43931b31015Sliushiwei default: 44031b31015Sliushiwei res = TEE_ERROR_NOT_SUPPORTED; 44131b31015Sliushiwei break; 44231b31015Sliushiwei } 44331b31015Sliushiwei ta_header_save_params(0, NULL); 44431b31015Sliushiwei 44531b31015Sliushiwei return res; 44631b31015Sliushiwei } 447