blob: a7d33d86adbceec21df0dd1558c01f6eb753fb6f [file] [log] [blame]
Soby Mathewc6820d12016-05-09 17:49:55 +01001/*
Antonio Nino Diaze40306b2017-01-13 15:03:07 +00002 * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved.
Soby Mathewc6820d12016-05-09 17:49:55 +01003 *
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 __ARCH_HELPERS_H__
32#define __ARCH_HELPERS_H__
33
34#include <arch.h> /* for additional register definitions */
35#include <stdint.h>
Antonio Nino Diaze40306b2017-01-13 15:03:07 +000036#include <sys/types.h>
Soby Mathewc6820d12016-05-09 17:49:55 +010037
38/**********************************************************************
39 * Macros which create inline functions to read or write CPU system
40 * registers
41 *********************************************************************/
42
43#define _DEFINE_COPROCR_WRITE_FUNC(_name, coproc, opc1, CRn, CRm, opc2) \
44static inline void write_## _name(u_register_t v) \
45{ \
46 __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
47}
48
49#define _DEFINE_COPROCR_READ_FUNC(_name, coproc, opc1, CRn, CRm, opc2) \
50static inline u_register_t read_ ## _name(void) \
51{ \
52 u_register_t v; \
53 __asm__ volatile ("mrc "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : "=r" (v));\
54 return v; \
55}
56
57/*
58 * The undocumented %Q and %R extended asm are used to implemented the below
59 * 64 bit `mrrc` and `mcrr` instructions. It works only on Little Endian
60 * systems for GCC versions < 4.6. Above GCC 4.6, both Little Endian and
61 * Big Endian systems generate the right instruction encoding.
62 */
63#if !(__GNUC__ > (4) || __GNUC__ == (4) && __GNUC_MINOR__ >= (6))
64#error "GCC 4.6 or above is required to build AArch32 Trusted Firmware"
65#endif
66
67#define _DEFINE_COPROCR_WRITE_FUNC_64(_name, coproc, opc1, CRm) \
68static inline void write64_## _name(uint64_t v) \
69{ \
70 __asm__ volatile ("mcrr "#coproc","#opc1", %Q0, %R0,"#CRm : : "r" (v));\
71}
72
73#define _DEFINE_COPROCR_READ_FUNC_64(_name, coproc, opc1, CRm) \
74static inline uint64_t read64_## _name(void) \
75{ uint64_t v; \
76 __asm__ volatile ("mrrc "#coproc","#opc1", %Q0, %R0,"#CRm : "=r" (v));\
77 return v; \
78}
79
80#define _DEFINE_SYSREG_READ_FUNC(_name, _reg_name) \
81static inline u_register_t read_ ## _name(void) \
82{ \
83 u_register_t v; \
84 __asm__ volatile ("mrs %0, " #_reg_name : "=r" (v)); \
85 return v; \
86}
87
88#define _DEFINE_SYSREG_WRITE_FUNC(_name, _reg_name) \
89static inline void write_ ## _name(u_register_t v) \
90{ \
91 __asm__ volatile ("msr " #_reg_name ", %0" : : "r" (v)); \
92}
93
94#define _DEFINE_SYSREG_WRITE_CONST_FUNC(_name, _reg_name) \
95static inline void write_ ## _name(const u_register_t v) \
96{ \
97 __asm__ volatile ("msr " #_reg_name ", %0" : : "i" (v)); \
98}
99
100/* Define read function for coproc register */
101#define DEFINE_COPROCR_READ_FUNC(_name, ...) \
102 _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__)
103
104/* Define read & write function for coproc register */
105#define DEFINE_COPROCR_RW_FUNCS(_name, ...) \
106 _DEFINE_COPROCR_READ_FUNC(_name, __VA_ARGS__) \
107 _DEFINE_COPROCR_WRITE_FUNC(_name, __VA_ARGS__)
108
109/* Define 64 bit read function for coproc register */
110#define DEFINE_COPROCR_READ_FUNC_64(_name, ...) \
111 _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__)
112
113/* Define 64 bit read & write function for coproc register */
114#define DEFINE_COPROCR_RW_FUNCS_64(_name, ...) \
115 _DEFINE_COPROCR_READ_FUNC_64(_name, __VA_ARGS__) \
116 _DEFINE_COPROCR_WRITE_FUNC_64(_name, __VA_ARGS__)
117
118/* Define read & write function for system register */
119#define DEFINE_SYSREG_RW_FUNCS(_name) \
120 _DEFINE_SYSREG_READ_FUNC(_name, _name) \
121 _DEFINE_SYSREG_WRITE_FUNC(_name, _name)
122
123/**********************************************************************
124 * Macros to create inline functions for tlbi operations
125 *********************************************************************/
126
127#define _DEFINE_TLBIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
128static inline void tlbi##_op(void) \
129{ \
130 u_register_t v = 0; \
131 __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
132}
133
Antonio Nino Diazac998032017-02-27 17:23:54 +0000134#define _DEFINE_BPIOP_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
135static inline void bpi##_op(void) \
136{ \
137 u_register_t v = 0; \
138 __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
139}
140
Soby Mathewc6820d12016-05-09 17:49:55 +0100141#define _DEFINE_TLBIOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
142static inline void tlbi##_op(u_register_t v) \
143{ \
144 __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
145}
146
147/* Define function for simple TLBI operation */
148#define DEFINE_TLBIOP_FUNC(_op, ...) \
149 _DEFINE_TLBIOP_FUNC(_op, __VA_ARGS__)
150
151/* Define function for TLBI operation with register parameter */
152#define DEFINE_TLBIOP_PARAM_FUNC(_op, ...) \
153 _DEFINE_TLBIOP_PARAM_FUNC(_op, __VA_ARGS__)
154
Antonio Nino Diazac998032017-02-27 17:23:54 +0000155/* Define function for simple BPI operation */
156#define DEFINE_BPIOP_FUNC(_op, ...) \
157 _DEFINE_BPIOP_FUNC(_op, __VA_ARGS__)
158
Soby Mathewc6820d12016-05-09 17:49:55 +0100159/**********************************************************************
160 * Macros to create inline functions for DC operations
161 *********************************************************************/
162#define _DEFINE_DCOP_PARAM_FUNC(_op, coproc, opc1, CRn, CRm, opc2) \
163static inline void dc##_op(u_register_t v) \
164{ \
165 __asm__ volatile ("mcr "#coproc","#opc1",%0,"#CRn","#CRm","#opc2 : : "r" (v));\
166}
167
168/* Define function for DC operation with register parameter */
169#define DEFINE_DCOP_PARAM_FUNC(_op, ...) \
170 _DEFINE_DCOP_PARAM_FUNC(_op, __VA_ARGS__)
171
172/**********************************************************************
173 * Macros to create inline functions for system instructions
174 *********************************************************************/
175 /* Define function for simple system instruction */
176#define DEFINE_SYSOP_FUNC(_op) \
177static inline void _op(void) \
178{ \
179 __asm__ (#_op); \
180}
181
182
183/* Define function for system instruction with type specifier */
184#define DEFINE_SYSOP_TYPE_FUNC(_op, _type) \
185static inline void _op ## _type(void) \
186{ \
187 __asm__ (#_op " " #_type); \
188}
189
190/* Define function for system instruction with register parameter */
191#define DEFINE_SYSOP_TYPE_PARAM_FUNC(_op, _type) \
192static inline void _op ## _type(u_register_t v) \
193{ \
194 __asm__ (#_op " " #_type ", %0" : : "r" (v)); \
195}
196
197void flush_dcache_range(uintptr_t addr, size_t size);
198void clean_dcache_range(uintptr_t addr, size_t size);
199void inv_dcache_range(uintptr_t addr, size_t size);
200
Antonio Nino Diaze40306b2017-01-13 15:03:07 +0000201void dcsw_op_louis(u_register_t op_type);
202void dcsw_op_all(u_register_t op_type);
203
Yatharth Kocharf528faf2016-06-28 16:58:26 +0100204void disable_mmu_secure(void);
205void disable_mmu_icache_secure(void);
206
Soby Mathewc6820d12016-05-09 17:49:55 +0100207DEFINE_SYSOP_FUNC(wfi)
208DEFINE_SYSOP_FUNC(wfe)
209DEFINE_SYSOP_FUNC(sev)
210DEFINE_SYSOP_TYPE_FUNC(dsb, sy)
211DEFINE_SYSOP_TYPE_FUNC(dmb, sy)
212DEFINE_SYSOP_TYPE_FUNC(dsb, ish)
Antonio Nino Diazac998032017-02-27 17:23:54 +0000213DEFINE_SYSOP_TYPE_FUNC(dsb, ishst)
Soby Mathewc6820d12016-05-09 17:49:55 +0100214DEFINE_SYSOP_TYPE_FUNC(dmb, ish)
215DEFINE_SYSOP_FUNC(isb)
216
Yatharth Kocharf528faf2016-06-28 16:58:26 +0100217void __dead2 smc(uint32_t r0, uint32_t r1, uint32_t r2, uint32_t r3,
218 uint32_t r4, uint32_t r5, uint32_t r6, uint32_t r7);
219
Soby Mathewc6820d12016-05-09 17:49:55 +0100220DEFINE_SYSREG_RW_FUNCS(spsr)
221DEFINE_SYSREG_RW_FUNCS(cpsr)
222
223/*******************************************************************************
224 * System register accessor prototypes
225 ******************************************************************************/
226DEFINE_COPROCR_READ_FUNC(mpidr, MPIDR)
227DEFINE_COPROCR_READ_FUNC(midr, MIDR)
228DEFINE_COPROCR_READ_FUNC(id_pfr1, ID_PFR1)
229DEFINE_COPROCR_READ_FUNC(isr, ISR)
230DEFINE_COPROCR_READ_FUNC(clidr, CLIDR)
231DEFINE_COPROCR_READ_FUNC_64(cntpct, CNTPCT_64)
232
233DEFINE_COPROCR_RW_FUNCS(scr, SCR)
234DEFINE_COPROCR_RW_FUNCS(ctr, CTR)
235DEFINE_COPROCR_RW_FUNCS(sctlr, SCTLR)
236DEFINE_COPROCR_RW_FUNCS(hsctlr, HSCTLR)
237DEFINE_COPROCR_RW_FUNCS(hcr, HCR)
238DEFINE_COPROCR_RW_FUNCS(hcptr, HCPTR)
239DEFINE_COPROCR_RW_FUNCS(cntfrq, CNTFRQ)
240DEFINE_COPROCR_RW_FUNCS(cnthctl, CNTHCTL)
241DEFINE_COPROCR_RW_FUNCS(mair0, MAIR0)
242DEFINE_COPROCR_RW_FUNCS(mair1, MAIR1)
243DEFINE_COPROCR_RW_FUNCS(ttbcr, TTBCR)
244DEFINE_COPROCR_RW_FUNCS(ttbr0, TTBR0)
245DEFINE_COPROCR_RW_FUNCS_64(ttbr0, TTBR0_64)
246DEFINE_COPROCR_RW_FUNCS(ttbr1, TTBR1)
247DEFINE_COPROCR_RW_FUNCS(vpidr, VPIDR)
248DEFINE_COPROCR_RW_FUNCS(vmpidr, VMPIDR)
249DEFINE_COPROCR_RW_FUNCS_64(vttbr, VTTBR_64)
250DEFINE_COPROCR_RW_FUNCS_64(ttbr1, TTBR1_64)
251DEFINE_COPROCR_RW_FUNCS_64(cntvoff, CNTVOFF_64)
252DEFINE_COPROCR_RW_FUNCS(csselr, CSSELR)
253
254DEFINE_COPROCR_RW_FUNCS(icc_sre_el1, ICC_SRE)
255DEFINE_COPROCR_RW_FUNCS(icc_sre_el2, ICC_HSRE)
256DEFINE_COPROCR_RW_FUNCS(icc_sre_el3, ICC_MSRE)
257DEFINE_COPROCR_RW_FUNCS(icc_pmr_el1, ICC_PMR)
258DEFINE_COPROCR_RW_FUNCS(icc_igrpen1_el3, ICC_MGRPEN1)
259DEFINE_COPROCR_RW_FUNCS(icc_igrpen0_el1, ICC_IGRPEN0)
260DEFINE_COPROCR_RW_FUNCS(icc_hppir0_el1, ICC_HPPIR0)
261DEFINE_COPROCR_RW_FUNCS(icc_hppir1_el1, ICC_HPPIR1)
262DEFINE_COPROCR_RW_FUNCS(icc_iar0_el1, ICC_IAR0)
263DEFINE_COPROCR_RW_FUNCS(icc_iar1_el1, ICC_IAR1)
264DEFINE_COPROCR_RW_FUNCS(icc_eoir0_el1, ICC_EOIR0)
265DEFINE_COPROCR_RW_FUNCS(icc_eoir1_el1, ICC_EOIR1)
266
David Cunado5f55e282016-10-31 17:37:34 +0000267DEFINE_COPROCR_RW_FUNCS(hdcr, HDCR)
David Cunadoc14b08e2016-11-25 00:21:59 +0000268DEFINE_COPROCR_RW_FUNCS(cnthp_ctl, CNTHP_CTL)
David Cunado5f55e282016-10-31 17:37:34 +0000269DEFINE_COPROCR_READ_FUNC(pmcr, PMCR)
270
Soby Mathewc6820d12016-05-09 17:49:55 +0100271/*
272 * TLBI operation prototypes
273 */
274DEFINE_TLBIOP_FUNC(all, TLBIALL)
275DEFINE_TLBIOP_FUNC(allis, TLBIALLIS)
276DEFINE_TLBIOP_PARAM_FUNC(mva, TLBIMVA)
277DEFINE_TLBIOP_PARAM_FUNC(mvaa, TLBIMVAA)
Antonio Nino Diazac998032017-02-27 17:23:54 +0000278DEFINE_TLBIOP_PARAM_FUNC(mvaais, TLBIMVAAIS)
279
280/*
281 * BPI operation prototypes.
282 */
283DEFINE_BPIOP_FUNC(allis, BPIALLIS)
Soby Mathewc6820d12016-05-09 17:49:55 +0100284
285/*
286 * DC operation prototypes
287 */
288DEFINE_DCOP_PARAM_FUNC(civac, DCCIMVAC)
289DEFINE_DCOP_PARAM_FUNC(ivac, DCIMVAC)
290DEFINE_DCOP_PARAM_FUNC(cvac, DCCMVAC)
291
292/* Previously defined accessor functions with incomplete register names */
293#define dsb() dsbsy()
294
295#define IS_IN_SECURE() \
296 (GET_NS_BIT(read_scr()) == 0)
297
298 /*
299 * If EL3 is AArch32, then secure PL1 and monitor mode correspond to EL3
300 */
301#define IS_IN_EL3() \
302 ((GET_M32(read_cpsr()) == MODE32_mon) || \
303 (IS_IN_SECURE() && (GET_M32(read_cpsr()) != MODE32_usr)))
304
305/* Macros for compatibility with AArch64 system registers */
306#define read_mpidr_el1() read_mpidr()
307
308#define read_scr_el3() read_scr()
309#define write_scr_el3(_v) write_scr(_v)
310
311#define read_hcr_el2() read_hcr()
312#define write_hcr_el2(_v) write_hcr(_v)
313
314#define read_cpacr_el1() read_cpacr()
315#define write_cpacr_el1(_v) write_cpacr(_v)
316
317#define read_cntfrq_el0() read_cntfrq()
318#define write_cntfrq_el0(_v) write_cntfrq(_v)
319#define read_isr_el1() read_isr()
320
321#define read_cntpct_el0() read64_cntpct()
322
Yatharth Kocharf528faf2016-06-28 16:58:26 +0100323#define read_ctr_el0() read_ctr()
324
Soby Mathewc6820d12016-05-09 17:49:55 +0100325#endif /* __ARCH_HELPERS_H__ */