1/* SPDX-License-Identifier: BSD-2-Clause */ 2/* 3 * Copyright (c) 2020, Linaro Limited 4 */ 5 6#include <platform_config.h> 7 8#include <arm32_macros.S> 9#include <arm.h> 10#include <asm.S> 11#include <ffa.h> 12#include <generated/asm-defines.h> 13#include <kernel/thread.h> 14#include <optee_ffa.h> 15 16FUNC thread_ffa_msg_wait , : 17 mov_imm r0, FFA_MSG_WAIT /* FID */ 18 mov r1, #FFA_TARGET_INFO_MBZ /* Target info MBZ */ 19 mov r2, #FFA_PARAM_MBZ /* Param MBZ */ 20 mov r3, #FFA_PARAM_MBZ /* Param MBZ */ 21 mov r4, #FFA_PARAM_MBZ /* Param MBZ */ 22 mov r5, #FFA_PARAM_MBZ /* Param MBZ */ 23 mov r6, #FFA_PARAM_MBZ /* Param MBZ */ 24 mov r7, #FFA_PARAM_MBZ /* Param MBZ */ 25 b .ffa_msg_loop 26END_FUNC thread_ffa_msg_wait 27 28 /* Caller provides r1, r3-r7 params */ 29LOCAL_FUNC ffa_msg_send_direct_resp , : 30 ldr r0, =FFA_MSG_SEND_DIRECT_RESP_32 /* FID */ 31 mov r2, #FFA_PARAM_MBZ /* RES MBZ */ 32 33.ffa_msg_loop: 34 /* Invoke SMC with caller provided parameters */ 35 smc #0 36 37 /* Store the parameters as struct thread_smc_args on stack */ 38 push {r0-r7} 39 mov r0, sp 40 41 /* parse and handle message */ 42 bl thread_spmc_msg_recv 43 44 /* Load struct thread_smc_args into registers */ 45 pop {r0-r7} 46 b .ffa_msg_loop 47END_FUNC ffa_msg_send_direct_resp 48 49FUNC thread_std_smc_entry , : 50UNWIND( .cantunwind) 51 52 push {r4, r5} /* Pass these following the arm32 calling convention */ 53 ror r4, r0, #16 /* Save target info with src and dst swapped */ 54 bl __thread_std_smc_entry 55 add sp, sp, #8 /* There's nothing return, just restore the sp */ 56 mov r5, r0 /* Save return value */ 57 58 /* Mask all maskable exceptions before switching to temporary stack */ 59 cpsid aif 60 bl thread_get_tmp_sp 61 mov sp, r0 62 63 bl thread_state_free 64 65 mov r1, r4 /* Target info */ 66 mov r3, r5 /* Return value */ 67 mov r4, #FFA_PARAM_MBZ /* Unused parameter */ 68 mov r5, #FFA_PARAM_MBZ /* Unused parameter */ 69 mov r6, #FFA_PARAM_MBZ /* Unused parameter */ 70 mov r7, #FFA_PARAM_MBZ /* Unused parameter */ 71 b ffa_msg_send_direct_resp 72END_FUNC thread_std_smc_entry 73 74/* void thread_rpc(struct thread_rpc_arg *rpc_arg) */ 75FUNC thread_rpc , : 76 push {r0, lr} 77UNWIND( .save {r0, lr}) 78 79 bl thread_save_state 80 mov r4, r0 /* Save original CPSR */ 81 82 /* 83 * Switch to temporary stack and SVC mode. Save CPSR to resume into. 84 */ 85 bl thread_get_tmp_sp 86 ldr r8, [sp] /* Get pointer to rv[] */ 87 cps #CPSR_MODE_SVC /* Change to SVC mode */ 88 mov sp, r0 /* Switch to tmp stack */ 89 90 mov r0, #THREAD_FLAGS_COPY_ARGS_ON_RETURN 91 mov r1, r4 /* CPSR to restore */ 92 ldr r2, =.thread_rpc_return 93 bl thread_state_suspend 94 mov r7, r0 /* Supply thread index */ 95 ldr r0, =FFA_MSG_SEND_DIRECT_RESP_32 96 mov r2, #FFA_PARAM_MBZ 97 mov r3, #0 /* Error code = 0 */ 98 ldm r8, {r1, r4-r6} /* Load rv[] into r1,r4-r6 */ 99 b ffa_msg_send_direct_resp 100 101.thread_rpc_return: 102 /* 103 * At this point has the stack pointer been restored to the value 104 * it had when thread_save_state() was called above. 105 * 106 * Jumps here from thread_resume above when RPC has returned. The 107 * IRQ and FIQ bits are restored to what they where when this 108 * function was originally entered. 109 */ 110 pop {r12, lr} /* Get pointer to rv[] */ 111 stm r12, {r0-r3} /* Store r0-r3 into rv[] */ 112 bx lr 113END_FUNC thread_rpc 114 115/* 116 * void thread_foreign_intr_exit(uint32_t thread_index) 117 * 118 * This function is jumped to at the end of macro foreign_intr_handler(). 119 * The current thread as indicated by @thread_index has just been 120 * suspended. The job here is just to inform normal world the thread id to 121 * resume when returning. 122 */ 123FUNC thread_foreign_intr_exit , : 124 /* load threads[r0].tsd.rpc_target_info into r1 */ 125 mov r1, #THREAD_CTX_SIZE 126 ldr r2, =threads 127 mla r1, r1, r0, r2 128 ldr r1, [r1, #THREAD_CTX_TSD_RPC_TARGET_INFO] 129 mov r2, #FFA_PARAM_MBZ 130 mov r3, #FFA_PARAM_MBZ 131 mov r4, #OPTEE_FFA_YIELDING_CALL_RETURN_INTERRUPT 132 mov r5, #FFA_PARAM_MBZ 133 mov r6, #FFA_PARAM_MBZ 134 mov r7, r0 135 b ffa_msg_send_direct_resp 136END_FUNC thread_foreign_intr_exit 137