1 // © 2022 Qualcomm Innovation Center, Inc. All rights reserved. 2 // 3 // SPDX-License-Identifier: BSD-3-Clause 4 5 #include <hyptypes.h> 6 7 #include <smccc_platform.h> 8 #include <thread.h> 9 10 #include <events/smccc.h> 11 12 #include "smccc_hypercall.h" 13 14 bool smccc_handle_hypercall_wrapper(smccc_function_id_t smc_id,bool is_hvc)15smccc_handle_hypercall_wrapper(smccc_function_id_t smc_id, bool is_hvc) 16 { 17 bool handled; 18 19 smccc_function_t smc_func = smccc_function_id_get_function(&smc_id); 20 smccc_owner_id_t smc_owner = smccc_function_id_get_owner_id(&smc_id); 21 22 if (smc_owner != SMCCC_OWNER_ID_VENDOR_HYP) { 23 handled = false; 24 goto out; 25 } 26 27 bool is_smc64 = smccc_function_id_get_is_smc64(&smc_id); 28 bool is_fast = smccc_function_id_get_is_fast(&smc_id); 29 30 thread_t *current = thread_get_self(); 31 register_t *args = ¤t->vcpu_regs_gpr.x[0]; 32 33 smccc_vendor_hyp_function_id_t smc_type = 34 smccc_vendor_hyp_function_id_cast((uint16_t)(smc_func)); 35 36 switch (smccc_vendor_hyp_function_id_get_call_class(&smc_type)) { 37 case SMCCC_VENDOR_HYP_FUNCTION_CLASS_PLATFORM_CALL: 38 handled = smccc_handle_smc_platform_call(args, is_hvc); 39 break; 40 case SMCCC_VENDOR_HYP_FUNCTION_CLASS_HYPERCALL: 41 if (is_fast && is_smc64) { 42 uint32_t hyp_num = 43 smccc_vendor_hyp_function_id_get_function( 44 &smc_type); 45 smccc_hypercall_table_wrapper(hyp_num, args); 46 } else { 47 args[0] = (register_t)SMCCC_UNKNOWN_FUNCTION64; 48 } 49 handled = true; 50 break; 51 case SMCCC_VENDOR_HYP_FUNCTION_CLASS_SERVICE: 52 if (is_fast && !is_smc64) { 53 uint16_t func = 54 smccc_vendor_hyp_function_id_get_function( 55 &smc_type); 56 switch ((smccc_vendor_hyp_function_t)func) { 57 case SMCCC_VENDOR_HYP_FUNCTION_CALL_UID: 58 args[0] = SMCCC_GUNYAH_UID0; 59 args[1] = SMCCC_GUNYAH_UID1; 60 args[2] = SMCCC_GUNYAH_UID2; 61 args[3] = SMCCC_GUNYAH_UID3; 62 break; 63 case SMCCC_VENDOR_HYP_FUNCTION_REVISION: 64 args[0] = (register_t)hyp_api_info_raw( 65 hyp_api_info_default()); 66 break; 67 case SMCCC_VENDOR_HYP_FUNCTION_CALL_COUNT: 68 // Deprecated 69 default: 70 args[0] = (register_t)SMCCC_UNKNOWN_FUNCTION64; 71 break; 72 } 73 } else { 74 args[0] = (register_t)SMCCC_UNKNOWN_FUNCTION64; 75 } 76 handled = true; 77 break; 78 default: 79 args[0] = (register_t)SMCCC_UNKNOWN_FUNCTION64; 80 handled = true; 81 break; 82 } 83 84 out: 85 return handled; 86 } 87