1 /* 2 * Copyright (c) 2015, Linaro Limited 3 * All rights reserved. 4 * Copyright (c) 2014, STMicroelectronics International N.V. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, 11 * this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include <tee/entry_fast.h> 31 #include <sm/teesmc.h> 32 #include <sm/teesmc_optee.h> 33 #include <kernel/tee_l2cc_mutex.h> 34 #include <kernel/panic.h> 35 #include <mm/core_mmu.h> 36 37 #include <assert.h> 38 39 static void tee_entry_get_shm_config(struct thread_smc_args *args) 40 { 41 args->a0 = TEESMC_RETURN_OK; 42 args->a1 = default_nsec_shm_paddr; 43 args->a2 = default_nsec_shm_size; 44 /* Should this be TEESMC cache attributes instead? */ 45 args->a3 = core_mmu_is_shm_cached(); 46 } 47 48 static void tee_entry_fastcall_l2cc_mutex(struct thread_smc_args *args) 49 { 50 TEE_Result ret; 51 52 #ifdef ARM32 53 switch (args->a1) { 54 case TEESMC_OPTEE_L2CC_MUTEX_GET_ADDR: 55 ret = tee_get_l2cc_mutex(&args->a2); 56 break; 57 case TEESMC_OPTEE_L2CC_MUTEX_SET_ADDR: 58 ret = tee_set_l2cc_mutex(&args->a2); 59 break; 60 case TEESMC_OPTEE_L2CC_MUTEX_ENABLE: 61 ret = tee_enable_l2cc_mutex(); 62 break; 63 case TEESMC_OPTEE_L2CC_MUTEX_DISABLE: 64 ret = tee_disable_l2cc_mutex(); 65 break; 66 default: 67 args->a0 = TEESMC_RETURN_EBADCMD; 68 return; 69 } 70 #else 71 ret = TEE_ERROR_NOT_SUPPORTED; 72 #endif 73 if (ret == TEE_ERROR_NOT_SUPPORTED) 74 args->a0 = TEESMC_RETURN_UNKNOWN_FUNCTION; 75 else if (ret) 76 args->a0 = TEESMC_RETURN_EBADADDR; 77 else 78 args->a0 = TEESMC_RETURN_OK; 79 } 80 81 void tee_entry_fast(struct thread_smc_args *args) 82 { 83 switch (args->a0) { 84 85 /* Generic functions */ 86 case TEESMC32_CALLS_COUNT: 87 tee_entry_get_api_call_count(args); 88 break; 89 case TEESMC32_CALLS_UID: 90 tee_entry_get_api_uuid(args); 91 break; 92 case TEESMC32_CALLS_REVISION: 93 tee_entry_get_api_revision(args); 94 break; 95 case TEESMC32_CALL_GET_OS_UUID: 96 tee_entry_get_os_uuid(args); 97 break; 98 case TEESMC32_CALL_GET_OS_REVISION: 99 tee_entry_get_os_revision(args); 100 break; 101 102 /* OP-TEE specific SMC functions */ 103 case TEESMC32_OPTEE_FASTCALL_GET_SHM_CONFIG: 104 tee_entry_get_shm_config(args); 105 break; 106 case TEESMC32_OPTEE_FASTCALL_L2CC_MUTEX: 107 tee_entry_fastcall_l2cc_mutex(args); 108 break; 109 default: 110 args->a0 = TEESMC_RETURN_UNKNOWN_FUNCTION; 111 break; 112 } 113 } 114 115 size_t tee_entry_generic_get_api_call_count(void) 116 { 117 /* 118 * All the different calls handled in this file. If the specific 119 * target has additional calls it will call this function and 120 * add the number of calls the target has added. 121 */ 122 return 9; 123 } 124 125 void __weak tee_entry_get_api_call_count(struct thread_smc_args *args) 126 { 127 args->a0 = tee_entry_generic_get_api_call_count(); 128 } 129 130 void __weak tee_entry_get_api_uuid(struct thread_smc_args *args) 131 { 132 args->a0 = TEESMC_OPTEE_UID_R0; 133 args->a1 = TEESMC_OPTEE_UID_R1; 134 args->a2 = TEESMC_OPTEE_UID_R2; 135 args->a3 = TEESMC_OPTEE_UID32_R3; 136 } 137 138 void __weak tee_entry_get_api_revision(struct thread_smc_args *args) 139 { 140 args->a0 = TEESMC_OPTEE_REVISION_MAJOR; 141 args->a1 = TEESMC_OPTEE_REVISION_MINOR; 142 } 143 144 void __weak tee_entry_get_os_uuid(struct thread_smc_args *args) 145 { 146 args->a0 = TEESMC_OS_OPTEE_UUID_R0; 147 args->a1 = TEESMC_OS_OPTEE_UUID_R1; 148 args->a2 = TEESMC_OS_OPTEE_UUID_R2; 149 args->a3 = TEESMC_OS_OPTEE_UUID_R3; 150 } 151 152 void __weak tee_entry_get_os_revision(struct thread_smc_args *args) 153 { 154 args->a0 = TEESMC_OS_OPTEE_REVISION_MAJOR; 155 args->a1 = TEESMC_OS_OPTEE_REVISION_MINOR; 156 } 157