blob: 62294d0497b8a82e28ff6342a75278e21af7aff8 [file] [log] [blame]
Soby Mathewd0194872016-04-29 19:01:30 +01001/*
Varun Wadekarc6a11f62017-05-25 18:04:48 -07002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Soby Mathewd0194872016-04-29 19:01:30 +01003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Soby Mathewd0194872016-04-29 19:01:30 +01005 */
6
7#ifndef __SMCC_HELPERS_H__
8#define __SMCC_HELPERS_H__
9
10#include <smcc.h>
11
12#ifndef __ASSEMBLY__
13#include <context.h>
14
15/* Convenience macros to return from SMC handler */
16#define SMC_RET0(_h) { \
17 return (uint64_t) (_h); \
18}
19#define SMC_RET1(_h, _x0) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070020 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X0), (_x0)); \
Soby Mathewd0194872016-04-29 19:01:30 +010021 SMC_RET0(_h); \
22}
23#define SMC_RET2(_h, _x0, _x1) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070024 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X1), (_x1)); \
Soby Mathewd0194872016-04-29 19:01:30 +010025 SMC_RET1(_h, (_x0)); \
26}
27#define SMC_RET3(_h, _x0, _x1, _x2) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070028 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X2), (_x2)); \
Soby Mathewd0194872016-04-29 19:01:30 +010029 SMC_RET2(_h, (_x0), (_x1)); \
30}
31#define SMC_RET4(_h, _x0, _x1, _x2, _x3) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070032 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X3), (_x3)); \
Soby Mathewd0194872016-04-29 19:01:30 +010033 SMC_RET3(_h, (_x0), (_x1), (_x2)); \
34}
Anthony Zhou700ebe52015-10-31 06:03:41 +080035#define SMC_RET5(_h, _x0, _x1, _x2, _x3, _x4) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070036 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X4), (_x4)); \
Anthony Zhou700ebe52015-10-31 06:03:41 +080037 SMC_RET4(_h, (_x0), (_x1), (_x2), (_x3)); \
38}
39#define SMC_RET6(_h, _x0, _x1, _x2, _x3, _x4, _x5) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070040 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X5), (_x5)); \
Anthony Zhou700ebe52015-10-31 06:03:41 +080041 SMC_RET5(_h, (_x0), (_x1), (_x2), (_x3), (_x4)); \
42}
43#define SMC_RET7(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070044 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X6), (_x6)); \
Anthony Zhou700ebe52015-10-31 06:03:41 +080045 SMC_RET6(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5)); \
46}
47#define SMC_RET8(_h, _x0, _x1, _x2, _x3, _x4, _x5, _x6, _x7) { \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070048 write_ctx_reg((get_gpregs_ctx(_h)), (CTX_GPREG_X7), (_x7)); \
Anthony Zhou700ebe52015-10-31 06:03:41 +080049 SMC_RET7(_h, (_x0), (_x1), (_x2), (_x3), (_x4), (_x5), (_x6)); \
50}
Soby Mathewd0194872016-04-29 19:01:30 +010051
52/*
53 * Convenience macros to access general purpose registers using handle provided
54 * to SMC handler. These take the offset values defined in context.h
55 */
56#define SMC_GET_GP(_h, _g) \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070057 read_ctx_reg((get_gpregs_ctx(_h)), (_g))
Soby Mathewd0194872016-04-29 19:01:30 +010058#define SMC_SET_GP(_h, _g, _v) \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070059 write_ctx_reg((get_gpregs_ctx(_h)), (_g), (_v))
Soby Mathewd0194872016-04-29 19:01:30 +010060
61/*
62 * Convenience macros to access EL3 context registers using handle provided to
63 * SMC handler. These take the offset values defined in context.h
64 */
65#define SMC_GET_EL3(_h, _e) \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070066 read_ctx_reg((get_el3state_ctx(_h)), (_e))
Soby Mathewd0194872016-04-29 19:01:30 +010067#define SMC_SET_EL3(_h, _e, _v) \
Varun Wadekarc6a11f62017-05-25 18:04:48 -070068 write_ctx_reg((get_el3state_ctx(_h)), (_e), (_v))
Soby Mathewd0194872016-04-29 19:01:30 +010069
70/* Return a UUID in the SMC return registers */
71#define SMC_UUID_RET(_h, _uuid) \
72 SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
73 ((const uint32_t *) &(_uuid))[1], \
74 ((const uint32_t *) &(_uuid))[2], \
75 ((const uint32_t *) &(_uuid))[3])
76
Soby Mathewa9482df2016-05-05 12:49:09 +010077/*
78 * Helper macro to retrieve the SMC parameters from cpu_context_t.
79 */
80#define get_smc_params_from_ctx(_hdl, _x1, _x2, _x3, _x4) \
81 do { \
82 const gp_regs_t *regs = get_gpregs_ctx(_hdl); \
83 _x1 = read_ctx_reg(regs, CTX_GPREG_X1); \
84 _x2 = read_ctx_reg(regs, CTX_GPREG_X2); \
85 _x3 = read_ctx_reg(regs, CTX_GPREG_X3); \
86 _x4 = read_ctx_reg(regs, CTX_GPREG_X4); \
87 } while (0)
88
Soby Mathewd0194872016-04-29 19:01:30 +010089#endif /*__ASSEMBLY__*/
90#endif /* __SMCC_HELPERS_H__ */