1*54fd6939SJiyong Park /* 2*54fd6939SJiyong Park * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3*54fd6939SJiyong Park * 4*54fd6939SJiyong Park * SPDX-License-Identifier: BSD-3-Clause 5*54fd6939SJiyong Park */ 6*54fd6939SJiyong Park 7*54fd6939SJiyong Park #ifndef SMCCC_HELPERS_H 8*54fd6939SJiyong Park #define SMCCC_HELPERS_H 9*54fd6939SJiyong Park 10*54fd6939SJiyong Park #include <lib/smccc.h> 11*54fd6939SJiyong Park 12*54fd6939SJiyong Park #ifndef __ASSEMBLER__ 13*54fd6939SJiyong Park 14*54fd6939SJiyong Park #include <stdbool.h> 15*54fd6939SJiyong Park 16*54fd6939SJiyong Park #include <context.h> 17*54fd6939SJiyong Park 18*54fd6939SJiyong Park /* Convenience macros to return from SMC handler */ 19*54fd6939SJiyong Park #define SMC_RET0(_h) { \ 20*54fd6939SJiyong Park return (uint64_t) (_h); \ 21*54fd6939SJiyong Park } 22*54fd6939SJiyong Park #define SMC_RET1(_h, _x0) { \ 23*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X0), (_x0)); \ 24*54fd6939SJiyong Park SMC_RET0(_h); \ 25*54fd6939SJiyong Park } 26*54fd6939SJiyong Park #define SMC_RET2(_h, _x0, _x1) { \ 27*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X1), (_x1)); \ 28*54fd6939SJiyong Park SMC_RET1(_h, (_x0)); \ 29*54fd6939SJiyong Park } 30*54fd6939SJiyong Park #define SMC_RET3(_h, _x0, _x1, _x2) { \ 31*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X2), (_x2)); \ 32*54fd6939SJiyong Park SMC_RET2(_h, (_x0), (_x1)); \ 33*54fd6939SJiyong Park } 34*54fd6939SJiyong Park #define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \ 35*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X3), (_x3)); \ 36*54fd6939SJiyong Park SMC_RET3(_h, (_x0), (_x1), (_x2)); \ 37*54fd6939SJiyong Park } 38*54fd6939SJiyong Park #define SMC_RET5(_h, _x0, _x1, _x2, _x3, _x4) { \ 39*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X4), (_x4)); \ 40*54fd6939SJiyong Park SMC_RET4(_h, (_x0), (_x1), (_x2), (_x3)); \ 41*54fd6939SJiyong Park } 42*54fd6939SJiyong Park #define SMC_RET6(_h, _x0, _x1, _x2, _x3, _x4, _x5) { \ 43*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X5), (_x5)); \ 44*54fd6939SJiyong Park SMC_RET5(_h, (_x0), (_x1), (_x2), (_x3), (_x4)); \ 45*54fd6939SJiyong Park } 46*54fd6939SJiyong Park #define SMC_RET7(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6) { \ 47*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X6), (_x6)); \ 48*54fd6939SJiyong Park SMC_RET6(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5)); \ 49*54fd6939SJiyong Park } 50*54fd6939SJiyong Park #define SMC_RET8(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7) { \ 51*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X7), (_x7)); \ 52*54fd6939SJiyong Park SMC_RET7(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6)); \ 53*54fd6939SJiyong Park } 54*54fd6939SJiyong Park 55*54fd6939SJiyong Park /* 56*54fd6939SJiyong Park * Convenience macros to access general purpose registers using handle provided 57*54fd6939SJiyong Park * to SMC handler. These take the offset values defined in context.h 58*54fd6939SJiyong Park */ 59*54fd6939SJiyong Park #define SMC_GET_GP(_h, _g) \ 60*54fd6939SJiyong Park read_ctx_reg((get_gpregs_ctx(_h)), (_g)) 61*54fd6939SJiyong Park #define SMC_SET_GP(_h, _g, _v) \ 62*54fd6939SJiyong Park write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v)) 63*54fd6939SJiyong Park 64*54fd6939SJiyong Park /* 65*54fd6939SJiyong Park * Convenience macros to access EL3 context registers using handle provided to 66*54fd6939SJiyong Park * SMC handler. These take the offset values defined in context.h 67*54fd6939SJiyong Park */ 68*54fd6939SJiyong Park #define SMC_GET_EL3(_h, _e) \ 69*54fd6939SJiyong Park read_ctx_reg((get_el3state_ctx(_h)), (_e)) 70*54fd6939SJiyong Park #define SMC_SET_EL3(_h, _e, _v) \ 71*54fd6939SJiyong Park write_ctx_reg((get_el3state_ctx(_h)), (_e), (_v)) 72*54fd6939SJiyong Park 73*54fd6939SJiyong Park /* 74*54fd6939SJiyong Park * Helper macro to retrieve the SMC parameters from cpu_context_t. 75*54fd6939SJiyong Park */ 76*54fd6939SJiyong Park #define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \ 77*54fd6939SJiyong Park do { \ 78*54fd6939SJiyong Park const gp_regs_t *regs = get_gpregs_ctx(_hdl); \ 79*54fd6939SJiyong Park _x1 = read_ctx_reg(regs, CTX_GPREG_X1); \ 80*54fd6939SJiyong Park _x2 = read_ctx_reg(regs, CTX_GPREG_X2); \ 81*54fd6939SJiyong Park _x3 = read_ctx_reg(regs, CTX_GPREG_X3); \ 82*54fd6939SJiyong Park _x4 = read_ctx_reg(regs, CTX_GPREG_X4); \ 83*54fd6939SJiyong Park } while (false) 84*54fd6939SJiyong Park 85*54fd6939SJiyong Park #endif /*__ASSEMBLER__*/ 86*54fd6939SJiyong Park 87*54fd6939SJiyong Park #endif /* SMCCC_HELPERS_H */ 88