1 /******************************************************************************
2 *
3 * Copyright (C) 2014 - 2016 Xilinx, Inc. All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 * THE SOFTWARE.
22 *
23 *
24 *
25 ******************************************************************************/
26 /*****************************************************************************/
27 /**
28 *
29 * @file xpseudo_asm_gcc.h
30 *
31 * This header file contains macros for using inline assembler code. It is
32 * written specifically for the GNU compiler.
33 *
34 * <pre>
35 * MODIFICATION HISTORY:
36 *
37 * Ver   Who      Date     Changes
38 * ----- -------- -------- -----------------------------------------------
39 * 5.00  pkp      05/21/14 First release
40 * 6.0   mus      07/27/16 Consolidated file for a53,a9 and r5 processors
41 * </pre>
42 *
43 ******************************************************************************/
44 
45 #ifndef XPSEUDO_ASM_GCC_H  /* prevent circular inclusions */
46 #define XPSEUDO_ASM_GCC_H  /* by using protection macros */
47 
48 /***************************** Include Files ********************************/
49 #include <rtdef.h>
50 
51 #ifdef __cplusplus
52 extern "C" {
53 #endif /* __cplusplus */
54 
55 /************************** Constant Definitions ****************************/
56 
57 /**************************** Type Definitions ******************************/
58 
59 /***************** Macros (Inline Functions) Definitions ********************/
60 
61 /* necessary for pre-processor */
62 #define stringify(s)    tostring(s)
63 #define tostring(s) #s
64 
65 #if defined (__aarch64__)
66 /* pseudo assembler instructions */
67 #define mfcpsr()    ({rt_uint32_t rval = 0U; \
68                asm volatile("mrs %0,  DAIF" : "=r" (rval));\
69               rval;\
70              })
71 
72 #define mtcpsr(v) __asm__ __volatile__ ("msr DAIF, %0" : : "r" (v))
73 
74 #define cpsiei()    //__asm__ __volatile__("cpsie   i\n")
75 #define cpsidi()    //__asm__ __volatile__("cpsid   i\n")
76 
77 #define cpsief()    //__asm__ __volatile__("cpsie   f\n")
78 #define cpsidf()    //__asm__ __volatile__("cpsid   f\n")
79 
80 
81 
82 #define mtgpr(rn, v)    /*__asm__ __volatile__(\
83               "mov r" stringify(rn) ", %0 \n"\
84               : : "r" (v)\
85             )*/
86 
87 #define mfgpr(rn)   /*({rt_uint32_t rval; \
88               __asm__ __volatile__(\
89                 "mov %0,r" stringify(rn) "\n"\
90                 : "=r" (rval)\
91               );\
92               rval;\
93              })*/
94 
95 /* memory synchronization operations */
96 
97 /* Instruction Synchronization Barrier */
98 #define isb() __asm__ __volatile__ ("isb sy")
99 
100 /* Data Synchronization Barrier */
101 #define dsb() __asm__ __volatile__("dsb sy")
102 
103 /* Data Memory Barrier */
104 #define dmb() __asm__ __volatile__("dmb sy")
105 
106 
107 /* Memory Operations */
108 #define ldr(adr)    ({u64 rval; \
109               __asm__ __volatile__(\
110                 "ldr    %0,[%1]"\
111                 : "=r" (rval) : "r" (adr)\
112               );\
113               rval;\
114              })
115 
116 #define mfelrel3() ({u64 rval = 0U; \
117                    asm volatile("mrs %0,  ELR_EL3" : "=r" (rval));\
118                   rval;\
119                  })
120 
121 #define mtelrel3(v) __asm__ __volatile__ ("msr ELR_EL3, %0" : : "r" (v))
122 
123 #else
124 
125 /* pseudo assembler instructions */
126 #define mfcpsr()    ({rt_uint32_t rval = 0U; \
127               __asm__ __volatile__(\
128                 "mrs    %0, cpsr\n"\
129                 : "=r" (rval)\
130               );\
131               rval;\
132              })
133 
134 #define mtcpsr(v)   __asm__ __volatile__(\
135               "msr  cpsr,%0\n"\
136               : : "r" (v)\
137             )
138 
139 #define cpsiei()    __asm__ __volatile__("cpsie i\n")
140 #define cpsidi()    __asm__ __volatile__("cpsid i\n")
141 
142 #define cpsief()    __asm__ __volatile__("cpsie f\n")
143 #define cpsidf()    __asm__ __volatile__("cpsid f\n")
144 
145 
146 
147 #define mtgpr(rn, v)    __asm__ __volatile__(\
148               "mov r" stringify(rn) ", %0 \n"\
149               : : "r" (v)\
150             )
151 
152 #define mfgpr(rn)   ({rt_uint32_t rval; \
153               __asm__ __volatile__(\
154                 "mov %0,r" stringify(rn) "\n"\
155                 : "=r" (rval)\
156               );\
157               rval;\
158              })
159 
160 /* memory synchronization operations */
161 
162 /* Instruction Synchronization Barrier */
163 #define isb() __asm__ __volatile__ ("isb" : : : "memory")
164 
165 /* Data Synchronization Barrier */
166 #define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
167 
168 /* Data Memory Barrier */
169 #define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
170 
171 
172 /* Memory Operations */
173 #define ldr(adr)    ({rt_uint32_t rval; \
174               __asm__ __volatile__(\
175                 "ldr    %0,[%1]"\
176                 : "=r" (rval) : "r" (adr)\
177               );\
178               rval;\
179              })
180 
181 #endif
182 
183 #define ldrb(adr)   ({rt_uint8_t rval; \
184               __asm__ __volatile__(\
185                 "ldrb   %0,[%1]"\
186                 : "=r" (rval) : "r" (adr)\
187               );\
188               rval;\
189              })
190 
191 #define str(adr, val)   __asm__ __volatile__(\
192               "str  %0,[%1]\n"\
193               : : "r" (val), "r" (adr)\
194             )
195 
196 #define strb(adr, val)  __asm__ __volatile__(\
197               "strb %0,[%1]\n"\
198               : : "r" (val), "r" (adr)\
199             )
200 
201 /* Count leading zeroes (clz) */
202 #define clz(arg)    ({rt_uint8_t rval; \
203               __asm__ __volatile__(\
204                 "clz    %0,%1"\
205                 : "=r" (rval) : "r" (arg)\
206               );\
207               rval;\
208              })
209 
210 #if defined (__aarch64__)
211 #define mtcpdc(reg,val) __asm__ __volatile__("dc " #reg ",%0"  : : "r" (val))
212 #define mtcpic(reg,val) __asm__ __volatile__("ic " #reg ",%0"  : : "r" (val))
213 
214 #define mtcpicall(reg)  __asm__ __volatile__("ic " #reg)
215 #define mtcptlbi(reg)   __asm__ __volatile__("tlbi " #reg)
216 #define mtcpat(reg,val) __asm__ __volatile__("at " #reg ",%0"  : : "r" (val))
217 /* CP15 operations */
218 #define mfcp(reg)   ({u64 rval = 0U;\
219             __asm__ __volatile__("mrs   %0, " #reg : "=r" (rval));\
220             rval;\
221             })
222 
223 #define mtcp(reg,val)   __asm__ __volatile__("msr " #reg ",%0"  : : "r" (val))
224 
225 #else
226 /* CP15 operations */
227 #define mtcp(rn, v) __asm__ __volatile__(\
228              "mcr " rn "\n"\
229              : : "r" (v)\
230             );
231 
232 #define mfcp(rn)    ({rt_uint32_t rval = 0U; \
233              __asm__ __volatile__(\
234                "mrc " rn "\n"\
235                : "=r" (rval)\
236              );\
237              rval;\
238              })
239 #endif
240 
241 /************************** Variable Definitions ****************************/
242 
243 /************************** Function Prototypes *****************************/
244 
245 #ifdef __cplusplus
246 }
247 #endif /* __cplusplus */
248 
249 #endif /* XPSEUDO_ASM_GCC_H */
250