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