mirror of
https://github.com/openharmony/tee_tee_os_framework.git
synced 2026-07-01 07:22:28 -04:00
Modify tab to four spaces
Signed-off-by: suwanghw <wangsu14@huawei.com>
This commit is contained in:
@@ -41,7 +41,7 @@ int32_t drv_mutex_init(pthread_mutex_t *mtx)
|
||||
tloge("pthread mutex init failed with ret:%d\n", ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct fd_node *alloc_and_init_fd_node(void)
|
||||
|
||||
@@ -213,7 +213,7 @@ static void *tee_task_entry_thread(void *data)
|
||||
pti->t_msghdl = msghdl;
|
||||
|
||||
/* store msghdl in self tls */
|
||||
if(ipc_save_my_msghdl(msghdl) != 0) {
|
||||
if(ipc_save_my_msghdl(msghdl) != 0) {
|
||||
tloge("save hdl error");
|
||||
goto err_save_hdl;
|
||||
}
|
||||
|
||||
@@ -205,7 +205,7 @@ static uint32_t get_gtask_and_ssa_handle(uint32_t *global_handle, uint32_t *ss_a
|
||||
{
|
||||
uint32_t global_taskid;
|
||||
|
||||
if (global_handle == NULL || ss_agent_handle == NULL)
|
||||
if (global_handle == NULL || ss_agent_handle == NULL)
|
||||
return OS_ERROR;
|
||||
|
||||
if (ipc_hunt_by_name(GLOBAL_SERVICE_NAME, &global_taskid) != 0) {
|
||||
|
||||
@@ -100,7 +100,7 @@ TEE_Result tee_obj_free(TEE_ObjectHandle *object)
|
||||
TEE_Result tee_obj_init(void)
|
||||
{
|
||||
(void)pthread_mutex_init(&g_object_mutex, NULL);
|
||||
dlist_init(&g_object_head);
|
||||
dlist_init(&g_object_head);
|
||||
dlist_init(&g_enum_obj_info_list);
|
||||
return TEE_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include <teed_private.h>
|
||||
|
||||
void teed_init_tee_ep_state(struct entry_point_info *tee_entry_point,
|
||||
uint32_t rw,
|
||||
uintptr_t pc,
|
||||
tee_context_t *tee_ctx);
|
||||
uint32_t rw,
|
||||
uintptr_t pc,
|
||||
tee_context_t *tee_ctx);
|
||||
|
||||
uint64_t teed_synchronous_sp_entry(tee_context_t *tee_ctx);
|
||||
|
||||
|
||||
@@ -31,17 +31,17 @@
|
||||
#define get_tee_pstate(state) (((state) >> TEE_PSTATE_SHIFT) & TEE_PSTATE_MASK)
|
||||
|
||||
#define clr_tee_pstate(state) \
|
||||
do { \
|
||||
((state) &= ~(TEE_PSTATE_MASK << \
|
||||
TEE_PSTATE_SHIFT)); \
|
||||
} while (0)
|
||||
do { \
|
||||
((state) &= ~(TEE_PSTATE_MASK << \
|
||||
TEE_PSTATE_SHIFT)); \
|
||||
} while (0)
|
||||
|
||||
#define set_tee_pstate(st, pst) \
|
||||
do { \
|
||||
clr_tee_pstate(st); \
|
||||
(st) |= ((pst) & TEE_PSTATE_MASK) << \
|
||||
TEE_PSTATE_SHIFT; \
|
||||
} while (0)
|
||||
do { \
|
||||
clr_tee_pstate(st); \
|
||||
(st) |= ((pst) & TEE_PSTATE_MASK) << \
|
||||
TEE_PSTATE_SHIFT; \
|
||||
} while (0)
|
||||
|
||||
/* smc id added for TEE */
|
||||
#define TEE_STD_REE_SIQ 0xb200000a
|
||||
@@ -78,21 +78,21 @@
|
||||
#define SMC_INACTIVE 0
|
||||
#define SMC_ACTIVE 1
|
||||
#define get_yield_smc_active_flag(state) \
|
||||
(((state) >> YIELD_SMC_ACTIVE_FLAG_SHIFT) \
|
||||
& YIELD_SMC_ACTIVE_FLAG_MASK)
|
||||
(((state) >> YIELD_SMC_ACTIVE_FLAG_SHIFT) \
|
||||
& YIELD_SMC_ACTIVE_FLAG_MASK)
|
||||
|
||||
#define set_yield_smc_active_flag(state) \
|
||||
do { \
|
||||
((state) |= \
|
||||
1u << YIELD_SMC_ACTIVE_FLAG_SHIFT); \
|
||||
} while (0)
|
||||
do { \
|
||||
((state) |= \
|
||||
1u << YIELD_SMC_ACTIVE_FLAG_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
#define clr_yield_smc_active_flag(state) \
|
||||
do { \
|
||||
((state) &= \
|
||||
~(YIELD_SMC_ACTIVE_FLAG_MASK \
|
||||
<< YIELD_SMC_ACTIVE_FLAG_SHIFT)); \
|
||||
} while (0)
|
||||
do { \
|
||||
((state) &= \
|
||||
~(YIELD_SMC_ACTIVE_FLAG_MASK \
|
||||
<< YIELD_SMC_ACTIVE_FLAG_SHIFT)); \
|
||||
} while (0)
|
||||
/*
|
||||
* This flag is used by the TEED to determine if the TEE has crashed in any way
|
||||
* and it is impossible to continue. The flag will disable forwarding any calls
|
||||
@@ -108,36 +108,36 @@
|
||||
#define STD_SMC_CRASH_FLAG_SHIFT 0x3u
|
||||
#define STD_SMC_CRASH_FLAG_MASK 0x1u
|
||||
#define get_std_crash_flag(state) \
|
||||
(((state) >> STD_SMC_CRASH_FLAG_SHIFT) & \
|
||||
STD_SMC_CRASH_FLAG_MASK)
|
||||
(((state) >> STD_SMC_CRASH_FLAG_SHIFT) & \
|
||||
STD_SMC_CRASH_FLAG_MASK)
|
||||
|
||||
#define set_std_crash_flag(state) \
|
||||
do { \
|
||||
((state) |= \
|
||||
1 << STD_SMC_CRASH_FLAG_SHIFT); \
|
||||
} while (0)
|
||||
do { \
|
||||
((state) |= \
|
||||
1 << STD_SMC_CRASH_FLAG_SHIFT); \
|
||||
} while (0)
|
||||
|
||||
/* Secure Payload execution state information i.e. aarch32 or aarch64 */
|
||||
#define TEE_AARCH32 MODE_RW_32
|
||||
#define TEE_AARCH64 MODE_RW_64
|
||||
#define TEE_AARCH32 MODE_RW_32
|
||||
#define TEE_AARCH64 MODE_RW_64
|
||||
|
||||
/* The SPD should know the type of Secure Payload */
|
||||
#define TEE_TYPE_UP PSCI_TOS_NOT_UP_MIG_CAP
|
||||
#define TEE_TYPE_UP PSCI_TOS_NOT_UP_MIG_CAP
|
||||
#define TEE_TYPE_UPM PSCI_TOS_UP_MIG_CAP
|
||||
#define TEE_TYPE_MP PSCI_TOS_NOT_PRESENT_MP
|
||||
#define TEE_TYPE_MP PSCI_TOS_NOT_PRESENT_MP
|
||||
|
||||
/*
|
||||
* Secure Payload migrate type information as known to the SPD. We assume that
|
||||
* the SPD is dealing with an MP Secure Payload.
|
||||
*/
|
||||
#define TEE_MIGRATE_INFO TEE_TYPE_MP
|
||||
#define TEE_MIGRATE_INFO TEE_TYPE_MP
|
||||
|
||||
/*
|
||||
* Number of cpus that the present on this platform. Rely on a topology
|
||||
* tree to determine this in the future to avoid assumptions about mpidr
|
||||
* allocation
|
||||
*/
|
||||
#define TEED_CORE_COUNT PLATFORM_CORE_COUNT
|
||||
#define TEED_CORE_COUNT PLATFORM_CORE_COUNT
|
||||
|
||||
/*
|
||||
* Constants that allow assembler code to preserve callee-saved registers of the
|
||||
@@ -205,7 +205,7 @@ DEFINE_REG_STRUCT(c_rt_regs, TEED_C_RT_CTX_ENTRIES);
|
||||
* register context.
|
||||
*/
|
||||
CASSERT(TEED_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \
|
||||
assert_spd_c_rt_regs_size_mismatch);
|
||||
assert_spd_c_rt_regs_size_mismatch);
|
||||
|
||||
/* SEL1 Secure payload (SP) caller saved register context structure. */
|
||||
DEFINE_REG_STRUCT(sp_ctx_regs, TEED_SP_CTX_ENTRIES);
|
||||
@@ -216,7 +216,7 @@ DEFINE_REG_STRUCT(sp_ctx_regs, TEED_SP_CTX_ENTRIES);
|
||||
* register context.
|
||||
*/
|
||||
CASSERT(TEED_SP_CTX_SIZE == sizeof(sp_ctx_regs_t), \
|
||||
assert_spd_sp_regs_size_mismatch);
|
||||
assert_spd_sp_regs_size_mismatch);
|
||||
|
||||
/*
|
||||
* Structure which helps the SPD to maintain the per-cpu state of the SP.
|
||||
@@ -237,50 +237,50 @@ CASSERT(TEED_SP_CTX_SIZE == sizeof(sp_ctx_regs_t), \
|
||||
* to SP.
|
||||
*/
|
||||
typedef struct tee_context {
|
||||
uint64_t elr_el3;
|
||||
uint32_t spsr_el3;
|
||||
uint32_t state;
|
||||
uint64_t mpidr;
|
||||
uint64_t rt_context;
|
||||
cpu_context_t cpu_context;
|
||||
uint64_t saved_tee_args[TEE_NUM_ARGS];
|
||||
uint64_t elr_el3;
|
||||
uint32_t spsr_el3;
|
||||
uint32_t state;
|
||||
uint64_t mpidr;
|
||||
uint64_t rt_context;
|
||||
cpu_context_t cpu_context;
|
||||
uint64_t saved_tee_args[TEE_NUM_ARGS];
|
||||
} tee_context_t;
|
||||
|
||||
typedef struct tee_vectors {
|
||||
uint32_t yield_smc_entry;
|
||||
uint32_t fast_smc_entry;
|
||||
uint32_t cpu_on_entry;
|
||||
uint32_t cpu_off_entry;
|
||||
uint32_t cpu_resume_entry;
|
||||
uint32_t cpu_suspend_entry;
|
||||
uint32_t sel1_intr_entry;
|
||||
uint32_t irq_return_entry;
|
||||
uint32_t s4_resume_entry;
|
||||
uint32_t s4_suspend_entry;
|
||||
uint32_t system_off_entry;
|
||||
uint32_t system_reset_entry;
|
||||
uint32_t abort_yield_smc_entry;
|
||||
uint32_t yield_smc_entry;
|
||||
uint32_t fast_smc_entry;
|
||||
uint32_t cpu_on_entry;
|
||||
uint32_t cpu_off_entry;
|
||||
uint32_t cpu_resume_entry;
|
||||
uint32_t cpu_suspend_entry;
|
||||
uint32_t sel1_intr_entry;
|
||||
uint32_t irq_return_entry;
|
||||
uint32_t s4_resume_entry;
|
||||
uint32_t s4_suspend_entry;
|
||||
uint32_t system_off_entry;
|
||||
uint32_t system_reset_entry;
|
||||
uint32_t abort_yield_smc_entry;
|
||||
} tee_vectors_t;
|
||||
|
||||
typedef struct smc_registers {
|
||||
u_register_t x1;
|
||||
u_register_t x2;
|
||||
u_register_t x3;
|
||||
u_register_t x4;
|
||||
u_register_t x1;
|
||||
u_register_t x2;
|
||||
u_register_t x3;
|
||||
u_register_t x4;
|
||||
} smc_registers_t;
|
||||
|
||||
/* Helper macros to store and retrieve tee args from tee_context */
|
||||
#define store_tee_args(_tee_ctx, _x1, _x2) \
|
||||
do { \
|
||||
(_tee_ctx)->saved_tee_args[0] = _x1; \
|
||||
(_tee_ctx)->saved_tee_args[1] = _x2; \
|
||||
} while (0)
|
||||
do { \
|
||||
(_tee_ctx)->saved_tee_args[0] = _x1; \
|
||||
(_tee_ctx)->saved_tee_args[1] = _x2; \
|
||||
} while (0)
|
||||
|
||||
#define get_tee_args(_tee_ctx, _x1, _x2) \
|
||||
do { \
|
||||
_x1 = (_tee_ctx)->saved_tee_args[0]; \
|
||||
_x2 = (_tee_ctx)->saved_tee_args[1]; \
|
||||
} while (0)
|
||||
do { \
|
||||
_x1 = (_tee_ctx)->saved_tee_args[0]; \
|
||||
_x2 = (_tee_ctx)->saved_tee_args[1]; \
|
||||
} while (0)
|
||||
|
||||
/* TEED power management handlers */
|
||||
const spd_pm_ops_t *get_teed_pm(void);
|
||||
|
||||
@@ -24,47 +24,47 @@
|
||||
* initialize tee context and entry point info for the secure payload
|
||||
*/
|
||||
void teed_init_tee_ep_state(struct entry_point_info *ep,
|
||||
uint32_t rw,
|
||||
uintptr_t pc,
|
||||
tee_context_t *tee_ctx)
|
||||
uint32_t rw,
|
||||
uintptr_t pc,
|
||||
tee_context_t *tee_ctx)
|
||||
{
|
||||
uint32_t ep_attr;
|
||||
uint32_t ee;
|
||||
uint32_t daif;
|
||||
/* Passing a NULL context is a critical programming error */
|
||||
assert(tee_ctx != NULL);
|
||||
assert(ep != NULL);
|
||||
assert(pc != INVALID_PC_ADDR);
|
||||
uint32_t ep_attr;
|
||||
uint32_t ee;
|
||||
uint32_t daif;
|
||||
/* Passing a NULL context is a critical programming error */
|
||||
assert(tee_ctx != NULL);
|
||||
assert(ep != NULL);
|
||||
assert(pc != INVALID_PC_ADDR);
|
||||
|
||||
/*
|
||||
* We support AArch64 TEE for now.
|
||||
* Associate this context with the cpu specified
|
||||
*/
|
||||
ee = (uint32_t)SPSR_E_LITTLE;
|
||||
tee_ctx->mpidr = read_mpidr_el1();
|
||||
tee_ctx->state = (uint32_t)TEE_PSTATE_OFF;
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_OFF);
|
||||
clr_yield_smc_active_flag(tee_ctx->state);
|
||||
/*
|
||||
* We support AArch64 TEE for now.
|
||||
* Associate this context with the cpu specified
|
||||
*/
|
||||
ee = (uint32_t)SPSR_E_LITTLE;
|
||||
tee_ctx->mpidr = read_mpidr_el1();
|
||||
tee_ctx->state = (uint32_t)TEE_PSTATE_OFF;
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_OFF);
|
||||
clr_yield_smc_active_flag(tee_ctx->state);
|
||||
|
||||
cm_set_context(&tee_ctx->cpu_context, SECURE);
|
||||
cm_set_context(&tee_ctx->cpu_context, SECURE);
|
||||
|
||||
/* initialise an entrypoint to set up the CPU context */
|
||||
ep_attr = SECURE | EP_ST_ENABLE;
|
||||
bool ee_bit_flag = (read_sctlr_el3() & SCTLR_EE_BIT) == 0 ? false : true;
|
||||
if (ee_bit_flag) {
|
||||
ep_attr |= EP_EE_BIG;
|
||||
ee = SPSR_E_BIG;
|
||||
}
|
||||
SET_PARAM_HEAD(ep, PARAM_EP, VERSION_1, ep_attr);
|
||||
ep->pc = pc;
|
||||
if (rw == TEE_AARCH64) {
|
||||
ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
|
||||
ep->spsr = SPSR_MODE32(MODE32_svc, pc & SPSR_T_MASK, ee, daif);
|
||||
}
|
||||
/* initialise an entrypoint to set up the CPU context */
|
||||
ep_attr = SECURE | EP_ST_ENABLE;
|
||||
bool ee_bit_flag = (read_sctlr_el3() & SCTLR_EE_BIT) == 0 ? false : true;
|
||||
if (ee_bit_flag) {
|
||||
ep_attr |= EP_EE_BIG;
|
||||
ee = SPSR_E_BIG;
|
||||
}
|
||||
SET_PARAM_HEAD(ep, PARAM_EP, VERSION_1, ep_attr);
|
||||
ep->pc = pc;
|
||||
if (rw == TEE_AARCH64) {
|
||||
ep->spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS);
|
||||
} else {
|
||||
daif = DAIF_ABT_BIT | DAIF_IRQ_BIT | DAIF_FIQ_BIT;
|
||||
ep->spsr = SPSR_MODE32(MODE32_svc, pc & SPSR_T_MASK, ee, daif);
|
||||
}
|
||||
|
||||
memset(&ep->args, 0, sizeof(ep->args));
|
||||
memset(&ep->args, 0, sizeof(ep->args));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -77,21 +77,21 @@ void teed_init_tee_ep_state(struct entry_point_info *ep,
|
||||
*/
|
||||
uint64_t teed_synchronous_sp_entry(tee_context_t *tee_ctx)
|
||||
{
|
||||
uint64_t rc;
|
||||
assert(tee_ctx != NULL);
|
||||
assert(tee_ctx->rt_context == INVALID_C_RT_CTX);
|
||||
uint64_t rc;
|
||||
assert(tee_ctx != NULL);
|
||||
assert(tee_ctx->rt_context == INVALID_C_RT_CTX);
|
||||
|
||||
/* Apply the Secure EL1 system register context and switch to it */
|
||||
assert(cm_get_context(SECURE) == &tee_ctx->cpu_context);
|
||||
/* Apply the Secure EL1 system register context and switch to it */
|
||||
assert(cm_get_context(SECURE) == &tee_ctx->cpu_context);
|
||||
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
cm_set_next_eret_context(SECURE);
|
||||
rc = teed_enter_sp(&tee_ctx->rt_context);
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
cm_set_next_eret_context(SECURE);
|
||||
rc = teed_enter_sp(&tee_ctx->rt_context);
|
||||
#if ENABLE_ASSERTIONS
|
||||
tee_ctx->rt_context = INVALID_C_RT_CTX;
|
||||
tee_ctx->rt_context = INVALID_C_RT_CTX;
|
||||
#endif
|
||||
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -104,20 +104,20 @@ uint64_t teed_synchronous_sp_entry(tee_context_t *tee_ctx)
|
||||
*/
|
||||
void teed_synchronous_sp_exit(const tee_context_t *tee_ctx, uint64_t ret)
|
||||
{
|
||||
assert(tee_ctx != NULL);
|
||||
/* Save the Secure EL1 system register context */
|
||||
assert(cm_get_context(SECURE) == &tee_ctx->cpu_context);
|
||||
cm_el1_sysregs_context_save(SECURE);
|
||||
int64_t init_context_saved = get_tee_init_context_saved();
|
||||
assert(tee_ctx != NULL);
|
||||
/* Save the Secure EL1 system register context */
|
||||
assert(cm_get_context(SECURE) == &tee_ctx->cpu_context);
|
||||
cm_el1_sysregs_context_save(SECURE);
|
||||
int64_t init_context_saved = get_tee_init_context_saved();
|
||||
|
||||
tee_context_t *tee_context_tmp = get_teed_sp_init_context();
|
||||
assert(tee_context_tmp != NULL);
|
||||
if (init_context_saved == INIT_CONTEXT_NOT_SAVED) {
|
||||
memcpy(tee_context_tmp, tee_ctx, sizeof(*tee_context_tmp));
|
||||
set_tee_init_context_saved(INIT_CONTEXT_SAVED);
|
||||
}
|
||||
assert(tee_ctx->rt_context != INVALID_C_RT_CTX);
|
||||
teed_exit_sp(tee_ctx->rt_context, ret);
|
||||
printf("sp exit: Should never reach here\n");
|
||||
assert(0);
|
||||
tee_context_t *tee_context_tmp = get_teed_sp_init_context();
|
||||
assert(tee_context_tmp != NULL);
|
||||
if (init_context_saved == INIT_CONTEXT_NOT_SAVED) {
|
||||
memcpy(tee_context_tmp, tee_ctx, sizeof(*tee_context_tmp));
|
||||
set_tee_init_context_saved(INIT_CONTEXT_SAVED);
|
||||
}
|
||||
assert(tee_ctx->rt_context != INVALID_C_RT_CTX);
|
||||
teed_exit_sp(tee_ctx->rt_context, ret);
|
||||
printf("sp exit: Should never reach here\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
@@ -26,53 +26,53 @@ tee_vectors_t *g_tee_vectors = NULL;
|
||||
|
||||
tee_context_t *get_teed_sp_context(const uint32_t linear_id)
|
||||
{
|
||||
if (linear_id >= TEED_CORE_COUNT)
|
||||
return NULL;
|
||||
if (linear_id >= TEED_CORE_COUNT)
|
||||
return NULL;
|
||||
|
||||
return &g_teed_sp_context[linear_id];
|
||||
return &g_teed_sp_context[linear_id];
|
||||
}
|
||||
|
||||
uint64_t get_teed_sp_context_size(void)
|
||||
{
|
||||
return sizeof(g_teed_sp_context);
|
||||
return sizeof(g_teed_sp_context);
|
||||
}
|
||||
|
||||
tee_context_t *get_teed_sp_context_ptr(void)
|
||||
{
|
||||
return g_teed_sp_context;
|
||||
return g_teed_sp_context;
|
||||
}
|
||||
|
||||
tee_context_t *get_teed_sp_init_context(void)
|
||||
{
|
||||
return &g_teed_sp_init_context;
|
||||
return &g_teed_sp_init_context;
|
||||
}
|
||||
|
||||
int64_t get_tee_init_context_saved(void)
|
||||
{
|
||||
return g_tee_init_context_saved;
|
||||
return g_tee_init_context_saved;
|
||||
}
|
||||
|
||||
void set_tee_init_context_saved(const int64_t tee_init_context_saved)
|
||||
{
|
||||
g_tee_init_context_saved = tee_init_context_saved;
|
||||
g_tee_init_context_saved = tee_init_context_saved;
|
||||
}
|
||||
|
||||
uint64_t get_primary_cpu_mpidr(void)
|
||||
{
|
||||
return g_primary_cpu_mpidr;
|
||||
return g_primary_cpu_mpidr;
|
||||
}
|
||||
|
||||
void set_primary_cpu_mpidr(const uint64_t primary_cpu_mpidr_in)
|
||||
{
|
||||
g_primary_cpu_mpidr = primary_cpu_mpidr_in;
|
||||
g_primary_cpu_mpidr = primary_cpu_mpidr_in;
|
||||
}
|
||||
|
||||
tee_vectors_t *get_tee_vectors_t(void)
|
||||
{
|
||||
return g_tee_vectors;
|
||||
return g_tee_vectors;
|
||||
}
|
||||
|
||||
void set_tee_vectors_t(tee_vectors_t *const tee_vectors_tmp)
|
||||
{
|
||||
g_tee_vectors = tee_vectors_tmp;
|
||||
g_tee_vectors = tee_vectors_tmp;
|
||||
}
|
||||
|
||||
@@ -16,49 +16,49 @@
|
||||
|
||||
#include <teed_private.h>
|
||||
|
||||
.global teed_enter_sp
|
||||
.global teed_enter_sp
|
||||
func teed_enter_sp
|
||||
/* Make space for the registers that we're going to save */
|
||||
mov x3, sp
|
||||
str x3, [x0, #0]
|
||||
sub sp, sp, #TEED_C_RT_CTX_SIZE
|
||||
/* Make space for the registers that we're going to save */
|
||||
mov x3, sp
|
||||
str x3, [x0, #0]
|
||||
sub sp, sp, #TEED_C_RT_CTX_SIZE
|
||||
|
||||
/* Save callee-saved registers on to the stack */
|
||||
stp x19, x20, [sp, #TEED_C_RT_CTX_X19]
|
||||
stp x21, x22, [sp, #TEED_C_RT_CTX_X21]
|
||||
stp x23, x24, [sp, #TEED_C_RT_CTX_X23]
|
||||
stp x25, x26, [sp, #TEED_C_RT_CTX_X25]
|
||||
stp x27, x28, [sp, #TEED_C_RT_CTX_X27]
|
||||
stp x29, x30, [sp, #TEED_C_RT_CTX_X29]
|
||||
/* Save callee-saved registers on to the stack */
|
||||
stp x19, x20, [sp, #TEED_C_RT_CTX_X19]
|
||||
stp x21, x22, [sp, #TEED_C_RT_CTX_X21]
|
||||
stp x23, x24, [sp, #TEED_C_RT_CTX_X23]
|
||||
stp x25, x26, [sp, #TEED_C_RT_CTX_X25]
|
||||
stp x27, x28, [sp, #TEED_C_RT_CTX_X27]
|
||||
stp x29, x30, [sp, #TEED_C_RT_CTX_X29]
|
||||
|
||||
/*
|
||||
* el3_exit() will use the secure context to restore to the
|
||||
* general purpose and EL3 system registers to ERET into the secure payload
|
||||
*/
|
||||
b el3_exit
|
||||
/*
|
||||
* el3_exit() will use the secure context to restore to the
|
||||
* general purpose and EL3 system registers to ERET into the secure payload
|
||||
*/
|
||||
b el3_exit
|
||||
endfunc teed_enter_sp
|
||||
|
||||
/*
|
||||
* This function is called 'x0' pointing to a C
|
||||
* runtime context saved in teed_enter_sp()
|
||||
*/
|
||||
.global teed_exit_sp
|
||||
/*
|
||||
* This function is called 'x0' pointing to a C
|
||||
* runtime context saved in teed_enter_sp()
|
||||
*/
|
||||
.global teed_exit_sp
|
||||
func teed_exit_sp
|
||||
/* Restore the previous stack */
|
||||
mov sp, x0
|
||||
/* Restore the previous stack */
|
||||
mov sp, x0
|
||||
|
||||
/* Restore callee-saved registers on to the stack */
|
||||
ldp x19, x20, [x0, #(TEED_C_RT_CTX_X19 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x21, x22, [x0, #(TEED_C_RT_CTX_X21 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x23, x24, [x0, #(TEED_C_RT_CTX_X23 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x25, x26, [x0, #(TEED_C_RT_CTX_X25 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x27, x28, [x0, #(TEED_C_RT_CTX_X27 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x29, x30, [x0, #(TEED_C_RT_CTX_X29 - TEED_C_RT_CTX_SIZE)]
|
||||
/* Restore callee-saved registers on to the stack */
|
||||
ldp x19, x20, [x0, #(TEED_C_RT_CTX_X19 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x21, x22, [x0, #(TEED_C_RT_CTX_X21 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x23, x24, [x0, #(TEED_C_RT_CTX_X23 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x25, x26, [x0, #(TEED_C_RT_CTX_X25 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x27, x28, [x0, #(TEED_C_RT_CTX_X27 - TEED_C_RT_CTX_SIZE)]
|
||||
ldp x29, x30, [x0, #(TEED_C_RT_CTX_X29 - TEED_C_RT_CTX_SIZE)]
|
||||
|
||||
/*
|
||||
* This should take us back to the instruction
|
||||
* after the call to the last teed_enter_sp().
|
||||
*/
|
||||
mov x0, x1
|
||||
ret
|
||||
/*
|
||||
* This should take us back to the instruction
|
||||
* after the call to the last teed_enter_sp().
|
||||
*/
|
||||
mov x0, x1
|
||||
ret
|
||||
endfunc teed_exit_sp
|
||||
|
||||
+369
-369
@@ -29,60 +29,60 @@
|
||||
* at 'tee_sel1_intr_entry()' for handling the interrupt.
|
||||
*/
|
||||
static uint64_t teed_sel1_interrupt_handler(uint32_t id,
|
||||
uint32_t flags,
|
||||
void *handle,
|
||||
void *cookie)
|
||||
uint32_t flags,
|
||||
void *handle,
|
||||
void *cookie)
|
||||
{
|
||||
uint32_t linear_id;
|
||||
tee_context_t *tee_ctx = NULL;
|
||||
uint32_t linear_id;
|
||||
tee_context_t *tee_ctx = NULL;
|
||||
|
||||
/* Check the security state when the exception was generated */
|
||||
assert(get_interrupt_src_ss(flags) == NON_SECURE);
|
||||
/* Check the security state when the exception was generated */
|
||||
assert(get_interrupt_src_ss(flags) == NON_SECURE);
|
||||
|
||||
/* Sanity check the pointer to this cpu's context */
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
/* Sanity check the pointer to this cpu's context */
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
|
||||
/* Save the non-secure context before entering the TEE */
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
/* Save the non-secure context before entering the TEE */
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
|
||||
/* Get a reference to this cpu's TEE context */
|
||||
linear_id = plat_my_core_pos();
|
||||
tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
/* Get a reference to this cpu's TEE context */
|
||||
linear_id = plat_my_core_pos();
|
||||
tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
|
||||
/*
|
||||
* Determine if the tee was previously preempted. Its last known
|
||||
* context has to be preserved in this case.
|
||||
* The tee should return control to the teeD after handling
|
||||
* this S-EL1 interrupt. Preserve essential EL3 context to allow entry
|
||||
* into the tee at the S-EL1 interrupt entry point using the
|
||||
* 'cpu_context' structure. There is no need to save the secure system
|
||||
* register context since the tee is supposed to preserve it
|
||||
* during S-EL1 interrupt handling.
|
||||
*/
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) == SMC_ACTIVE) {
|
||||
tee_ctx->spsr_el3 = (uint32_t)SMC_GET_EL3(&tee_ctx->cpu_context, CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context, CTX_ELR_EL3);
|
||||
}
|
||||
/*
|
||||
* Determine if the tee was previously preempted. Its last known
|
||||
* context has to be preserved in this case.
|
||||
* The tee should return control to the teeD after handling
|
||||
* this S-EL1 interrupt. Preserve essential EL3 context to allow entry
|
||||
* into the tee at the S-EL1 interrupt entry point using the
|
||||
* 'cpu_context' structure. There is no need to save the secure system
|
||||
* register context since the tee is supposed to preserve it
|
||||
* during S-EL1 interrupt handling.
|
||||
*/
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) == SMC_ACTIVE) {
|
||||
tee_ctx->spsr_el3 = (uint32_t)SMC_GET_EL3(&tee_ctx->cpu_context, CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context, CTX_ELR_EL3);
|
||||
}
|
||||
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->sel1_intr_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->sel1_intr_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
|
||||
cm_set_next_eret_context(SECURE);
|
||||
/*
|
||||
* Tell the TEE that it has to handle a S-EL1 interrupt
|
||||
* synchronously. It is safe to retrieve
|
||||
* this address from ELR_EL3 as the secure context will not take effect
|
||||
* until el3_exit().
|
||||
*/
|
||||
SMC_RET2((uintptr_t)&tee_ctx->cpu_context,
|
||||
TEE_HANDLE_SEL1_INTR_AND_RETURN, read_elr_el3());
|
||||
cm_set_next_eret_context(SECURE);
|
||||
/*
|
||||
* Tell the TEE that it has to handle a S-EL1 interrupt
|
||||
* synchronously. It is safe to retrieve
|
||||
* this address from ELR_EL3 as the secure context will not take effect
|
||||
* until el3_exit().
|
||||
*/
|
||||
SMC_RET2((uintptr_t)&tee_ctx->cpu_context,
|
||||
TEE_HANDLE_SEL1_INTR_AND_RETURN, read_elr_el3());
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -96,42 +96,42 @@ static uint64_t teed_sel1_interrupt_handler(uint32_t id,
|
||||
*/
|
||||
static int32_t teed_init(void)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
entry_point_info_t *tee_entry_point = NULL;
|
||||
uint64_t rc;
|
||||
uint64_t mpidr = read_mpidr();
|
||||
/* set the primary cpu */
|
||||
set_primary_cpu_mpidr(mpidr);
|
||||
/*
|
||||
* Get information about the Secure Payload (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
*/
|
||||
tee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
cm_init_my_context(tee_entry_point);
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
entry_point_info_t *tee_entry_point = NULL;
|
||||
uint64_t rc;
|
||||
uint64_t mpidr = read_mpidr();
|
||||
/* set the primary cpu */
|
||||
set_primary_cpu_mpidr(mpidr);
|
||||
/*
|
||||
* Get information about the Secure Payload (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
*/
|
||||
tee_entry_point = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
cm_init_my_context(tee_entry_point);
|
||||
|
||||
#ifdef BOOT_BL32_FROM_OTHER_EXCEPTION
|
||||
/* set el3 fiq bit for tee init */
|
||||
cpu_context_t *ctx = NULL;
|
||||
el3_state_t *state = NULL;
|
||||
uint32_t scr_el3;
|
||||
ctx = cm_get_context(GET_SECURITY_STATE(tee_entry_point->h.attr));
|
||||
state = get_el3state_ctx(ctx);
|
||||
scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
|
||||
scr_el3 &= ~SCR_FIQ_BIT;
|
||||
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
||||
/* set el3 fiq bit for tee init */
|
||||
cpu_context_t *ctx = NULL;
|
||||
el3_state_t *state = NULL;
|
||||
uint32_t scr_el3;
|
||||
ctx = cm_get_context(GET_SECURITY_STATE(tee_entry_point->h.attr));
|
||||
state = get_el3state_ctx(ctx);
|
||||
scr_el3 = read_ctx_reg(state, CTX_SCR_EL3);
|
||||
scr_el3 &= ~SCR_FIQ_BIT;
|
||||
write_ctx_reg(state, CTX_SCR_EL3, scr_el3);
|
||||
|
||||
/* save nosecure context and disable interrupt during init */
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
/* save nosecure context and disable interrupt during init */
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
#endif
|
||||
/*
|
||||
* Arrange for an entry into the test secure payload. It will be
|
||||
* returned via TEE_ENTRY_DONE case
|
||||
*/
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
assert(rc != 0);
|
||||
return rc;
|
||||
/*
|
||||
* Arrange for an entry into the test secure payload. It will be
|
||||
* returned via TEE_ENTRY_DONE case
|
||||
*/
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
assert(rc != 0);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -141,49 +141,49 @@ static int32_t teed_init(void)
|
||||
*/
|
||||
static int32_t teed_setup(void)
|
||||
{
|
||||
entry_point_info_t *image_info = NULL;
|
||||
uint32_t linear_id;
|
||||
entry_point_info_t *image_info = NULL;
|
||||
uint32_t linear_id;
|
||||
|
||||
linear_id = plat_my_core_pos();
|
||||
NOTICE("teed setup start!\n");
|
||||
/*
|
||||
* Get information about the Secure Payload (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
* conditionally include the SPD service
|
||||
*/
|
||||
image_info = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
if (image_info == NULL) {
|
||||
WARN("No TEE provided by BL2 boot loader, Booting device"
|
||||
" without TEE initialization. SMC`s destined for TEE"
|
||||
" will return SMC_UNK\n");
|
||||
return TEE_SETUP_FAIL;
|
||||
}
|
||||
assert(image_info != NULL);
|
||||
/*
|
||||
* If there's no valid entry point for SP, we return a non-zero value
|
||||
* signalling failure initializing the service. We bail out without
|
||||
* registering any handlers
|
||||
*/
|
||||
if (image_info->pc == INVALID_PC_ADDR)
|
||||
return TEE_SETUP_FAIL;
|
||||
linear_id = plat_my_core_pos();
|
||||
NOTICE("teed setup start!\n");
|
||||
/*
|
||||
* Get information about the Secure Payload (BL32) image. Its
|
||||
* absence is a critical failure.
|
||||
* conditionally include the SPD service
|
||||
*/
|
||||
image_info = bl31_plat_get_next_image_ep_info(SECURE);
|
||||
if (image_info == NULL) {
|
||||
WARN("No TEE provided by BL2 boot loader, Booting device"
|
||||
" without TEE initialization. SMC`s destined for TEE"
|
||||
" will return SMC_UNK\n");
|
||||
return TEE_SETUP_FAIL;
|
||||
}
|
||||
assert(image_info != NULL);
|
||||
/*
|
||||
* If there's no valid entry point for SP, we return a non-zero value
|
||||
* signalling failure initializing the service. We bail out without
|
||||
* registering any handlers
|
||||
*/
|
||||
if (image_info->pc == INVALID_PC_ADDR)
|
||||
return TEE_SETUP_FAIL;
|
||||
|
||||
/*
|
||||
* We could inspect the SP image and determine its execution
|
||||
* state i.e whether AArch32 or AArch64. Assuming it's AArch64
|
||||
* for the time being.
|
||||
*/
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
teed_init_tee_ep_state(image_info,
|
||||
TEE_AARCH64,
|
||||
image_info->pc,
|
||||
tee_ctx);
|
||||
/*
|
||||
* We could inspect the SP image and determine its execution
|
||||
* state i.e whether AArch32 or AArch64. Assuming it's AArch64
|
||||
* for the time being.
|
||||
*/
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
teed_init_tee_ep_state(image_info,
|
||||
TEE_AARCH64,
|
||||
image_info->pc,
|
||||
tee_ctx);
|
||||
|
||||
/*
|
||||
* All TEED initialization done. Now register our init function
|
||||
* with BL31 for deferred invocation
|
||||
*/
|
||||
bl31_register_bl32_init(&teed_init);
|
||||
return 0;
|
||||
/*
|
||||
* All TEED initialization done. Now register our init function
|
||||
* with BL31 for deferred invocation
|
||||
*/
|
||||
bl31_register_bl32_init(&teed_init);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -195,40 +195,40 @@ static int32_t teed_setup(void)
|
||||
* TEE_HANDLED_S_EL1_FIQ_AARCH32:
|
||||
*/
|
||||
static uintptr_t smc_handle_s_el1(tee_context_t *tee_ctx,
|
||||
void *handle, uint32_t ns)
|
||||
void *handle, uint32_t ns)
|
||||
{
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
assert(tee_ctx != NULL);
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
/*
|
||||
* Restore the relevant EL3 state which saved to service
|
||||
* this SMC.
|
||||
*/
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
SMC_SET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3,
|
||||
tee_ctx->spsr_el3);
|
||||
SMC_SET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3,
|
||||
tee_ctx->elr_el3);
|
||||
}
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
assert(tee_ctx != NULL);
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
/*
|
||||
* Restore the relevant EL3 state which saved to service
|
||||
* this SMC.
|
||||
*/
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
SMC_SET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3,
|
||||
tee_ctx->spsr_el3);
|
||||
SMC_SET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3,
|
||||
tee_ctx->elr_el3);
|
||||
}
|
||||
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
|
||||
/*
|
||||
* Restore non-secure state. There is no need to save the
|
||||
* secure system register context since the tee was supposed
|
||||
* to preserve it during S-EL1 interrupt handling.
|
||||
*/
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET0((uintptr_t)ns_cpu_context);
|
||||
/*
|
||||
* Restore non-secure state. There is no need to save the
|
||||
* secure system register context since the tee was supposed
|
||||
* to preserve it during S-EL1 interrupt handling.
|
||||
*/
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET0((uintptr_t)ns_cpu_context);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -238,45 +238,45 @@ static uintptr_t smc_handle_s_el1(tee_context_t *tee_ctx,
|
||||
* TEE_ENTRY_DONE_AARCH32:
|
||||
*/
|
||||
static void smc_handle_entry_done(tee_context_t *tee_ctx,
|
||||
u_register_t x1, u_register_t *flags)
|
||||
u_register_t x1, u_register_t *flags)
|
||||
{
|
||||
/*
|
||||
* Stash the SP entry points information. This is done
|
||||
* only once on the primary cpu
|
||||
*/
|
||||
uint64_t rc;
|
||||
tee_vectors_t* tee_vectors_tmp = (tee_vectors_t *)(uintptr_t)x1;
|
||||
set_tee_vectors_t(tee_vectors_tmp);
|
||||
if (tee_vectors_tmp != NULL) {
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
/*
|
||||
* tee has been successfully initialized. Register
|
||||
* power managemnt hooks with PSCI
|
||||
*/
|
||||
const spd_pm_ops_t *teed_pm_tmp = get_teed_pm();
|
||||
psci_register_spd_pm_hook(teed_pm_tmp);
|
||||
/*
|
||||
* Stash the SP entry points information. This is done
|
||||
* only once on the primary cpu
|
||||
*/
|
||||
uint64_t rc;
|
||||
tee_vectors_t* tee_vectors_tmp = (tee_vectors_t *)(uintptr_t)x1;
|
||||
set_tee_vectors_t(tee_vectors_tmp);
|
||||
if (tee_vectors_tmp != NULL) {
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
/*
|
||||
* tee has been successfully initialized. Register
|
||||
* power managemnt hooks with PSCI
|
||||
*/
|
||||
const spd_pm_ops_t *teed_pm_tmp = get_teed_pm();
|
||||
psci_register_spd_pm_hook(teed_pm_tmp);
|
||||
|
||||
/*
|
||||
* Register an interrupt handler for S-EL1 interrupts
|
||||
* when generated during code executing in the
|
||||
* non-secure state.
|
||||
*/
|
||||
*flags = 0;
|
||||
set_interrupt_rm_flag(*flags, NON_SECURE);
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
|
||||
teed_sel1_interrupt_handler,
|
||||
*flags);
|
||||
if (rc != 0)
|
||||
panic();
|
||||
}
|
||||
/*
|
||||
* Register an interrupt handler for S-EL1 interrupts
|
||||
* when generated during code executing in the
|
||||
* non-secure state.
|
||||
*/
|
||||
*flags = 0;
|
||||
set_interrupt_rm_flag(*flags, NON_SECURE);
|
||||
rc = register_interrupt_type_handler(INTR_TYPE_S_EL1,
|
||||
teed_sel1_interrupt_handler,
|
||||
*flags);
|
||||
if (rc != 0)
|
||||
panic();
|
||||
}
|
||||
|
||||
/*
|
||||
* SP reports completion. The SPD must have initiated
|
||||
* the original request through a synchronous entry
|
||||
* into the SP. Jump back to the original C runtime
|
||||
* context.
|
||||
*/
|
||||
teed_synchronous_sp_exit(tee_ctx, x1);
|
||||
/*
|
||||
* SP reports completion. The SPD must have initiated
|
||||
* the original request through a synchronous entry
|
||||
* into the SP. Jump back to the original C runtime
|
||||
* context.
|
||||
*/
|
||||
teed_synchronous_sp_exit(tee_ctx, x1);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -309,138 +309,138 @@ static void smc_handle_entry_done(tee_context_t *tee_ctx,
|
||||
*/
|
||||
static void smc_handle_abort_on_resume(const tee_context_t *tee_ctx, u_register_t x1)
|
||||
{
|
||||
/*
|
||||
* SP reports completion. The SPD must have initiated the
|
||||
* original request through a synchronous entry into the SP.
|
||||
* Jump back to the original C runtime context, and pass x1 as
|
||||
* return value to the caller
|
||||
*/
|
||||
teed_synchronous_sp_exit(tee_ctx, x1);
|
||||
/*
|
||||
* SP reports completion. The SPD must have initiated the
|
||||
* original request through a synchronous entry into the SP.
|
||||
* Jump back to the original C runtime context, and pass x1 as
|
||||
* return value to the caller
|
||||
*/
|
||||
teed_synchronous_sp_exit(tee_ctx, x1);
|
||||
}
|
||||
|
||||
static uintptr_t smc_handle_std_request(tee_context_t *tee_ctx,
|
||||
smc_registers_t registers_t,
|
||||
const void *handle, uint32_t smc_fid,
|
||||
uint32_t ns)
|
||||
smc_registers_t registers_t,
|
||||
const void *handle, uint32_t smc_fid,
|
||||
uint32_t ns)
|
||||
{
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
/*
|
||||
* Restore the correct state considering if the
|
||||
* OS has been active.
|
||||
*/
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
cm_set_elr_spsr_el3(SECURE,
|
||||
(uintptr_t)&tee_vectors_tmp->irq_return_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
} else {
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->yield_smc_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
}
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
/*
|
||||
* Restore the correct state considering if the
|
||||
* OS has been active.
|
||||
*/
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
cm_set_elr_spsr_el3(SECURE,
|
||||
(uintptr_t)&tee_vectors_tmp->irq_return_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
} else {
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->yield_smc_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
}
|
||||
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
cm_set_next_eret_context(SECURE);
|
||||
cm_el1_sysregs_context_restore(SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
cm_set_next_eret_context(SECURE);
|
||||
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
SMC_RET0((uintptr_t)&tee_ctx->cpu_context);
|
||||
} else {
|
||||
set_yield_smc_active_flag(tee_ctx->state);
|
||||
SMC_RET5((uintptr_t)&tee_ctx->cpu_context, smc_fid, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3, registers_t.x4);
|
||||
}
|
||||
if (get_yield_smc_active_flag(tee_ctx->state) != SMC_INACTIVE) {
|
||||
SMC_RET0((uintptr_t)&tee_ctx->cpu_context);
|
||||
} else {
|
||||
set_yield_smc_active_flag(tee_ctx->state);
|
||||
SMC_RET5((uintptr_t)&tee_ctx->cpu_context, smc_fid, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3, registers_t.x4);
|
||||
}
|
||||
}
|
||||
|
||||
static uintptr_t smc_handle_std_ree_siq(uint32_t smc_fid,
|
||||
tee_context_t *tee_ctx,
|
||||
u_register_t x1, void *handle,
|
||||
uint32_t ns)
|
||||
tee_context_t *tee_ctx,
|
||||
u_register_t x1, void *handle,
|
||||
uint32_t ns)
|
||||
{
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
assert(handle == cm_get_context(NON_SECURE));
|
||||
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_el1_sysregs_context_save(NON_SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
assert(&tee_ctx->cpu_context == cm_get_context(SECURE));
|
||||
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
cm_set_elr_spsr_el3(SECURE,
|
||||
(uintptr_t)&tee_vectors_tmp->fast_smc_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
cm_set_elr_spsr_el3(SECURE,
|
||||
(uintptr_t)&tee_vectors_tmp->fast_smc_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context), CTX_GPREG_X1, x1);
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET1((uintptr_t)handle, smc_fid);
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context), CTX_GPREG_X1, x1);
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET1((uintptr_t)handle, smc_fid);
|
||||
}
|
||||
|
||||
static uintptr_t smc_handle_std_response(uint32_t smc_fid,
|
||||
tee_context_t *tee_ctx,
|
||||
smc_registers_t registers_t,
|
||||
const void *handle, uint32_t ns)
|
||||
tee_context_t *tee_ctx,
|
||||
smc_registers_t registers_t,
|
||||
const void *handle, uint32_t ns)
|
||||
{
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
/* Forward secure responses to NS */
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
/* Forward secure responses to NS */
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
cm_el1_sysregs_context_save(SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
cm_el1_sysregs_context_save(SECURE);
|
||||
fpregs_context_save(get_fpregs_ctx(cm_get_context(SECURE)));
|
||||
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
clr_yield_smc_active_flag(tee_ctx->state);
|
||||
SMC_RET4((uintptr_t)ns_cpu_context, smc_fid, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3);
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
clr_yield_smc_active_flag(tee_ctx->state);
|
||||
SMC_RET4((uintptr_t)ns_cpu_context, smc_fid, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3);
|
||||
}
|
||||
|
||||
static uintptr_t smc_handle_std_crash(tee_context_t *tee_ctx,
|
||||
smc_registers_t registers_t, const void *handle,
|
||||
uint32_t ns)
|
||||
smc_registers_t registers_t, const void *handle,
|
||||
uint32_t ns)
|
||||
{
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
NOTICE("notify teeos has crashed\n");
|
||||
/* Secure OS has crashed, set the flag and return to ns */
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
NOTICE("notify teeos has crashed\n");
|
||||
/* Secure OS has crashed, set the flag and return to ns */
|
||||
cpu_context_t *ns_cpu_context = NULL;
|
||||
assert(handle == cm_get_context(SECURE));
|
||||
|
||||
set_std_crash_flag(tee_ctx->state);
|
||||
set_std_crash_flag(tee_ctx->state);
|
||||
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
/* Get a reference to the non-secure context */
|
||||
ns_cpu_context = cm_get_context(NON_SECURE);
|
||||
assert(ns_cpu_context != NULL);
|
||||
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET4((uintptr_t)ns_cpu_context, TEE_STD_CRASH, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3);
|
||||
/* Restore non-secure state */
|
||||
cm_el1_sysregs_context_restore(NON_SECURE);
|
||||
fpregs_context_restore(get_fpregs_ctx(cm_get_context(NON_SECURE)));
|
||||
cm_set_next_eret_context(NON_SECURE);
|
||||
SMC_RET4((uintptr_t)ns_cpu_context, TEE_STD_CRASH, registers_t.x1,
|
||||
registers_t.x2, registers_t.x3);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -453,98 +453,98 @@ static uintptr_t smc_handle_std_crash(tee_context_t *tee_ctx,
|
||||
*/
|
||||
|
||||
static uintptr_t teed_smc_handler(uint32_t smc_fid, u_register_t x1,
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4, void *cookie,
|
||||
void *handle, u_register_t flags)
|
||||
u_register_t x2, u_register_t x3,
|
||||
u_register_t x4, void *cookie,
|
||||
void *handle, u_register_t flags)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
/* Determine which security state this SMC originated from */
|
||||
uint32_t ns = is_caller_non_secure(flags);
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
smc_registers_t registers_t = { x1, x2, x3, x4 };
|
||||
/*
|
||||
* For calls comming from non-secure side after the OS signals
|
||||
* it has crashed just return to NS side, no more forwarding
|
||||
*/
|
||||
assert(tee_ctx != NULL);
|
||||
if (ns != SECURE_WORLD_FLAG &&
|
||||
get_std_crash_flag(tee_ctx->state) != STD_NO_CRASH_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, TEE_STD_CRASH);
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
/* Determine which security state this SMC originated from */
|
||||
uint32_t ns = is_caller_non_secure(flags);
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
smc_registers_t registers_t = { x1, x2, x3, x4 };
|
||||
/*
|
||||
* For calls comming from non-secure side after the OS signals
|
||||
* it has crashed just return to NS side, no more forwarding
|
||||
*/
|
||||
assert(tee_ctx != NULL);
|
||||
if (ns != SECURE_WORLD_FLAG &&
|
||||
get_std_crash_flag(tee_ctx->state) != STD_NO_CRASH_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, TEE_STD_CRASH);
|
||||
|
||||
switch (smc_fid) {
|
||||
/*
|
||||
* This function ID is used only by the tee to indicate that it has
|
||||
* finished handling a S-EL1 interrupt or was preempted by a higher
|
||||
* priority pending EL3 interrupt. Execution should resume
|
||||
* in the normal world.
|
||||
*/
|
||||
case TEE_HANDLED_S_EL1_INTR:
|
||||
case TEE_HANDLED_S_EL1_FIQ_AARCH32:
|
||||
return smc_handle_s_el1(tee_ctx, handle, ns);
|
||||
/*
|
||||
* This function ID is used only by the SP to indicate it has
|
||||
* finished initialising itself after a cold boot
|
||||
*/
|
||||
case TEE_ENTRY_DONE:
|
||||
case TEE_ENTRY_DONE_AARCH32:
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
smc_handle_entry_done(tee_ctx, x1, &flags);
|
||||
break;
|
||||
/*
|
||||
* This function ID is used only by the SP to indicate it has finished
|
||||
* aborting a preempted Yielding SMC Call.
|
||||
*/
|
||||
case TEE_ABORT_DONE:
|
||||
case TEE_ON_DONE:
|
||||
case TEE_ON_DONE_AARCH32:
|
||||
case TEE_RESUME_DONE:
|
||||
case TEE_RESUME_DONE_AARCH32:
|
||||
/*
|
||||
* These function IDs are used only by the SP to indicate it has
|
||||
* finished:
|
||||
* 1. suspending itself after an earlier psci cpu_suspend
|
||||
* request.
|
||||
* 2. turning itself off in response to an earlier psci
|
||||
* cpu_off request.
|
||||
*/
|
||||
case TEE_SUSPEND_DONE:
|
||||
case TEE_SUSPEND_DONE_AARCH32:
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
switch (smc_fid) {
|
||||
/*
|
||||
* This function ID is used only by the tee to indicate that it has
|
||||
* finished handling a S-EL1 interrupt or was preempted by a higher
|
||||
* priority pending EL3 interrupt. Execution should resume
|
||||
* in the normal world.
|
||||
*/
|
||||
case TEE_HANDLED_S_EL1_INTR:
|
||||
case TEE_HANDLED_S_EL1_FIQ_AARCH32:
|
||||
return smc_handle_s_el1(tee_ctx, handle, ns);
|
||||
/*
|
||||
* This function ID is used only by the SP to indicate it has
|
||||
* finished initialising itself after a cold boot
|
||||
*/
|
||||
case TEE_ENTRY_DONE:
|
||||
case TEE_ENTRY_DONE_AARCH32:
|
||||
if (ns == SECURE_WORLD_FLAG)
|
||||
smc_handle_entry_done(tee_ctx, x1, &flags);
|
||||
break;
|
||||
/*
|
||||
* This function ID is used only by the SP to indicate it has finished
|
||||
* aborting a preempted Yielding SMC Call.
|
||||
*/
|
||||
case TEE_ABORT_DONE:
|
||||
case TEE_ON_DONE:
|
||||
case TEE_ON_DONE_AARCH32:
|
||||
case TEE_RESUME_DONE:
|
||||
case TEE_RESUME_DONE_AARCH32:
|
||||
/*
|
||||
* These function IDs are used only by the SP to indicate it has
|
||||
* finished:
|
||||
* 1. suspending itself after an earlier psci cpu_suspend
|
||||
* request.
|
||||
* 2. turning itself off in response to an earlier psci
|
||||
* cpu_off request.
|
||||
*/
|
||||
case TEE_SUSPEND_DONE:
|
||||
case TEE_SUSPEND_DONE_AARCH32:
|
||||
if (ns != SECURE_WORLD_FLAG)
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
|
||||
smc_handle_abort_on_resume(tee_ctx, x1);
|
||||
break;
|
||||
case TEE_STD_REQUEST:
|
||||
return smc_handle_std_request(tee_ctx, registers_t, handle, smc_fid, ns);
|
||||
case TEE_STD_REE_SIQ:
|
||||
return smc_handle_std_ree_siq(smc_fid, tee_ctx, x1, handle, ns);
|
||||
case TEE_STD_RESPONSE:
|
||||
return smc_handle_std_response(smc_fid, tee_ctx, registers_t, handle, ns);
|
||||
case TEE_STD_CRASH:
|
||||
return smc_handle_std_crash(tee_ctx, registers_t, handle, ns);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
smc_handle_abort_on_resume(tee_ctx, x1);
|
||||
break;
|
||||
case TEE_STD_REQUEST:
|
||||
return smc_handle_std_request(tee_ctx, registers_t, handle, smc_fid, ns);
|
||||
case TEE_STD_REE_SIQ:
|
||||
return smc_handle_std_ree_siq(smc_fid, tee_ctx, x1, handle, ns);
|
||||
case TEE_STD_RESPONSE:
|
||||
return smc_handle_std_response(smc_fid, tee_ctx, registers_t, handle, ns);
|
||||
case TEE_STD_CRASH:
|
||||
return smc_handle_std_crash(tee_ctx, registers_t, handle, ns);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
SMC_RET1((uintptr_t)handle, SMC_UNK);
|
||||
}
|
||||
|
||||
/* Define a SPD runtime service descriptor for fast SMC calls */
|
||||
DECLARE_RT_SVC(
|
||||
teed_fast,
|
||||
OEN_TOS_START,
|
||||
OEN_TOS_END,
|
||||
SMC_TYPE_FAST,
|
||||
teed_setup,
|
||||
teed_smc_handler
|
||||
teed_fast,
|
||||
OEN_TOS_START,
|
||||
OEN_TOS_END,
|
||||
SMC_TYPE_FAST,
|
||||
teed_setup,
|
||||
teed_smc_handler
|
||||
);
|
||||
|
||||
/* Define a SPD runtime service descriptor for Yielding SMC Calls */
|
||||
DECLARE_RT_SVC(
|
||||
teed_std,
|
||||
OEN_TOS_START,
|
||||
OEN_TOS_END,
|
||||
SMC_TYPE_YIELD,
|
||||
NULL,
|
||||
teed_smc_handler
|
||||
teed_std,
|
||||
OEN_TOS_START,
|
||||
OEN_TOS_END,
|
||||
SMC_TYPE_YIELD,
|
||||
NULL,
|
||||
teed_smc_handler
|
||||
);
|
||||
|
||||
+165
-165
@@ -45,17 +45,17 @@ static void teed_cpu_on_handler(u_register_t target_cpu)
|
||||
*/
|
||||
static int32_t teed_cpu_off_handler(u_register_t unused)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
*/
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_OFF);
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
*/
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_OFF);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -64,44 +64,44 @@ static int32_t teed_cpu_off_handler(u_register_t unused)
|
||||
*/
|
||||
static void teed_cpu_suspend_handler(u_register_t max_off_pwrlvl)
|
||||
{
|
||||
int32_t rc;
|
||||
uint64_t power_state;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
int32_t rc;
|
||||
uint64_t power_state;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
(void)max_off_pwrlvl;
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
*/
|
||||
if (is_system_suspend() != 0)
|
||||
power_state = CPU_IDLE_STATE; /* stand for cpu idle */
|
||||
else
|
||||
power_state = CPU_SUSPEND_STATE; /* stand for cpu suspend */
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
(void)max_off_pwrlvl;
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
*/
|
||||
if (is_system_suspend() != 0)
|
||||
power_state = CPU_IDLE_STATE; /* stand for cpu idle */
|
||||
else
|
||||
power_state = CPU_SUSPEND_STATE; /* stand for cpu suspend */
|
||||
|
||||
/* Program the entry point and enter the TEE */
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context),
|
||||
CTX_GPREG_X0,
|
||||
power_state);
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->cpu_suspend_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the TEE.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the TEE is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_SUSPEND);
|
||||
/* Program the entry point and enter the TEE */
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context),
|
||||
CTX_GPREG_X0,
|
||||
power_state);
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->cpu_suspend_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the TEE.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the TEE is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_SUSPEND);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -112,50 +112,50 @@ static void teed_cpu_suspend_handler(u_register_t max_off_pwrlvl)
|
||||
*/
|
||||
static void teed_cpu_on_finish_handler(u_register_t unused)
|
||||
{
|
||||
int32_t rc;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
entry_point_info_t tee_on_entrypoint;
|
||||
el3_state_t *state = NULL;
|
||||
int32_t rc;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
entry_point_info_t tee_on_entrypoint;
|
||||
el3_state_t *state = NULL;
|
||||
|
||||
tee_vectors_t *tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_OFF);
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
tee_vectors_t *tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_OFF);
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
|
||||
uint64_t mpidr = read_mpidr();
|
||||
uint64_t primary_cpu_mpidr_tmp = get_primary_cpu_mpidr();
|
||||
if (linear_id >= TEED_CORE_COUNT)
|
||||
return;
|
||||
uint64_t mpidr = read_mpidr();
|
||||
uint64_t primary_cpu_mpidr_tmp = get_primary_cpu_mpidr();
|
||||
if (linear_id >= TEED_CORE_COUNT)
|
||||
return;
|
||||
|
||||
bool condition = (g_cpu_initialized[linear_id] == CPU_INIT_DONE ||
|
||||
mpidr == primary_cpu_mpidr_tmp);
|
||||
if (!condition) {
|
||||
tee_context_t *teed_sp_init_context = get_teed_sp_init_context();
|
||||
assert(teed_sp_init_context != NULL);
|
||||
(void)memcpy(&tee_ctx->cpu_context, &(teed_sp_init_context->cpu_context), sizeof(cpu_context_t));
|
||||
(void)memset(&tee_on_entrypoint, 0, sizeof(tee_on_entrypoint));
|
||||
/* Initialise this cpu's secure context */
|
||||
teed_init_tee_ep_state(&tee_on_entrypoint,
|
||||
TEE_AARCH64,
|
||||
(uintptr_t)&tee_vectors_tmp->cpu_on_entry,
|
||||
tee_ctx);
|
||||
state = get_el3state_ctx(&tee_ctx->cpu_context);
|
||||
write_ctx_reg(state, CTX_ELR_EL3, tee_on_entrypoint.pc);
|
||||
write_ctx_reg(state, CTX_SPSR_EL3, tee_on_entrypoint.spsr);
|
||||
}
|
||||
/* Enter the TEE */
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
g_cpu_initialized[linear_id] = CPU_INIT_DONE;
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the SP.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the SP is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
bool condition = (g_cpu_initialized[linear_id] == CPU_INIT_DONE ||
|
||||
mpidr == primary_cpu_mpidr_tmp);
|
||||
if (!condition) {
|
||||
tee_context_t *teed_sp_init_context = get_teed_sp_init_context();
|
||||
assert(teed_sp_init_context != NULL);
|
||||
(void)memcpy(&tee_ctx->cpu_context, &(teed_sp_init_context->cpu_context), sizeof(cpu_context_t));
|
||||
(void)memset(&tee_on_entrypoint, 0, sizeof(tee_on_entrypoint));
|
||||
/* Initialise this cpu's secure context */
|
||||
teed_init_tee_ep_state(&tee_on_entrypoint,
|
||||
TEE_AARCH64,
|
||||
(uintptr_t)&tee_vectors_tmp->cpu_on_entry,
|
||||
tee_ctx);
|
||||
state = get_el3state_ctx(&tee_ctx->cpu_context);
|
||||
write_ctx_reg(state, CTX_ELR_EL3, tee_on_entrypoint.pc);
|
||||
write_ctx_reg(state, CTX_SPSR_EL3, tee_on_entrypoint.spsr);
|
||||
}
|
||||
/* Enter the TEE */
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
g_cpu_initialized[linear_id] = CPU_INIT_DONE;
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the SP.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the SP is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -165,41 +165,41 @@ static void teed_cpu_on_finish_handler(u_register_t unused)
|
||||
*/
|
||||
static void teed_cpu_suspend_finish_handler(u_register_t max_off_pwrlvl)
|
||||
{
|
||||
int32_t rc;
|
||||
uint64_t power_state;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
int32_t rc;
|
||||
uint64_t power_state;
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
assert(tee_ctx != NULL);
|
||||
|
||||
(void)max_off_pwrlvl;
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_SUSPEND);
|
||||
(void)max_off_pwrlvl;
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_SUSPEND);
|
||||
|
||||
if (is_system_suspend() != 0)
|
||||
power_state = CPU_IDLE_STATE; /* stand for cpu idle */
|
||||
else
|
||||
power_state = CPU_SUSPEND_STATE; /* stand for cpu suspend */
|
||||
if (is_system_suspend() != 0)
|
||||
power_state = CPU_IDLE_STATE; /* stand for cpu idle */
|
||||
else
|
||||
power_state = CPU_SUSPEND_STATE; /* stand for cpu suspend */
|
||||
|
||||
/* Program the entry point, max_off_pwrlvl and enter the SP */
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context),
|
||||
CTX_GPREG_X0,
|
||||
power_state);
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->cpu_resume_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the TEE.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the SP is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
/* Program the entry point, max_off_pwrlvl and enter the SP */
|
||||
write_ctx_reg(get_gpregs_ctx(&tee_ctx->cpu_context),
|
||||
CTX_GPREG_X0,
|
||||
power_state);
|
||||
tee_ctx->spsr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_SPSR_EL3);
|
||||
tee_ctx->elr_el3 = SMC_GET_EL3(&tee_ctx->cpu_context,
|
||||
CTX_ELR_EL3);
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->cpu_resume_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
rc = teed_synchronous_sp_entry(tee_ctx);
|
||||
/*
|
||||
* Read the response from the TEE. A non-zero return means that
|
||||
* something went wrong while communicating with the TEE.
|
||||
*/
|
||||
if (rc != 0)
|
||||
panic();
|
||||
/* Update its context to reflect the state the SP is in */
|
||||
set_tee_pstate(tee_ctx->state, TEE_PSTATE_ON);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -208,8 +208,8 @@ static void teed_cpu_suspend_finish_handler(u_register_t max_off_pwrlvl)
|
||||
*/
|
||||
static int32_t teed_cpu_migrate_info(u_register_t *resident_cpu)
|
||||
{
|
||||
(void)resident_cpu;
|
||||
return TEE_MIGRATE_INFO;
|
||||
(void)resident_cpu;
|
||||
return TEE_MIGRATE_INFO;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -218,23 +218,23 @@ static int32_t teed_cpu_migrate_info(u_register_t *resident_cpu)
|
||||
*/
|
||||
static void teed_system_off(void)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
tee_vectors_t* tee_vectors_tmp = get_tee_vectors_t();
|
||||
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
|
||||
/* Program the entry point */
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->system_off_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
/*
|
||||
* Enter the TEE. We do not care about the return value because we
|
||||
* must continue the shutdown anyway
|
||||
*/
|
||||
NOTICE("teed system off\n");
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
/* Program the entry point */
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->system_off_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
/*
|
||||
* Enter the TEE. We do not care about the return value because we
|
||||
* must continue the shutdown anyway
|
||||
*/
|
||||
NOTICE("teed system off\n");
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -243,26 +243,26 @@ static void teed_system_off(void)
|
||||
*/
|
||||
static void teed_system_reset(void)
|
||||
{
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
tee_vectors_t *tee_vectors_tmp = get_tee_vectors_t();
|
||||
uint32_t linear_id = plat_my_core_pos();
|
||||
tee_context_t *tee_ctx = get_teed_sp_context(linear_id);
|
||||
tee_vectors_t *tee_vectors_tmp = get_tee_vectors_t();
|
||||
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
* Program the entry point
|
||||
*/
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->system_reset_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
/*
|
||||
* Enter the TEE. We do not care about the return value because we
|
||||
* must continue the reset anyway
|
||||
*/
|
||||
NOTICE("teed system reset\n");
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
assert(tee_vectors_tmp != NULL);
|
||||
assert(tee_ctx != NULL);
|
||||
assert(get_tee_pstate(tee_ctx->state) == TEE_PSTATE_ON);
|
||||
/*
|
||||
* Abort any preempted SMC request before overwriting the SECURE
|
||||
* context.
|
||||
* Program the entry point
|
||||
*/
|
||||
cm_set_elr_spsr_el3(SECURE, (uintptr_t)&tee_vectors_tmp->system_reset_entry,
|
||||
SPSR_64(MODE_EL1, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS));
|
||||
/*
|
||||
* Enter the TEE. We do not care about the return value because we
|
||||
* must continue the reset anyway
|
||||
*/
|
||||
NOTICE("teed system reset\n");
|
||||
(void)teed_synchronous_sp_entry(tee_ctx);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -270,18 +270,18 @@ static void teed_system_reset(void)
|
||||
* TEE bookkeeping before PSCI executes a power management operation.
|
||||
*/
|
||||
static const spd_pm_ops_t g_teed_pm = {
|
||||
.svc_on = teed_cpu_on_handler,
|
||||
.svc_off = teed_cpu_off_handler,
|
||||
.svc_suspend = teed_cpu_suspend_handler,
|
||||
.svc_on_finish = teed_cpu_on_finish_handler,
|
||||
.svc_suspend_finish = teed_cpu_suspend_finish_handler,
|
||||
.svc_migrate = NULL,
|
||||
.svc_migrate_info = teed_cpu_migrate_info,
|
||||
.svc_system_off = teed_system_off,
|
||||
.svc_system_reset = teed_system_reset
|
||||
.svc_on = teed_cpu_on_handler,
|
||||
.svc_off = teed_cpu_off_handler,
|
||||
.svc_suspend = teed_cpu_suspend_handler,
|
||||
.svc_on_finish = teed_cpu_on_finish_handler,
|
||||
.svc_suspend_finish = teed_cpu_suspend_finish_handler,
|
||||
.svc_migrate = NULL,
|
||||
.svc_migrate_info = teed_cpu_migrate_info,
|
||||
.svc_system_off = teed_system_off,
|
||||
.svc_system_reset = teed_system_reset
|
||||
};
|
||||
|
||||
const spd_pm_ops_t *get_teed_pm()
|
||||
{
|
||||
return &g_teed_pm;
|
||||
return &g_teed_pm;
|
||||
}
|
||||
|
||||
+5
-5
@@ -10,14 +10,14 @@
|
||||
|
||||
TEED_DIR := services/spd/teed
|
||||
|
||||
SPD_INCLUDES := -Iservices/spd/teed/include \
|
||||
SPD_INCLUDES := -Iservices/spd/teed/include \
|
||||
-Iinclude/bl31 \
|
||||
-Iinclude/lib \
|
||||
-Iinclude/lib/el3_runtime \
|
||||
-Iinclude/lib/psci \
|
||||
-Iinclude/common \
|
||||
-Iinclude/plat/common \
|
||||
-Iinclude/lib/el3_runtime/aarch64
|
||||
-Iinclude/lib/psci \
|
||||
-Iinclude/common \
|
||||
-Iinclude/plat/common \
|
||||
-Iinclude/lib/el3_runtime/aarch64
|
||||
|
||||
SPD_SOURCES := services/spd/teed/src/teed_common.c \
|
||||
services/spd/teed/src/teed_helpers.S \
|
||||
|
||||
@@ -243,7 +243,7 @@ void *perm_thread_init_file(void *data)
|
||||
|
||||
while (true) {
|
||||
rc = ipc_msg_receive(native_channel, &req_msg, (unsigned long)sizeof(req_msg), msghdl, &info, -1);
|
||||
if (rc < 0) {
|
||||
if (rc < 0) {
|
||||
tloge("%s: message receive failed, %llx\n", LOG_TAG, rc);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ void unregister_uuid(uint32_t sender, const char *name)
|
||||
client->dead = 1;
|
||||
|
||||
(void)ipc_release_from_taskid(sender, 0);
|
||||
(void)ipc_release_by_name(name);
|
||||
(void)ipc_release_by_name(name);
|
||||
|
||||
for (i = 0; i < MAX_CLIENT_OPEN_FILES; i++) {
|
||||
if ((client->file_instance[i].file_link) == NULL) {
|
||||
|
||||
Reference in New Issue
Block a user