1*2f3f5939SLeon Chen /* 2*2f3f5939SLeon Chen * Copyright (c) 2022, ARM Limited and Contributors. All rights reserved. 3*2f3f5939SLeon Chen * 4*2f3f5939SLeon Chen * SPDX-License-Identifier: BSD-3-Clause 5*2f3f5939SLeon Chen */ 6*2f3f5939SLeon Chen 7*2f3f5939SLeon Chen #ifndef MTK_SIP_SVC_H 8*2f3f5939SLeon Chen #define MTK_SIP_SVC_H 9*2f3f5939SLeon Chen 10*2f3f5939SLeon Chen #include <stdint.h> 11*2f3f5939SLeon Chen #include <lib/smccc.h> 12*2f3f5939SLeon Chen #include <mtk_sip_def.h> 13*2f3f5939SLeon Chen 14*2f3f5939SLeon Chen /* SMC function IDs for SiP Service queries */ 15*2f3f5939SLeon Chen #define SIP_SVC_CALL_COUNT U(0x8200ff00) 16*2f3f5939SLeon Chen #define SIP_SVC_UID U(0x8200ff01) 17*2f3f5939SLeon Chen /* 0x8200ff02 is reserved */ 18*2f3f5939SLeon Chen #define SIP_SVC_VERSION U(0x8200ff03) 19*2f3f5939SLeon Chen 20*2f3f5939SLeon Chen /* MediaTek SiP Service Calls version numbers */ 21*2f3f5939SLeon Chen #define MTK_SIP_SVC_VERSION_MAJOR U(0x0) 22*2f3f5939SLeon Chen #define MTK_SIP_SVC_VERSION_MINOR U(0x1) 23*2f3f5939SLeon Chen 24*2f3f5939SLeon Chen /* Number of MediaTek SiP Calls implemented */ 25*2f3f5939SLeon Chen #define MTK_COMMON_SIP_NUM_CALLS U(4) 26*2f3f5939SLeon Chen 27*2f3f5939SLeon Chen /* MediaTek SiP Service Calls function IDs */ 28*2f3f5939SLeon Chen #define MTK_SIP_SET_AUTHORIZED_SECURE_REG U(0x82000001) 29*2f3f5939SLeon Chen 30*2f3f5939SLeon Chen #define SMC_ID_EXPAND_AS_ENUM(_smc_id, _smc_num) \ 31*2f3f5939SLeon Chen _smc_id##_AARCH32 = ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \ 32*2f3f5939SLeon Chen ((0) << FUNCID_CC_SHIFT) | \ 33*2f3f5939SLeon Chen (OEN_SIP_START << FUNCID_OEN_SHIFT) | \ 34*2f3f5939SLeon Chen ((_smc_num) << FUNCID_NUM_SHIFT)), \ 35*2f3f5939SLeon Chen _smc_id##_AARCH64 = ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \ 36*2f3f5939SLeon Chen ((1) << FUNCID_CC_SHIFT) | \ 37*2f3f5939SLeon Chen (OEN_SIP_START << FUNCID_OEN_SHIFT) | \ 38*2f3f5939SLeon Chen ((_smc_num) << FUNCID_NUM_SHIFT)), 39*2f3f5939SLeon Chen 40*2f3f5939SLeon Chen #define SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX(_smc_id, _smc_num) \ 41*2f3f5939SLeon Chen extern short _smc_id##_descriptor_index; 42*2f3f5939SLeon Chen 43*2f3f5939SLeon Chen /* Bind SMC handler with SMC ID */ 44*2f3f5939SLeon Chen #define DECLARE_SMC_HANDLER(_smc_id, _smc_handler) \ 45*2f3f5939SLeon Chen const struct smc_descriptor _smc_id##_descriptor \ 46*2f3f5939SLeon Chen __used \ 47*2f3f5939SLeon Chen __aligned(sizeof(void *)) \ 48*2f3f5939SLeon Chen __section(".mtk_smc_descriptor_pool") = { \ 49*2f3f5939SLeon Chen .smc_handler = _smc_handler, \ 50*2f3f5939SLeon Chen .smc_name = #_smc_id, \ 51*2f3f5939SLeon Chen .smc_id_aarch32 = _smc_id##_AARCH32, \ 52*2f3f5939SLeon Chen .smc_id_aarch64 = _smc_id##_AARCH64, \ 53*2f3f5939SLeon Chen .smc_descriptor_index = &_smc_id##_descriptor_index \ 54*2f3f5939SLeon Chen } 55*2f3f5939SLeon Chen 56*2f3f5939SLeon Chen MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX); 57*2f3f5939SLeon Chen MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_EXTERN_SMC_INDEX); 58*2f3f5939SLeon Chen 59*2f3f5939SLeon Chen /* Expand SiP SMC ID table as enum */ 60*2f3f5939SLeon Chen enum { 61*2f3f5939SLeon Chen MTK_SIP_SMC_FROM_BL33_TABLE(SMC_ID_EXPAND_AS_ENUM) 62*2f3f5939SLeon Chen MTK_SIP_SMC_FROM_NS_EL1_TABLE(SMC_ID_EXPAND_AS_ENUM) 63*2f3f5939SLeon Chen MTK_SIP_SMC_MAX_NUMBER 64*2f3f5939SLeon Chen }; 65*2f3f5939SLeon Chen 66*2f3f5939SLeon Chen /* MediaTek SiP Calls error code */ 67*2f3f5939SLeon Chen enum { 68*2f3f5939SLeon Chen MTK_SIP_E_SUCCESS = 0, 69*2f3f5939SLeon Chen MTK_SIP_E_INVALID_PARAM = -1, 70*2f3f5939SLeon Chen MTK_SIP_E_NOT_SUPPORTED = -2, 71*2f3f5939SLeon Chen MTK_SIP_E_INVALID_RANGE = -3, 72*2f3f5939SLeon Chen MTK_SIP_E_PERMISSION_DENY = -4, 73*2f3f5939SLeon Chen MTK_SIP_E_LOCK_FAIL = -5, 74*2f3f5939SLeon Chen }; 75*2f3f5939SLeon Chen 76*2f3f5939SLeon Chen struct smccc_res { 77*2f3f5939SLeon Chen uint64_t a1; 78*2f3f5939SLeon Chen uint64_t a2; 79*2f3f5939SLeon Chen uint64_t a3; 80*2f3f5939SLeon Chen }; 81*2f3f5939SLeon Chen 82*2f3f5939SLeon Chen typedef uintptr_t (*smc_handler_t)(u_register_t, 83*2f3f5939SLeon Chen u_register_t, 84*2f3f5939SLeon Chen u_register_t, 85*2f3f5939SLeon Chen u_register_t, 86*2f3f5939SLeon Chen void *, 87*2f3f5939SLeon Chen struct smccc_res *); 88*2f3f5939SLeon Chen 89*2f3f5939SLeon Chen struct smc_descriptor { 90*2f3f5939SLeon Chen smc_handler_t smc_handler; 91*2f3f5939SLeon Chen const uint32_t smc_id_aarch32; 92*2f3f5939SLeon Chen const uint32_t smc_id_aarch64; 93*2f3f5939SLeon Chen const char *smc_name; 94*2f3f5939SLeon Chen short *const smc_descriptor_index; 95*2f3f5939SLeon Chen }; 96*2f3f5939SLeon Chen 97*2f3f5939SLeon Chen /* 98*2f3f5939SLeon Chen * This function should be implemented in MediaTek SOC directory. It fullfills 99*2f3f5939SLeon Chen * MTK_SIP_SET_AUTHORIZED_SECURE_REG SiP call by checking the sreg with the 100*2f3f5939SLeon Chen * predefined secure register list, if a match was found, set val to sreg. 101*2f3f5939SLeon Chen * 102*2f3f5939SLeon Chen * Return MTK_SIP_E_SUCCESS on success, and MTK_SIP_E_INVALID_PARAM on failure. 103*2f3f5939SLeon Chen */ 104*2f3f5939SLeon Chen uint64_t mt_sip_set_authorized_sreg(uint32_t sreg, uint32_t val); 105*2f3f5939SLeon Chen 106*2f3f5939SLeon Chen #endif /* MTK_SIP_SVC_H */ 107