source: rtems/cpukit/score/cpu/arm/include/rtems/score/armv7m.h @ 8476715a

Last change on this file since 8476715a was 8476715a, checked in by Christian Mauderer <christian.mauderer@…>, on 06/01/21 at 09:25:24

cpu/armv7m: Fix initialization of MPU regions

The write to RBAR didn't have the valid flag set. Therefore the write to
RASR had an influence on the previously set region. That means for
example that if Region 0 had been enabled but 1 should be disabled due
to a size of 0, the previous code would have disabled region 0 instead.

This patch fixes that behaviour.

Close #4450

  • Property mode set to 100644
File size: 19.2 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 = ARMV7M_MPU_RBAR_VALID | 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.