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