1 /**************************************************************************//**
2  * @file     cmsis_cp15.h for CMSIS-Core(R)
3  * @brief    CMSIS compiler specific macros, functions, instructions
4  * @version  V1.0.0
5  * @date     17. Oct 2019
6  ******************************************************************************/
7 /*
8  * Copyright (c) 2009-2017 ARM Limited. All rights reserved.
9  * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io>
10  *
11  * SPDX-License-Identifier: Apache-2.0
12  *
13  * Licensed under the Apache License, Version 2.0 (the License); you may
14  * not use this file except in compliance with the License.
15  * You may obtain a copy of the License at
16  *
17  * www.apache.org/licenses/LICENSE-2.0
18  *
19  * Unless required by applicable law or agreed to in writing, software
20  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
21  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  * See the License for the specific language governing permissions and
23  * limitations under the License.
24  */
25 
26 #if   defined ( __ICCARM__ )
27   #pragma system_include         /* treat file as system include file for MISRA check */
28 #elif defined (__clang__)
29   #pragma clang system_header   /* treat file as system include file */
30 #endif
31 
32 #ifndef __CMSIS_CP15_H
33 #define __CMSIS_CP15_H
34 
35 /** \brief  Get ACTLR
36     \return               Auxiliary Control register value
37  */
__get_ACTLR(void)38 __STATIC_FORCEINLINE uint32_t __get_ACTLR(void)
39 {
40   uint32_t result;
41   __get_CP(15, 0, result, 1, 0, 1);
42   return(result);
43 }
44 
45 /** \brief  Set ACTLR
46     \param [in]    actlr  Auxiliary Control value to set
47  */
__set_ACTLR(uint32_t actlr)48 __STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr)
49 {
50   __set_CP(15, 0, actlr, 1, 0, 1);
51 }
52 
53 /** \brief  Get CPACR
54     \return               Coprocessor Access Control register value
55  */
__get_CPACR(void)56 __STATIC_FORCEINLINE uint32_t __get_CPACR(void)
57 {
58   uint32_t result;
59   __get_CP(15, 0, result, 1, 0, 2);
60   return result;
61 }
62 
63 /** \brief  Set CPACR
64     \param [in]    cpacr  Coprocessor Access Control value to set
65  */
__set_CPACR(uint32_t cpacr)66 __STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr)
67 {
68   __set_CP(15, 0, cpacr, 1, 0, 2);
69 }
70 
71 /** \brief  Get DFSR
72     \return               Data Fault Status Register value
73  */
__get_DFSR(void)74 __STATIC_FORCEINLINE uint32_t __get_DFSR(void)
75 {
76   uint32_t result;
77   __get_CP(15, 0, result, 5, 0, 0);
78   return result;
79 }
80 
81 /** \brief  Set DFSR
82     \param [in]    dfsr  Data Fault Status value to set
83  */
__set_DFSR(uint32_t dfsr)84 __STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr)
85 {
86   __set_CP(15, 0, dfsr, 5, 0, 0);
87 }
88 
89 /** \brief  Get IFSR
90     \return               Instruction Fault Status Register value
91  */
__get_IFSR(void)92 __STATIC_FORCEINLINE uint32_t __get_IFSR(void)
93 {
94   uint32_t result;
95   __get_CP(15, 0, result, 5, 0, 1);
96   return result;
97 }
98 
99 /** \brief  Set IFSR
100     \param [in]    ifsr  Instruction Fault Status value to set
101  */
__set_IFSR(uint32_t ifsr)102 __STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr)
103 {
104   __set_CP(15, 0, ifsr, 5, 0, 1);
105 }
106 
107 #if (defined(__CORTEX_R) && (__CORTEX_R == 52U)) || \
108     defined(DOXYGEN)
109 
110 /** \brief  Get ISR
111     \return               Interrupt Status Register value
112  */
__get_ISR(void)113 __STATIC_FORCEINLINE uint32_t __get_ISR(void)
114 {
115   uint32_t result;
116   __get_CP(15, 0, result, 12, 1, 0);
117   return result;
118 }
119 
120 #endif
121 
122 /** \brief  Get CBAR
123     \return               Configuration Base Address register value
124  */
__get_CBAR(void)125 __STATIC_FORCEINLINE uint32_t __get_CBAR(void)
126 {
127   uint32_t result;
128   __get_CP(15, 4, result, 15, 0, 0);
129   return result;
130 }
131 
132 /** \brief  Set SCTLR
133 
134     This function assigns the given value to the System Control Register.
135 
136     \param [in]    sctlr  System Control Register value to set
137  */
__set_SCTLR(uint32_t sctlr)138 __STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr)
139 {
140   __set_CP(15, 0, sctlr, 1, 0, 0);
141 }
142 
143 /** \brief  Get SCTLR
144     \return               System Control Register value
145  */
__get_SCTLR(void)146 __STATIC_FORCEINLINE uint32_t __get_SCTLR(void)
147 {
148   uint32_t result;
149   __get_CP(15, 0, result, 1, 0, 0);
150   return result;
151 }
152 
153 /** \brief  Set ACTRL
154     \param [in]    actrl  Auxiliary Control Register value to set
155  */
__set_ACTRL(uint32_t actrl)156 __STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl)
157 {
158   __set_CP(15, 0, actrl, 1, 0, 1);
159 }
160 
161 /** \brief  Get ACTRL
162     \return               Auxiliary Control Register value
163  */
__get_ACTRL(void)164 __STATIC_FORCEINLINE uint32_t __get_ACTRL(void)
165 {
166   uint32_t result;
167   __get_CP(15, 0, result, 1, 0, 1);
168   return result;
169 }
170 
171 /** \brief  Get MPIDR
172 
173     This function returns the value of the Multiprocessor Affinity Register.
174 
175     \return               Multiprocessor Affinity Register value
176  */
__get_MPIDR(void)177 __STATIC_FORCEINLINE uint32_t __get_MPIDR(void)
178 {
179   uint32_t result;
180   __get_CP(15, 0, result, 0, 0, 5);
181   return result;
182 }
183 
184 /** \brief  Get VBAR
185 
186     This function returns the value of the Vector Base Address Register.
187 
188     \return               Vector Base Address Register
189  */
__get_VBAR(void)190 __STATIC_FORCEINLINE uint32_t __get_VBAR(void)
191 {
192   uint32_t result;
193   __get_CP(15, 0, result, 12, 0, 0);
194   return result;
195 }
196 
197 /** \brief  Set VBAR
198 
199     This function assigns the given value to the Vector Base Address Register.
200 
201     \param [in]    vbar  Vector Base Address Register value to set
202  */
__set_VBAR(uint32_t vbar)203 __STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar)
204 {
205   __set_CP(15, 0, vbar, 12, 0, 0);
206 }
207 
208 #if (defined(__CORTEX_R) && (__CORTEX_R == 52U) && \
209     defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \
210     defined(DOXYGEN)
211 
212 /** \brief  Set CNTFRQ
213 
214   This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
215 
216   \param [in]    value  CNTFRQ Register value to set
217 */
__set_CNTFRQ(uint32_t value)218 __STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value)
219 {
220   __set_CP(15, 0, value, 14, 0, 0);
221 }
222 
223 /** \brief  Get CNTFRQ
224 
225     This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
226 
227     \return               CNTFRQ Register value
228  */
__get_CNTFRQ(void)229 __STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void)
230 {
231   uint32_t result;
232   __get_CP(15, 0, result, 14, 0 , 0);
233   return result;
234 }
235 
236 /** \brief  Set CNTP_TVAL
237 
238   This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
239 
240   \param [in]    value  CNTP_TVAL Register value to set
241 */
__set_CNTP_TVAL(uint32_t value)242 __STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value)
243 {
244   __set_CP(15, 0, value, 14, 2, 0);
245 }
246 
247 /** \brief  Get CNTP_TVAL
248 
249     This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
250 
251     \return               CNTP_TVAL Register value
252  */
__get_CNTP_TVAL(void)253 __STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void)
254 {
255   uint32_t result;
256   __get_CP(15, 0, result, 14, 2, 0);
257   return result;
258 }
259 
260 /** \brief  Get CNTPCT
261 
262     This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT).
263 
264     \return               CNTPCT Register value
265  */
__get_CNTPCT(void)266 __STATIC_FORCEINLINE uint64_t __get_CNTPCT(void)
267 {
268   uint64_t result;
269   __get_CP64(15, 0, result, 14);
270   return result;
271 }
272 
273 /** \brief  Set CNTP_CVAL
274 
275   This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
276 
277   \param [in]    value  CNTP_CVAL Register value to set
278 */
__set_CNTP_CVAL(uint64_t value)279 __STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value)
280 {
281   __set_CP64(15, 2, value, 14);
282 }
283 
284 /** \brief  Get CNTP_CVAL
285 
286     This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL).
287 
288     \return               CNTP_CVAL Register value
289  */
__get_CNTP_CVAL(void)290 __STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void)
291 {
292   uint64_t result;
293   __get_CP64(15, 2, result, 14);
294   return result;
295 }
296 
297 /** \brief  Set CNTP_CTL
298 
299   This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
300 
301   \param [in]    value  CNTP_CTL Register value to set
302 */
__set_CNTP_CTL(uint32_t value)303 __STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value)
304 {
305   __set_CP(15, 0, value, 14, 2, 1);
306 }
307 
308 /** \brief  Get CNTP_CTL register
309     \return               CNTP_CTL Register value
310  */
__get_CNTP_CTL(void)311 __STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void)
312 {
313   uint32_t result;
314   __get_CP(15, 0, result, 14, 2, 1);
315   return result;
316 }
317 
318 #endif
319 
320 /** \brief  Set BPIALL.
321 
322   Branch Predictor Invalidate All
323  */
__set_BPIALL(uint32_t value)324 __STATIC_FORCEINLINE void __set_BPIALL(uint32_t value)
325 {
326   __set_CP(15, 0, value, 7, 5, 6);
327 }
328 
329 /** \brief  Set ICIALLU
330 
331   Instruction Cache Invalidate All
332  */
__set_ICIALLU(uint32_t value)333 __STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value)
334 {
335   __set_CP(15, 0, value, 7, 5, 0);
336 }
337 
338 /** \brief  Set DCCMVAC
339 
340   Data cache clean
341  */
__set_DCCMVAC(uint32_t value)342 __STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value)
343 {
344   __set_CP(15, 0, value, 7, 10, 1);
345 }
346 
347 /** \brief  Set DCIMVAC
348 
349   Data cache invalidate
350  */
__set_DCIMVAC(uint32_t value)351 __STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value)
352 {
353   __set_CP(15, 0, value, 7, 6, 1);
354 }
355 
356 /** \brief  Set DCCIMVAC
357 
358   Data cache clean and invalidate
359  */
__set_DCCIMVAC(uint32_t value)360 __STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value)
361 {
362   __set_CP(15, 0, value, 7, 14, 1);
363 }
364 
365 /** \brief  Set CSSELR
366  */
__set_CSSELR(uint32_t value)367 __STATIC_FORCEINLINE void __set_CSSELR(uint32_t value)
368 {
369 //  __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory");
370   __set_CP(15, 2, value, 0, 0, 0);
371 }
372 
373 /** \brief  Get CSSELR
374     \return CSSELR Register value
375  */
__get_CSSELR(void)376 __STATIC_FORCEINLINE uint32_t __get_CSSELR(void)
377 {
378   uint32_t result;
379 //  __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory");
380   __get_CP(15, 2, result, 0, 0, 0);
381   return result;
382 }
383 
384 /** \brief  Set CCSIDR
385     \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead.
386  */
387 CMSIS_DEPRECATED
__set_CCSIDR(uint32_t value)388 __STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value)
389 {
390   __set_CSSELR(value);
391 }
392 
393 /** \brief  Get CCSIDR
394     \return CCSIDR Register value
395  */
__get_CCSIDR(void)396 __STATIC_FORCEINLINE uint32_t __get_CCSIDR(void)
397 {
398   uint32_t result;
399 //  __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory");
400   __get_CP(15, 1, result, 0, 0, 0);
401   return result;
402 }
403 
404 /** \brief  Get CLIDR
405     \return CLIDR Register value
406  */
__get_CLIDR(void)407 __STATIC_FORCEINLINE uint32_t __get_CLIDR(void)
408 {
409   uint32_t result;
410 //  __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory");
411   __get_CP(15, 1, result, 0, 0, 1);
412   return result;
413 }
414 
415 /** \brief  Set DCISW
416  */
__set_DCISW(uint32_t value)417 __STATIC_FORCEINLINE void __set_DCISW(uint32_t value)
418 {
419 //  __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory")
420   __set_CP(15, 0, value, 7, 6, 2);
421 }
422 
423 /** \brief  Set DCCSW
424  */
__set_DCCSW(uint32_t value)425 __STATIC_FORCEINLINE void __set_DCCSW(uint32_t value)
426 {
427 //  __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory")
428   __set_CP(15, 0, value, 7, 10, 2);
429 }
430 
431 /** \brief  Set DCCISW
432  */
__set_DCCISW(uint32_t value)433 __STATIC_FORCEINLINE void __set_DCCISW(uint32_t value)
434 {
435 //  __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory")
436   __set_CP(15, 0, value, 7, 14, 2);
437 }
438 
439 #endif
440