source: rtems/cpukit/score/cpu/arm/include/rtems/score/armv7m.h @ 5ad17be9

Last change on this file since 5ad17be9 was 5ad17be9, checked in by Christian Mauderer <christian.mauderer@…>, on 05/28/21 at 14:58:49

cpu/armv7m: Avoid regions with negative size

Don't initialze regions that have a negative size (for example due to a
wrong calculation).

Update #4450

  • Property mode set to 100644
File size: 19.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief ARMV7M Architecture Support
5 */
6
7/*
8 * Copyright (c) 2011-2014 Sebastian Huber.  All rights reserved.
9 *
10 *  embedded brains GmbH
11 *  Obere Lagerstr. 30
12 *  82178 Puchheim
13 *  Germany
14 *  <rtems@embedded-brains.de>
15 *
16 * The license and distribution terms for this file may be
17 * found in the file LICENSE in this distribution or at
18 * http://www.rtems.org/license/LICENSE.
19 */
20
21#ifndef RTEMS_SCORE_ARMV7M_H
22#define RTEMS_SCORE_ARMV7M_H
23
24#include <rtems/score/cpu.h>
25#ifndef ASM
26#include <rtems/score/assert.h>
27#endif
28
29#ifdef __cplusplus
30extern "C" {
31#endif /* __cplusplus */
32
33#ifdef ARM_MULTILIB_ARCH_V7M
34
35/* Coprocessor Access Control Register, CPACR */
36#define ARMV7M_CPACR 0xe000ed88
37
38#ifndef ASM
39
40typedef struct {
41  uint32_t reserved_0;
42  uint32_t ictr;
43  uint32_t actlr;
44  uint32_t reserved_1;
45} ARMV7M_ICTAC;
46
47typedef void (*ARMV7M_Exception_handler)(void);
48
49typedef struct {
50  uint32_t register_r0;
51  uint32_t register_r1;
52  uint32_t register_r2;
53  uint32_t register_r3;
54  uint32_t register_r12;
55  void *register_lr;
56  void *register_pc;
57  uint32_t register_xpsr;
58#ifdef ARM_MULTILIB_VFP
59  uint32_t register_s0;
60  uint32_t register_s1;
61  uint32_t register_s2;
62  uint32_t register_s3;
63  uint32_t register_s4;
64  uint32_t register_s5;
65  uint32_t register_s6;
66  uint32_t register_s7;
67  uint32_t register_s8;
68  uint32_t register_s9;
69  uint32_t register_s10;
70  uint32_t register_s11;
71  uint32_t register_s12;
72  uint32_t register_s13;
73  uint32_t register_s14;
74  uint32_t register_s15;
75  uint32_t register_fpscr;
76  uint32_t reserved;
77#endif
78} ARMV7M_Exception_frame;
79
80typedef struct {
81  uint32_t comp;
82  uint32_t mask;
83  uint32_t function;
84  uint32_t reserved;
85} ARMV7M_DWT_comparator;
86
87typedef struct {
88#define ARMV7M_DWT_CTRL_NOCYCCNT (1U << 25)
89#define ARMV7M_DWT_CTRL_CYCCNTENA (1U << 0)
90  uint32_t ctrl;
91  uint32_t cyccnt;
92  uint32_t cpicnt;
93  uint32_t exccnt;
94  uint32_t sleepcnt;
95  uint32_t lsucnt;
96  uint32_t foldcnt;
97  uint32_t pcsr;
98  ARMV7M_DWT_comparator comparator[249];
99#define ARMV7M_DWT_LAR_UNLOCK_MAGIC 0xc5acce55U
100  uint32_t lar;
101  uint32_t lsr;
102} ARMV7M_DWT;
103
104typedef struct {
105  uint32_t cpuid;
106
107#define ARMV7M_SCB_ICSR_NMIPENDSET (1U << 31)
108#define ARMV7M_SCB_ICSR_PENDSVSET (1U << 28)
109#define ARMV7M_SCB_ICSR_PENDSVCLR (1U << 27)
110#define ARMV7M_SCB_ICSR_PENDSTSET (1U << 26)
111#define ARMV7M_SCB_ICSR_PENDSTCLR (1U << 25)
112#define ARMV7M_SCB_ICSR_ISRPREEMPT (1U << 23)
113#define ARMV7M_SCB_ICSR_ISRPENDING (1U << 22)
114#define ARMV7M_SCB_ICSR_VECTPENDING_GET(reg) (((reg) >> 12) & 0x1ffU)
115#define ARMV7M_SCB_ICSR_RETTOBASE (1U << 11)
116#define ARMV7M_SCB_ICSR_VECTACTIVE_GET(reg) ((reg) & 0x1ffU)
117  uint32_t icsr;
118
119  ARMV7M_Exception_handler *vtor;
120
121#define ARMV7M_SCB_AIRCR_VECTKEY (0x05fa << 16)
122#define ARMV7M_SCB_AIRCR_ENDIANESS (1U << 15)
123#define ARMV7M_SCB_AIRCR_PRIGROUP_SHIFT 8
124#define ARMV7M_SCB_AIRCR_PRIGROUP_MASK \
125  ((0x7U) << ARMV7M_SCB_AIRCR_PRIGROUP_SHIFT)
126#define ARMV7M_SCB_AIRCR_PRIGROUP(val) \
127  (((val) << ARMV7M_SCB_AIRCR_PRIGROUP_SHIFT) & ARMV7M_SCB_AIRCR_PRIGROUP_MASK)
128#define ARMV7M_SCB_AIRCR_PRIGROUP_GET(reg) \
129  (((val) & ARMV7M_SCB_AIRCR_PRIGROUP_MASK) >> ARMV7M_SCB_AIRCR_PRIGROUP_SHIFT)
130#define ARMV7M_SCB_AIRCR_PRIGROUP_SET(reg, val) \
131  (((reg) & ~ARMV7M_SCB_AIRCR_PRIGROUP_MASK) | ARMV7M_SCB_AIRCR_PRIGROUP(val))
132#define ARMV7M_SCB_AIRCR_SYSRESETREQ (1U << 2)
133#define ARMV7M_SCB_AIRCR_VECTCLRACTIVE (1U << 1)
134#define ARMV7M_SCB_AIRCR_VECTRESET (1U << 0)
135  uint32_t aircr;
136
137  uint32_t scr;
138  uint32_t ccr;
139  uint8_t shpr [12];
140
141#define ARMV7M_SCB_SHCSR_USGFAULTENA (1U << 18)
142#define ARMV7M_SCB_SHCSR_BUSFAULTENA (1U << 17)
143#define ARMV7M_SCB_SHCSR_MEMFAULTENA (1U << 16)
144  uint32_t shcsr;
145
146  uint32_t cfsr;
147  uint32_t hfsr;
148  uint32_t dfsr;
149  uint32_t mmfar;
150  uint32_t bfar;
151  uint32_t afsr;
152  uint32_t reserved_e000ed40[18];
153  uint32_t cpacr;
154  uint32_t reserved_e000ed8c[106];
155  uint32_t fpccr;
156  uint32_t fpcar;
157  uint32_t fpdscr;
158  uint32_t mvfr0;
159  uint32_t mvfr1;
160} ARMV7M_SCB;
161
162typedef struct {
163#define ARMV7M_SYSTICK_CSR_COUNTFLAG (1U << 16)
164#define ARMV7M_SYSTICK_CSR_CLKSOURCE (1U << 2)
165#define ARMV7M_SYSTICK_CSR_TICKINT (1U << 1)
166#define ARMV7M_SYSTICK_CSR_ENABLE (1U << 0)
167  uint32_t csr;
168
169  uint32_t rvr;
170  uint32_t cvr;
171
172#define ARMV7M_SYSTICK_CALIB_NOREF (1U << 31)
173#define ARMV7M_SYSTICK_CALIB_SKEW (1U << 30)
174#define ARMV7M_SYSTICK_CALIB_TENMS_GET(reg) ((reg) & 0xffffffU)
175  uint32_t calib;
176} ARMV7M_Systick;
177
178typedef struct {
179  uint32_t iser [8];
180  uint32_t reserved_0 [24];
181  uint32_t icer [8];
182  uint32_t reserved_1 [24];
183  uint32_t ispr [8];
184  uint32_t reserved_2 [24];
185  uint32_t icpr [8];
186  uint32_t reserved_3 [24];
187  uint32_t iabr [8];
188  uint32_t reserved_4 [56];
189  uint8_t  ipr [240];
190  uint32_t reserved_5 [644];
191  uint32_t stir;
192} ARMV7M_NVIC;
193
194typedef struct {
195#define ARMV7M_MPU_TYPE_IREGION_GET(reg) (((reg) >> 16) & 0xffU)
196#define ARMV7M_MPU_TYPE_DREGION_GET(reg) (((reg) >> 8) & 0xffU)
197#define ARMV7M_MPU_TYPE_SEPARATE (1U << 0)
198  uint32_t type;
199
200#define ARMV7M_MPU_CTRL_PRIVDEFENA (1U << 2)
201#define ARMV7M_MPU_CTRL_HFNMIENA (1U << 1)
202#define ARMV7M_MPU_CTRL_ENABLE (1U << 0)
203  uint32_t ctrl;
204
205  uint32_t rnr;
206
207#define ARMV7M_MPU_RBAR_ADDR_SHIFT 5
208#define ARMV7M_MPU_RBAR_ADDR_MASK \
209  ((0x7ffffffU) << ARMV7M_MPU_RBAR_ADDR_SHIFT)
210#define ARMV7M_MPU_RBAR_ADDR(val) \
211  (((val) << ARMV7M_MPU_RBAR_ADDR_SHIFT) & ARMV7M_MPU_RBAR_ADDR_MASK)
212#define ARMV7M_MPU_RBAR_ADDR_GET(reg) \
213  (((val) & ARMV7M_MPU_RBAR_ADDR_MASK) >> ARMV7M_MPU_RBAR_ADDR_SHIFT)
214#define ARMV7M_MPU_RBAR_ADDR_SET(reg, val) \
215  (((reg) & ~ARMV7M_MPU_RBAR_ADDR_MASK) | ARMV7M_MPU_RBAR_ADDR(val))
216#define ARMV7M_MPU_RBAR_VALID (1U << 4)
217#define ARMV7M_MPU_RBAR_REGION_SHIFT 0
218#define ARMV7M_MPU_RBAR_REGION_MASK \
219  ((0xfU) << ARMV7M_MPU_RBAR_REGION_SHIFT)
220#define ARMV7M_MPU_RBAR_REGION(val) \
221  (((val) << ARMV7M_MPU_RBAR_REGION_SHIFT) & ARMV7M_MPU_RBAR_REGION_MASK)
222#define ARMV7M_MPU_RBAR_REGION_GET(reg) \
223  (((val) & ARMV7M_MPU_RBAR_REGION_MASK) >> ARMV7M_MPU_RBAR_REGION_SHIFT)
224#define ARMV7M_MPU_RBAR_REGION_SET(reg, val) \
225  (((reg) & ~ARMV7M_MPU_RBAR_REGION_MASK) | ARMV7M_MPU_RBAR_REGION(val))
226  uint32_t rbar;
227
228#define ARMV7M_MPU_RASR_XN (1U << 28)
229#define ARMV7M_MPU_RASR_AP_SHIFT 24
230#define ARMV7M_MPU_RASR_AP_MASK \
231  ((0x7U) << ARMV7M_MPU_RASR_AP_SHIFT)
232#define ARMV7M_MPU_RASR_AP(val) \
233  (((val) << ARMV7M_MPU_RASR_AP_SHIFT) & ARMV7M_MPU_RASR_AP_MASK)
234#define ARMV7M_MPU_RASR_AP_GET(reg) \
235  (((val) & ARMV7M_MPU_RASR_AP_MASK) >> ARMV7M_MPU_RASR_AP_SHIFT)
236#define ARMV7M_MPU_RASR_AP_SET(reg, val) \
237  (((reg) & ~ARMV7M_MPU_RASR_AP_MASK) | ARMV7M_MPU_RASR_AP(val))
238#define ARMV7M_MPU_RASR_TEX_SHIFT 19
239#define ARMV7M_MPU_RASR_TEX_MASK \
240  ((0x7U) << ARMV7M_MPU_RASR_TEX_SHIFT)
241#define ARMV7M_MPU_RASR_TEX(val) \
242  (((val) << ARMV7M_MPU_RASR_TEX_SHIFT) & ARMV7M_MPU_RASR_TEX_MASK)
243#define ARMV7M_MPU_RASR_TEX_GET(reg) \
244  (((val) & ARMV7M_MPU_RASR_TEX_MASK) >> ARMV7M_MPU_RASR_TEX_SHIFT)
245#define ARMV7M_MPU_RASR_TEX_SET(reg, val) \
246  (((reg) & ~ARMV7M_MPU_RASR_TEX_MASK) | ARMV7M_MPU_RASR_TEX(val))
247#define ARMV7M_MPU_RASR_S (1U << 18)
248#define ARMV7M_MPU_RASR_C (1U << 17)
249#define ARMV7M_MPU_RASR_B (1U << 16)
250#define ARMV7M_MPU_RASR_SRD_SHIFT 8
251#define ARMV7M_MPU_RASR_SRD_MASK \
252  ((0xffU) << ARMV7M_MPU_RASR_SRD_SHIFT)
253#define ARMV7M_MPU_RASR_SRD(val) \
254  (((val) << ARMV7M_MPU_RASR_SRD_SHIFT) & ARMV7M_MPU_RASR_SRD_MASK)
255#define ARMV7M_MPU_RASR_SRD_GET(reg) \
256  (((val) & ARMV7M_MPU_RASR_SRD_MASK) >> ARMV7M_MPU_RASR_SRD_SHIFT)
257#define ARMV7M_MPU_RASR_SRD_SET(reg, val) \
258  (((reg) & ~ARMV7M_MPU_RASR_SRD_MASK) | ARMV7M_MPU_RASR_SRD(val))
259#define ARMV7M_MPU_RASR_SIZE_SHIFT 1
260#define ARMV7M_MPU_RASR_SIZE_MASK \
261  ((0x1fU) << ARMV7M_MPU_RASR_SIZE_SHIFT)
262#define ARMV7M_MPU_RASR_SIZE(val) \
263  (((val) << ARMV7M_MPU_RASR_SIZE_SHIFT) & ARMV7M_MPU_RASR_SIZE_MASK)
264#define ARMV7M_MPU_RASR_SIZE_GET(reg) \
265  (((val) & ARMV7M_MPU_RASR_SIZE_MASK) >> ARMV7M_MPU_RASR_SIZE_SHIFT)
266#define ARMV7M_MPU_RASR_SIZE_SET(reg, val) \
267  (((reg) & ~ARMV7M_MPU_RASR_SIZE_MASK) | ARMV7M_MPU_RASR_SIZE(val))
268#define ARMV7M_MPU_RASR_ENABLE (1U << 0)
269  uint32_t rasr;
270
271  uint32_t rbar_a1;
272  uint32_t rasr_a1;
273  uint32_t rbar_a2;
274  uint32_t rasr_a2;
275  uint32_t rbar_a3;
276  uint32_t rasr_a3;
277} ARMV7M_MPU;
278
279typedef enum {
280  ARMV7M_MPU_AP_PRIV_NO_USER_NO,
281  ARMV7M_MPU_AP_PRIV_RW_USER_NO,
282  ARMV7M_MPU_AP_PRIV_RW_USER_RO,
283  ARMV7M_MPU_AP_PRIV_RW_USER_RW,
284  ARMV7M_MPU_AP_PRIV_RO_USER_NO = 0x5,
285  ARMV7M_MPU_AP_PRIV_RO_USER_RO,
286} ARMV7M_MPU_Access_permissions;
287
288typedef enum {
289  ARMV7M_MPU_ATTR_R = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_RO_USER_NO)
290    | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_XN,
291  ARMV7M_MPU_ATTR_RW = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_RW_USER_NO)
292    | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_XN | ARMV7M_MPU_RASR_B,
293  ARMV7M_MPU_ATTR_RWX = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_RW_USER_NO)
294    | ARMV7M_MPU_RASR_C | ARMV7M_MPU_RASR_B,
295  ARMV7M_MPU_ATTR_X = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_NO_USER_NO)
296    | ARMV7M_MPU_RASR_C,
297  ARMV7M_MPU_ATTR_RX = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_RO_USER_NO)
298    | ARMV7M_MPU_RASR_C,
299  ARMV7M_MPU_ATTR_IO = ARMV7M_MPU_RASR_AP(ARMV7M_MPU_AP_PRIV_RW_USER_NO)
300    | ARMV7M_MPU_RASR_XN,
301} ARMV7M_MPU_Attributes;
302
303typedef enum {
304  ARMV7M_MPU_SIZE_32_B = 0x4,
305  ARMV7M_MPU_SIZE_64_B,
306  ARMV7M_MPU_SIZE_128_B,
307  ARMV7M_MPU_SIZE_256_B,
308  ARMV7M_MPU_SIZE_512_B,
309  ARMV7M_MPU_SIZE_1_KB,
310  ARMV7M_MPU_SIZE_2_KB,
311  ARMV7M_MPU_SIZE_4_KB,
312  ARMV7M_MPU_SIZE_8_KB,
313  ARMV7M_MPU_SIZE_16_KB,
314  ARMV7M_MPU_SIZE_32_KB,
315  ARMV7M_MPU_SIZE_64_KB,
316  ARMV7M_MPU_SIZE_128_KB,
317  ARMV7M_MPU_SIZE_256_KB,
318  ARMV7M_MPU_SIZE_512_KB,
319  ARMV7M_MPU_SIZE_1_MB,
320  ARMV7M_MPU_SIZE_2_MB,
321  ARMV7M_MPU_SIZE_4_MB,
322  ARMV7M_MPU_SIZE_8_MB,
323  ARMV7M_MPU_SIZE_16_MB,
324  ARMV7M_MPU_SIZE_32_MB,
325  ARMV7M_MPU_SIZE_64_MB,
326  ARMV7M_MPU_SIZE_128_MB,
327  ARMV7M_MPU_SIZE_256_MB,
328  ARMV7M_MPU_SIZE_512_MB,
329  ARMV7M_MPU_SIZE_1_GB,
330  ARMV7M_MPU_SIZE_2_GB,
331  ARMV7M_MPU_SIZE_4_GB
332} ARMV7M_MPU_Size;
333
334typedef struct {
335  uint32_t rbar;
336  uint32_t rasr;
337} ARMV7M_MPU_Region;
338
339#define ARMV7M_MPU_REGION_INITIALIZER(idx, addr, size, attr) \
340  { \
341    ((addr) & ARMV7M_MPU_RBAR_ADDR_MASK) \
342      | ARMV7M_MPU_RBAR_VALID \
343      | ARMV7M_MPU_RBAR_REGION(idx), \
344    ARMV7M_MPU_RASR_SIZE(size) | (attr) | ARMV7M_MPU_RASR_ENABLE \
345  }
346
347#define ARMV7M_MPU_REGION_DISABLED_INITIALIZER(idx) \
348  { \
349    ARMV7M_MPU_RBAR_VALID | ARMV7M_MPU_RBAR_REGION(idx), \
350    0 \
351  }
352
353/**
354 * Higher level region configuration.
355 *
356 * Allows to configure with begin and end which is more convenient for
357 * calculating the sizes from linker command file. Note that you still have to
358 * follow the following rules:
359 *
360 * - Begin address has to be aligned to 0x20 (lower 5 bits set to 0)
361 * - Sizes can only be a value of 2^x with a minimum of 32 Byte. If you have an
362 *   end address that is not aligned, the region will get bigger.
363 * - Later regions have higher priority.
364 */
365typedef struct {
366  const void *begin;
367  const void *end;
368  uint32_t rasr;
369} ARMV7M_MPU_Region_config;
370
371typedef struct {
372  uint32_t dhcsr;
373  uint32_t dcrsr;
374  uint32_t dcrdr;
375#define ARMV7M_DEBUG_DEMCR_VC_CORERESET (1U << 0)
376#define ARMV7M_DEBUG_DEMCR_VC_MMERR (1U << 4)
377#define ARMV7M_DEBUG_DEMCR_VC_NOCPERR (1U << 5)
378#define ARMV7M_DEBUG_DEMCR_VC_CHKERR (1U << 6)
379#define ARMV7M_DEBUG_DEMCR_VC_STATERR (1U << 7)
380#define ARMV7M_DEBUG_DEMCR_VC_BUSERR (1U << 8)
381#define ARMV7M_DEBUG_DEMCR_VC_INTERR (1U << 9)
382#define ARMV7M_DEBUG_DEMCR_VC_HARDERR (1U << 10)
383#define ARMV7M_DEBUG_DEMCR_MON_EN (1U << 16)
384#define ARMV7M_DEBUG_DEMCR_MON_PEND (1U << 17)
385#define ARMV7M_DEBUG_DEMCR_MON_STEP (1U << 18)
386#define ARMV7M_DEBUG_DEMCR_MON_REQ (1U << 19)
387#define ARMV7M_DEBUG_DEMCR_TRCENA (1U << 24)
388  uint32_t demcr;
389} ARMV7M_DEBUG;
390
391#define ARMV7M_DWT_BASE 0xe0001000
392#define ARMV7M_SCS_BASE 0xe000e000
393#define ARMV7M_ICTAC_BASE (ARMV7M_SCS_BASE + 0x0)
394#define ARMV7M_SYSTICK_BASE (ARMV7M_SCS_BASE + 0x10)
395#define ARMV7M_NVIC_BASE (ARMV7M_SCS_BASE + 0x100)
396#define ARMV7M_SCB_BASE (ARMV7M_SCS_BASE + 0xd00)
397#define ARMV7M_MPU_BASE (ARMV7M_SCS_BASE + 0xd90)
398#define ARMV7M_DEBUG_BASE (ARMV7M_SCS_BASE + 0xdf0)
399
400#define _ARMV7M_DWT \
401  ((volatile ARMV7M_DWT *) ARMV7M_DWT_BASE)
402#define _ARMV7M_ICTAC \
403  ((volatile ARMV7M_ICTAC *) ARMV7M_ICTAC_BASE)
404#define _ARMV7M_SCB \
405  ((volatile ARMV7M_SCB *) ARMV7M_SCB_BASE)
406#define _ARMV7M_Systick \
407  ((volatile ARMV7M_Systick *) ARMV7M_SYSTICK_BASE)
408#define _ARMV7M_NVIC \
409  ((volatile ARMV7M_NVIC *) ARMV7M_NVIC_BASE)
410#define _ARMV7M_MPU \
411  ((volatile ARMV7M_MPU *) ARMV7M_MPU_BASE)
412#define _ARMV7M_DEBUG \
413  ((volatile ARMV7M_DEBUG *) ARMV7M_DEBUG_BASE)
414
415#define ARMV7M_VECTOR_MSP 0
416#define ARMV7M_VECTOR_RESET 1
417#define ARMV7M_VECTOR_NMI 2
418#define ARMV7M_VECTOR_HARD_FAULT 3
419#define ARMV7M_VECTOR_MEM_MANAGE 4
420#define ARMV7M_VECTOR_BUS_FAULT 5
421#define ARMV7M_VECTOR_USAGE_FAULT 6
422#define ARMV7M_VECTOR_SVC 11
423#define ARMV7M_VECTOR_DEBUG_MONITOR 12
424#define ARMV7M_VECTOR_PENDSV 14
425#define ARMV7M_VECTOR_SYSTICK 15
426#define ARMV7M_VECTOR_IRQ(n) ((n) + 16)
427#define ARMV7M_IRQ_OF_VECTOR(n) ((n) - 16)
428
429#define ARMV7M_EXCEPTION_PRIORITY_LOWEST 255
430
431static inline bool _ARMV7M_Is_vector_an_irq( int vector )
432{
433  /* External (i.e. non-system) IRQs start after the SysTick vector. */
434  return vector > ARMV7M_VECTOR_SYSTICK;
435}
436
437static inline uint32_t _ARMV7M_Get_basepri(void)
438{
439  uint32_t val;
440  __asm__ volatile ("mrs %[val], basepri\n" : [val] "=&r" (val));
441  return val;
442}
443
444static inline void _ARMV7M_Set_basepri(uint32_t val)
445{
446  __asm__ volatile ("msr basepri, %[val]\n" : : [val] "r" (val));
447}
448
449static inline uint32_t _ARMV7M_Get_primask(void)
450{
451  uint32_t val;
452  __asm__ volatile ("mrs %[val], primask\n" : [val] "=&r" (val));
453  return val;
454}
455
456static inline void _ARMV7M_Set_primask(uint32_t val)
457{
458  __asm__ volatile ("msr primask, %[val]\n" : : [val] "r" (val));
459}
460
461static inline uint32_t _ARMV7M_Get_faultmask(void)
462{
463  uint32_t val;
464  __asm__ volatile ("mrs %[val], faultmask\n" : [val] "=&r" (val));
465  return val;
466}
467
468static inline void _ARMV7M_Set_faultmask(uint32_t val)
469{
470  __asm__ volatile ("msr faultmask, %[val]\n" : : [val] "r" (val));
471}
472
473static inline uint32_t _ARMV7M_Get_control(void)
474{
475  uint32_t val;
476  __asm__ volatile ("mrs %[val], control\n" : [val] "=&r" (val));
477  return val;
478}
479
480static inline void _ARMV7M_Set_control(uint32_t val)
481{
482  __asm__ volatile ("msr control, %[val]\n" : : [val] "r" (val));
483}
484
485static inline uint32_t _ARMV7M_Get_MSP(void)
486{
487  uint32_t val;
488  __asm__ volatile ("mrs %[val], msp\n" : [val] "=&r" (val));
489  return val;
490}
491
492static inline void _ARMV7M_Set_MSP(uint32_t val)
493{
494  __asm__ volatile ("msr msp, %[val]\n" : : [val] "r" (val));
495}
496
497static inline uint32_t _ARMV7M_Get_PSP(void)
498{
499  uint32_t val;
500  __asm__ volatile ("mrs %[val], psp\n" : [val] "=&r" (val));
501  return val;
502}
503
504static inline void _ARMV7M_Set_PSP(uint32_t val)
505{
506  __asm__ volatile ("msr psp, %[val]\n" : : [val] "r" (val));
507}
508
509static inline uint32_t _ARMV7M_Get_XPSR(void)
510{
511  uint32_t val;
512  __asm__ volatile ("mrs %[val], xpsr\n" : [val] "=&r" (val));
513  return val;
514}
515
516static inline bool _ARMV7M_NVIC_Is_enabled( int irq )
517{
518  int index = irq >> 5;
519  uint32_t bit = 1U << (irq & 0x1f);
520
521  return (_ARMV7M_NVIC->iser [index] & bit) != 0;
522}
523
524static inline void _ARMV7M_NVIC_Set_enable( int irq )
525{
526  int index = irq >> 5;
527  uint32_t bit = 1U << (irq & 0x1f);
528
529  _ARMV7M_NVIC->iser [index] = bit;
530}
531
532static inline void _ARMV7M_NVIC_Clear_enable( int irq )
533{
534  int index = irq >> 5;
535  uint32_t bit = 1U << (irq & 0x1f);
536
537  _ARMV7M_NVIC->icer [index] = bit;
538}
539
540static inline bool _ARMV7M_NVIC_Is_pending( int irq )
541{
542  int index = irq >> 5;
543  uint32_t bit = 1U << (irq & 0x1f);
544
545  return (_ARMV7M_NVIC->ispr [index] & bit) != 0;
546}
547
548static inline void _ARMV7M_NVIC_Set_pending( int irq )
549{
550  int index = irq >> 5;
551  uint32_t bit = 1U << (irq & 0x1f);
552
553  _ARMV7M_NVIC->ispr [index] = bit;
554}
555
556static inline void _ARMV7M_NVIC_Clear_pending( int irq )
557{
558  int index = irq >> 5;
559  uint32_t bit = 1U << (irq & 0x1f);
560
561  _ARMV7M_NVIC->icpr [index] = bit;
562}
563
564static inline bool _ARMV7M_NVIC_Is_active( int irq )
565{
566  int index = irq >> 5;
567  uint32_t bit = 1U << (irq & 0x1f);
568
569  return (_ARMV7M_NVIC->iabr [index] & bit) != 0;
570}
571
572static inline void _ARMV7M_NVIC_Set_priority( int irq, int priority )
573{
574  _ARMV7M_NVIC->ipr [irq] = (uint8_t) priority;
575}
576
577static inline int _ARMV7M_NVIC_Get_priority( int irq )
578{
579  return _ARMV7M_NVIC->ipr [irq];
580}
581
582static inline bool _ARMV7M_DWT_Enable_CYCCNT( void )
583{
584  uint32_t demcr;
585  uint32_t dwt_ctrl;
586
587  demcr = _ARMV7M_DEBUG->demcr;
588  _ARMV7M_DEBUG->demcr = demcr | ARMV7M_DEBUG_DEMCR_TRCENA;
589  _ARM_Data_synchronization_barrier();
590
591  dwt_ctrl = _ARMV7M_DWT->ctrl;
592  if ((dwt_ctrl & ARMV7M_DWT_CTRL_NOCYCCNT) == 0) {
593    _ARMV7M_DWT->lar = ARMV7M_DWT_LAR_UNLOCK_MAGIC;
594    _ARM_Data_synchronization_barrier();
595    _ARMV7M_DWT->ctrl = dwt_ctrl | ARMV7M_DWT_CTRL_CYCCNTENA;
596    return true;
597  } else {
598    _ARMV7M_DEBUG->demcr = demcr;
599    return false;
600  }
601}
602
603int _ARMV7M_Get_exception_priority( int vector );
604
605void _ARMV7M_Set_exception_priority( int vector, int priority );
606
607ARMV7M_Exception_handler _ARMV7M_Get_exception_handler( int index );
608
609void _ARMV7M_Set_exception_handler(
610  int index,
611  ARMV7M_Exception_handler handler
612);
613
614/**
615 * @brief ARMV7M set exception priority and handler.
616 */
617void _ARMV7M_Set_exception_priority_and_handler(
618  int index,
619  int priority,
620  ARMV7M_Exception_handler handler
621);
622
623void _ARMV7M_Exception_default( void );
624
625void _ARMV7M_Interrupt_service_enter( void );
626
627void _ARMV7M_Interrupt_service_leave( void );
628
629void _ARMV7M_Pendable_service_call( void );
630
631void _ARMV7M_Supervisor_call( void );
632
633void _ARMV7M_Clock_handler( void );
634
635static inline uint32_t _ARMV7M_MPU_Get_region_size(uintptr_t size)
636{
637  if ((size & (size - 1)) == 0) {
638    return ARMV7M_MPU_RASR_SIZE(30 - __builtin_clz(size));
639  } else {
640    return ARMV7M_MPU_RASR_SIZE(31 - __builtin_clz(size));
641  }
642}
643
644static inline void _ARMV7M_MPU_Set_region(
645  volatile ARMV7M_MPU *mpu,
646  uint32_t region,
647  uint32_t rasr,
648  const void *begin,
649  const void *end
650)
651{
652  uintptr_t size;
653  uint32_t rbar;
654
655  RTEMS_OBFUSCATE_VARIABLE(begin);
656  RTEMS_OBFUSCATE_VARIABLE(end);
657  size = (uintptr_t) end - (uintptr_t) begin;
658
659  if ( (uintptr_t) end > (uintptr_t) begin ) {
660    rbar = (uintptr_t) begin | region | ARMV7M_MPU_RBAR_VALID;
661    rasr |= _ARMV7M_MPU_Get_region_size(size);
662  } else {
663    rbar = region;
664    rasr = 0;
665  }
666
667  mpu->rbar = rbar;
668  mpu->rasr = rasr;
669}
670
671static inline void _ARMV7M_MPU_Disable_region(
672  volatile ARMV7M_MPU *mpu,
673  uint32_t region
674)
675{
676  mpu->rbar = ARMV7M_MPU_RBAR_VALID | region;
677  mpu->rasr = 0;
678}
679
680static inline void _ARMV7M_MPU_Setup(
681  const ARMV7M_MPU_Region_config *cfg,
682  size_t cfg_count
683)
684{
685  volatile ARMV7M_MPU *mpu;
686  volatile ARMV7M_SCB *scb;
687  uint32_t region_count;
688  uint32_t region;
689
690  mpu = _ARMV7M_MPU;
691  scb = _ARMV7M_SCB;
692
693  mpu->ctrl = 0;
694
695  _ARM_Data_synchronization_barrier();
696  _ARM_Instruction_synchronization_barrier();
697
698  region_count = ARMV7M_MPU_TYPE_DREGION_GET(mpu->type);
699
700  _Assert(cfg_count <= region_count);
701
702  for (region = 0; region < cfg_count; ++region) {
703    _ARMV7M_MPU_Set_region(
704      mpu,
705      region,
706      cfg[region].rasr,
707      cfg[region].begin,
708      cfg[region].end
709    );
710  }
711
712  for (region = cfg_count; region < region_count; ++region) {
713    _ARMV7M_MPU_Disable_region(mpu, region);
714  }
715
716  mpu->ctrl = ARMV7M_MPU_CTRL_ENABLE | ARMV7M_MPU_CTRL_PRIVDEFENA;
717  scb->shcsr |= ARMV7M_SCB_SHCSR_MEMFAULTENA;
718
719  _ARM_Data_synchronization_barrier();
720  _ARM_Instruction_synchronization_barrier();
721}
722
723#endif /* ASM */
724
725#endif /* ARM_MULTILIB_ARCH_V7M */
726
727#ifdef __cplusplus
728}
729#endif /* __cplusplus */
730
731#endif /* RTEMS_SCORE_ARMV7M_H */
Note: See TracBrowser for help on using the repository browser.