blob: 4f9d8148b559b940a28d5685f78d60e63b0c9129 [file] [log] [blame]
Soby Mathewacc144b2016-05-05 12:53:53 +01001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#ifndef __SMCC_HELPERS_H__
32#define __SMCC_HELPERS_H__
33
34#include <smcc.h>
35
36/* These are offsets to registers in smc_ctx_t */
37#define SMC_CTX_GPREG_R0 0x0
38#define SMC_CTX_GPREG_R1 0x4
39#define SMC_CTX_GPREG_R2 0x8
40#define SMC_CTX_GPREG_R3 0xC
41#define SMC_CTX_GPREG_R4 0x10
Soby Mathewadb70272016-12-06 12:10:51 +000042#define SMC_CTX_GPREG_R5 0x14
Soby Mathewacc144b2016-05-05 12:53:53 +010043#define SMC_CTX_SP_USR 0x34
44#define SMC_CTX_SPSR_MON 0x78
45#define SMC_CTX_LR_MON 0x7C
46#define SMC_CTX_SIZE 0x80
47
48#ifndef __ASSEMBLY__
49#include <cassert.h>
50#include <types.h>
51
52/*
53 * The generic structure to save arguments and callee saved registers during
54 * an SMC. Also this structure is used to store the result return values after
55 * the completion of SMC service.
56 */
57typedef struct smc_ctx {
58 u_register_t r0;
59 u_register_t r1;
60 u_register_t r2;
61 u_register_t r3;
62 u_register_t r4;
63 u_register_t r5;
64 u_register_t r6;
65 u_register_t r7;
66 u_register_t r8;
67 u_register_t r9;
68 u_register_t r10;
69 u_register_t r11;
70 u_register_t r12;
71 /* spsr_usr doesn't exist */
72 u_register_t sp_usr;
73 u_register_t lr_usr;
74 u_register_t spsr_irq;
75 u_register_t sp_irq;
76 u_register_t lr_irq;
77 u_register_t spsr_fiq;
78 u_register_t sp_fiq;
79 u_register_t lr_fiq;
80 u_register_t spsr_svc;
81 u_register_t sp_svc;
82 u_register_t lr_svc;
83 u_register_t spsr_abt;
84 u_register_t sp_abt;
85 u_register_t lr_abt;
86 u_register_t spsr_und;
87 u_register_t sp_und;
88 u_register_t lr_und;
89 u_register_t spsr_mon;
90 /* No need to save 'sp_mon' because we are already in monitor mode */
91 u_register_t lr_mon;
92} smc_ctx_t;
93
94/*
95 * Compile time assertions related to the 'smc_context' structure to
96 * ensure that the assembler and the compiler view of the offsets of
97 * the structure members is the same.
98 */
99CASSERT(SMC_CTX_GPREG_R0 == __builtin_offsetof(smc_ctx_t, r0), \
100 assert_smc_ctx_greg_r0_offset_mismatch);
101CASSERT(SMC_CTX_GPREG_R1 == __builtin_offsetof(smc_ctx_t, r1), \
102 assert_smc_ctx_greg_r1_offset_mismatch);
103CASSERT(SMC_CTX_GPREG_R2 == __builtin_offsetof(smc_ctx_t, r2), \
104 assert_smc_ctx_greg_r2_offset_mismatch);
105CASSERT(SMC_CTX_GPREG_R3 == __builtin_offsetof(smc_ctx_t, r3), \
106 assert_smc_ctx_greg_r3_offset_mismatch);
107CASSERT(SMC_CTX_GPREG_R4 == __builtin_offsetof(smc_ctx_t, r4), \
108 assert_smc_ctx_greg_r4_offset_mismatch);
109CASSERT(SMC_CTX_SP_USR == __builtin_offsetof(smc_ctx_t, sp_usr), \
110 assert_smc_ctx_sp_usr_offset_mismatch);
111CASSERT(SMC_CTX_LR_MON == __builtin_offsetof(smc_ctx_t, lr_mon), \
112 assert_smc_ctx_lr_mon_offset_mismatch);
113CASSERT(SMC_CTX_SPSR_MON == __builtin_offsetof(smc_ctx_t, spsr_mon), \
114 assert_smc_ctx_spsr_mon_offset_mismatch);
115
116CASSERT(SMC_CTX_SIZE == sizeof(smc_ctx_t), assert_smc_ctx_size_mismatch);
117
118/* Convenience macros to return from SMC handler */
119#define SMC_RET0(_h) { \
120 return (uintptr_t)(_h); \
121}
122#define SMC_RET1(_h, _r0) { \
123 ((smc_ctx_t *)(_h))->r0 = (_r0); \
124 SMC_RET0(_h); \
125}
126#define SMC_RET2(_h, _r0, _r1) { \
127 ((smc_ctx_t *)(_h))->r1 = (_r1); \
128 SMC_RET1(_h, (_r0)); \
129}
130#define SMC_RET3(_h, _r0, _r1, _r2) { \
131 ((smc_ctx_t *)(_h))->r2 = (_r2); \
132 SMC_RET2(_h, (_r0), (_r1)); \
133}
134#define SMC_RET4(_h, _r0, _r1, _r2, _r3) { \
135 ((smc_ctx_t *)(_h))->r3 = (_r3); \
136 SMC_RET3(_h, (_r0), (_r1), (_r2)); \
137}
138
139/* Return a UUID in the SMC return registers */
140#define SMC_UUID_RET(_h, _uuid) \
141 SMC_RET4(handle, ((const uint32_t *) &(_uuid))[0], \
142 ((const uint32_t *) &(_uuid))[1], \
143 ((const uint32_t *) &(_uuid))[2], \
144 ((const uint32_t *) &(_uuid))[3])
145
146/*
147 * Helper macro to retrieve the SMC parameters from smc_ctx_t.
148 */
149#define get_smc_params_from_ctx(_hdl, _r1, _r2, _r3, _r4) { \
150 _r1 = ((smc_ctx_t *)_hdl)->r1; \
151 _r2 = ((smc_ctx_t *)_hdl)->r2; \
152 _r3 = ((smc_ctx_t *)_hdl)->r3; \
153 _r4 = ((smc_ctx_t *)_hdl)->r4; \
154 }
155
156/* ------------------------------------------------------------------------
157 * Helper APIs for setting and retrieving appropriate `smc_ctx_t`.
158 * These functions need to implemented by the BL including this library.
159 * ------------------------------------------------------------------------
160 */
161
162/* Get the pointer to `smc_ctx_t` corresponding to the security state. */
163void *smc_get_ctx(int security_state);
164
165/* Set the next `smc_ctx_t` corresponding to the security state. */
166void smc_set_next_ctx(int security_state);
167
168/* Get the pointer to next `smc_ctx_t` already set by `smc_set_next_ctx()`. */
169void *smc_get_next_ctx(void);
170
171#endif /*__ASSEMBLY__*/
172#endif /* __SMCC_HELPERS_H__ */