source: rtems/cpukit/score/cpu/arm/include/rtems/score/aarch32-pmsa.h @ 98cef40

Last change on this file since 98cef40 was 854ea2b, checked in by Sebastian Huber <sebastian.huber@…>, on 12/15/20 at 09:59:21

arm: Add support for Arm PMSAv8-32

Update #4202.

  • Property mode set to 100644
File size: 10.5 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup RTEMSScoreCPUARMPMSAv8
7 *
8 * @brief This header file provides the API to manage an Arm PMSAv8-32 based
9 *   Memory Protection Unit (MPU).
10 */
11
12/*
13 * Copyright (C) 2020 embedded brains GmbH (http://www.embedded-brains.de)
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions
17 * are met:
18 * 1. Redistributions of source code must retain the above copyright
19 *    notice, this list of conditions and the following disclaimer.
20 * 2. Redistributions in binary form must reproduce the above copyright
21 *    notice, this list of conditions and the following disclaimer in the
22 *    documentation and/or other materials provided with the distribution.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 * POSSIBILITY OF SUCH DAMAGE.
35 */
36
37#ifndef _RTEMS_SCORE_AARCH32_PMSA_H
38#define _RTEMS_SCORE_AARCH32_PMSA_H
39
40#include <stddef.h>
41#include <stdint.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47/**
48 * @defgroup RTEMSScoreCPUARMPMSAv8 PMSAv8-32 Support
49 *
50 * @ingroup RTEMSScoreCPUARM
51 *
52 * @brief This group provides support functions to manage an Arm PMSAv8-32
53 *   (Protected Memory System Architecture) based Memory Protection Unit (MPU).
54 *
55 * @{
56 */
57
58#define AARCH32_PMSA_MIN_REGION_ALIGN 64
59
60#define AARCH32_PMSA_ATTR_EN 0x1U
61
62#define AARCH32_PMSA_ATTR_IDX_SHIFT 1
63#define AARCH32_PMSA_ATTR_IDX_MASK 0xeU
64#define AARCH32_PMSA_ATTR_IDX( _idx ) \
65  ( ( _idx ) << AARCH32_PMSA_ATTR_IDX_SHIFT )
66
67#define AARCH32_PMSA_ATTR_XN 0x6U
68
69#define AARCH32_PMSA_ATTR_AP_SHIFT 7
70#define AARCH32_PMSA_ATTR_AP_MASK 0x18U
71#define AARCH32_PMSA_ATTR_AP( _ap ) \
72  ( ( _ap ) << AARCH32_PMSA_ATTR_AP_SHIFT )
73#define AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO 0x0U
74#define AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_RW 0x1U
75#define AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO 0x2U
76#define AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_RO 0x3U
77
78#define AARCH32_PMSA_ATTR_SH_SHIFT 9
79#define AARCH32_PMSA_ATTR_SH_MASK 0x600U
80#define AARCH32_PMSA_ATTR_SH( _sh ) \
81  ( ( _sh ) << AARCH32_PMSA_ATTR_SH_SHIFT )
82#define AARCH32_PMSA_ATTR_SH_NO 0x0U
83#define AARCH32_PMSA_ATTR_SH_RES 0x1U
84#define AARCH32_PMSA_ATTR_SH_OUTER 0x2U
85#define AARCH32_PMSA_ATTR_SH_INNER 0x3U
86
87#define AARCH32_PMSA_MEM_DEVICE_NG_NR_NE 0x00U
88#define AARCH32_PMSA_MEM_DEVICE_NG_NR_E  0x04U
89#define AARCH32_PMSA_MEM_DEVICE_NG_R_E   0x08U
90#define AARCH32_PMSA_MEM_DEVICE_G_R_E    0x0cU
91
92#define AARCH32_PMSA_MEM_OUTER_WTT  0x00U
93#define AARCH32_PMSA_MEM_OUTER_NC   0x40U
94#define AARCH32_PMSA_MEM_OUTER_WBT  0x40U
95#define AARCH32_PMSA_MEM_OUTER_WTNT 0x80U
96#define AARCH32_PMSA_MEM_OUTER_WBNT 0xc0U
97
98#define AARCH32_PMSA_MEM_OUTER_RA 0x20U
99#define AARCH32_PMSA_MEM_OUTER_WA 0x10U
100
101#define AARCH32_PMSA_MEM_INNER_WTT  0x00U
102#define AARCH32_PMSA_MEM_INNER_NC   0x40U
103#define AARCH32_PMSA_MEM_INNER_WBT  0x40U
104#define AARCH32_PMSA_MEM_INNER_WTNT 0x80U
105#define AARCH32_PMSA_MEM_INNER_WBNT 0xc0U
106
107#define AARCH32_PMSA_MEM_INNER_RA 0x02U
108#define AARCH32_PMSA_MEM_INNER_WA 0x01U
109
110#define AARCH32_PMSA_MEM_ATTR( _ma0, _ma1, _ma2, _ma3 ) \
111  ( ( _ma0 ) | ( ( _ma1 ) << 8 ) | ( ( _ma1 ) << 16 ) | ( ( _ma1 ) << 24 ) )
112
113#define AARCH32_PMSA_MEM_ATTR_DEFAULT_CACHED \
114  ( AARCH32_PMSA_MEM_OUTER_WBNT | \
115    AARCH32_PMSA_MEM_OUTER_RA | \
116    AARCH32_PMSA_MEM_OUTER_WA | \
117    AARCH32_PMSA_MEM_INNER_WBNT | \
118    AARCH32_PMSA_MEM_INNER_RA | \
119    AARCH32_PMSA_MEM_INNER_WA )
120
121#define AARCH32_PMSA_MEM_ATTR_DEFAULT_UNCACHED \
122  ( AARCH32_PMSA_MEM_OUTER_NC | \
123    AARCH32_PMSA_MEM_INNER_NC )
124
125#define AARCH32_PMSA_MEM_ATTR_DEFAULT_DEVICE \
126  AARCH32_PMSA_MEM_DEVICE_NG_NR_NE
127
128#define AARCH32_PMSA_CODE_CACHED \
129  ( AARCH32_PMSA_ATTR_EN | \
130    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
131    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
132    AARCH32_PMSA_ATTR_IDX( 0U ) )
133
134#define AARCH32_PMSA_CODE_UNCACHED \
135  ( AARCH32_PMSA_ATTR_EN | \
136    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
137    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
138    AARCH32_PMSA_ATTR_IDX( 1U ) )
139
140#define AARCH32_PMSA_DATA_READ_ONLY_CACHED \
141  ( AARCH32_PMSA_ATTR_EN | \
142    AARCH32_PMSA_ATTR_XN | \
143    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) |  \
144    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_OUTER ) | \
145    AARCH32_PMSA_ATTR_IDX( 0U ) )
146
147#define AARCH32_PMSA_DATA_READ_ONLY_UNCACHED \
148  ( AARCH32_PMSA_ATTR_EN | \
149    AARCH32_PMSA_ATTR_XN | \
150    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RO_EL0_NO ) | \
151    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
152    AARCH32_PMSA_ATTR_IDX( 1U ) )
153
154#define AARCH32_PMSA_DATA_READ_WRITE_CACHED \
155  ( AARCH32_PMSA_ATTR_EN | \
156    AARCH32_PMSA_ATTR_XN | \
157    AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO | \
158    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_OUTER ) | \
159    AARCH32_PMSA_ATTR_IDX( 0U ) )
160
161#define AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
162  ( AARCH32_PMSA_ATTR_EN | \
163    AARCH32_PMSA_ATTR_XN | \
164    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO ) | \
165    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
166    AARCH32_PMSA_ATTR_IDX( 1U ) )
167
168#define AARCH32_PMSA_DEVICE \
169  ( AARCH32_PMSA_ATTR_EN | \
170    AARCH32_PMSA_ATTR_XN | \
171    AARCH32_PMSA_ATTR_AP( AARCH32_PMSA_ATTR_AP_EL1_RW_EL0_NO ) | \
172    AARCH32_PMSA_ATTR_SH( AARCH32_PMSA_ATTR_SH_NO ) | \
173    AARCH32_PMSA_ATTR_IDX( 2U ) )
174
175/**
176 * @brief The default section definitions shall be used by the BSP to define
177 *   ::_AArch32_PMSA_Sections.
178 *
179 * In addition to the default section definitions, the BSP should provide
180 * section definitions for the memory-mapped devices and other memory areas.
181 */
182#define AARCH32_PMSA_DEFAULT_SECTIONS \
183  { \
184    .begin = (uint32_t) bsp_section_fast_text_begin, \
185    .end = (uint32_t) bsp_section_fast_text_end, \
186    .attributes = AARCH32_PMSA_CODE_CACHED \
187  }, { \
188    .begin = (uint32_t) bsp_section_fast_data_begin, \
189    .end = (uint32_t) bsp_section_fast_data_end, \
190    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
191  }, { \
192    .begin = (uint32_t) bsp_section_start_begin, \
193    .end = (uint32_t) bsp_section_start_end, \
194    .attributes = AARCH32_PMSA_CODE_CACHED \
195  }, { \
196    .begin = (uint32_t) bsp_section_vector_begin, \
197    .end = (uint32_t) bsp_section_vector_end, \
198    .attributes = AARCH32_PMSA_CODE_CACHED \
199  }, { \
200    .begin = (uint32_t) bsp_section_text_begin, \
201    .end = (uint32_t) bsp_section_text_end, \
202    .attributes = AARCH32_PMSA_CODE_CACHED \
203  }, { \
204    .begin = (uint32_t) bsp_section_rodata_begin, \
205    .end = (uint32_t) bsp_section_rodata_end, \
206    .attributes = AARCH32_PMSA_DATA_READ_ONLY_CACHED \
207  }, { \
208    .begin = (uint32_t) bsp_section_data_begin, \
209    .end = (uint32_t) bsp_section_data_end, \
210    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
211  }, { \
212    .begin = (uint32_t) bsp_section_bss_begin, \
213    .end = (uint32_t) bsp_section_bss_end, \
214    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
215  }, { \
216    .begin = (uint32_t) bsp_section_rtemsstack_begin, \
217    .end = (uint32_t) bsp_section_rtemsstack_end, \
218    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
219  }, { \
220    .begin = (uint32_t) bsp_section_work_begin, \
221    .end = (uint32_t) bsp_section_work_end, \
222    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
223  }, { \
224    .begin = (uint32_t) bsp_section_stack_begin, \
225    .end = (uint32_t) bsp_section_stack_end, \
226    .attributes = AARCH32_PMSA_DATA_READ_WRITE_CACHED \
227  }, { \
228    .begin = (uint32_t) bsp_section_nocache_begin, \
229    .end = (uint32_t) bsp_section_nocache_end, \
230    .attributes = AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
231  }, { \
232    .begin = (uint32_t) bsp_section_nocachenoload_begin, \
233    .end = (uint32_t) bsp_section_nocachenoload_end, \
234    .attributes = AARCH32_PMSA_DATA_READ_WRITE_UNCACHED \
235  }
236
237/**
238 * @brief The section definition is used to initialize the Memory Protection
239 *   Unit (MPU).
240 *
241 * A section is empty if the begin address is equal to the end address.
242 */
243typedef struct {
244  /**
245   * @brief This member defines the begin address of the section.
246   */
247  uint32_t begin;
248
249  /**
250   * @brief This member defines the end address of the section.
251   */
252  uint32_t end;
253
254  /**
255   * @brief This member defines the attributes of the section.
256   */
257  uint32_t attributes;
258} AArch32_PMSA_Section;
259
260/**
261 * @brief Initializes the Memory Protection Unit (MPU).
262 *
263 * The section definitions are used to define the regions of the MPU.  Sections
264 * are merged if possible to reduce the count of used regions.  If too many
265 * regions are used, then the MPU is not enabled.  Overlapping section
266 * definitions result in undefined system behaviour.
267 *
268 * @param memory_attributes_0 are the memory attributes for MAIR0.
269 *
270 * @param memory_attributes_1 are the memory attributes for MAIR1.
271 *
272 * @param sections is the array with section definitions.
273 *
274 * @param section_count is the count of section definitions.
275 */
276void _AArch32_PMSA_Initialize(
277  uint32_t                    memory_attributes_0,
278  uint32_t                    memory_attributes_1,
279  const AArch32_PMSA_Section *sections,
280  size_t                      section_count
281);
282
283/**
284 * @brief This array provides section definitions to initialize the memory
285 *   protection unit (MPU).
286 *
287 * The BSP shall provide the section definitions with the help of
288 * ::AARCH32_PMSA_DEFAULT_SECTIONS.  The section count is provided by
289 * ::_AArch32_PMSA_Section_count.
290 */
291extern const AArch32_PMSA_Section _AArch32_PMSA_Sections[];
292
293/**
294 * @brief This constant provides the count of elements in
295 * ::_AArch32_PMSA_Sections.
296 */
297extern const size_t _AArch32_PMSA_Section_count;
298
299/**
300 * @brief Initializes the Memory Protection Unit (MPU) using the section
301 *   definitions with default memory attributes.
302 *
303 * Calls _AArch32_PMSA_Initialize() using ::_AArch32_PMSA_Sections and
304 * ::_AArch32_PMSA_Section_count and the default memory attributes.
305 */
306void _AArch32_PMSA_Initialize_default( void );
307
308/** @} */
309
310#ifdef __cplusplus
311}
312#endif
313
314#endif /* _RTEMS_SCORE_AARCH32_PMSA_H */
Note: See TracBrowser for help on using the repository browser.