1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 34
35
36 package ti.sysbios.family.arm.v8;
37
38 import xdc.rov.ViewInfo;
39
40 /*!
41 * ======== MPU ========
42 * Memory Protection Unit (MPU) Manager.
43 *
44 * This module manages the Memory Protect Unit (MPU) present in ARMv8
45 * Cortex-M devices. It enables the application to partition the memory
46 * into different regions and set protection attributes for each region.
47 *
48 * The number of memory regions supported is device specific and may vary
49 * on different devices.
50 *
51 * Programming a memory region requires specifying the base address and
52 * ending address of the region, and the region's protection attributes.
53 * The protection attributes for each region include attributes such as
54 * memory type (device or normal), shareability, cacheability and
55 * read-write access permission.
56 *
57 * @a(Memory region attributes)
58 * Memory regions can be configured as different memory types by setting
59 * the {@link #RegionAttrs shareable}, {@link #RegionAttrs accessPerm},
60 * {@link #RegionAttrs executable} and {@link #RegionAttrs attrIndx}
61 * fields of the {@link #RegionAttrs} structure which is passed as an
62 * argument to {@link #setRegion MPU_setRegion()} function.
63 *
64 * The two memory types supported by the hardware are "Normal" (cacheable or
65 * non-cacheable) and "Device" memory (gathering, reordering and/or early
66 * acknowledgement). "Device" memory type is recommended for mapping
67 * peripheral address space like memory-mapped registers. This type ensures
68 * that the memory accesses to the peripheral memory are not performed
69 * speculatively, are not repeated, and are always performed in order. The
70 * "Normal" memory type is recommended for mapping memory regions storing
71 * application code and data. The memory type is encoded in a Memory Attribute
72 * Indirection Register (MAIR) and an index to it (see
73 * {@link #RegionAttrs attrIndx}) is passed to
74 * {@link #setRegion MPU_setRegion()} function.
75 *
76 * SYS/BIOS has 8 MAIR config params (MAIR0, MAIR2, ...) that are
77 * initialized to default value. In order to have a custom memory
78 * attribute, a user can either change the MAIRn config param in
79 * the application's cfg script or call the {@link #setMAIR MPU_setMAIR()}
80 * runtime API.
81 *
82 * For more details on MAIR encodings please refer v8M ARM Architecture
83 * Reference Manual.
84 *
85 * @a(Changing shareability attributes of a cacheable memory region)
86 * If changing the shareability attribute of a cacheable memory region,
87 * it is possible for coherency problems to arise. In order to avoid possible
88 * coherency errors, the below sequence should be followed to change the
89 * shareability attributes of the memory region:
90 * - Make the memory region Non-cacheable and outer-shareable
91 * - Clean and invalidate the memory region from the cache
92 * - Change the shareability attribute to the desired value
93 *
94 * @a(Examples)
95 * Example showing how to set attributes for a given memory region using
96 * *.cfg script:
97 *
98 * @p(code)
99 * var MPU = xdc.useModule('ti.sysbios.family.arm.v8.MPU');
100 * MPU.enableMPU = true;
101 *
102 * // Mark memory region as normal outer and inner write-back
103 * // cacheable
104 * var attrs = new MPU.RegionAttrs();
105 * MPU.initRegionAttrsMeta(attrs);
106 * attrs.enable = true;
107 * attrs.shareable = MPU.Shareable_NONE;
108 * attrs.executable = false;
109 * attrs.accessPerm = MPU.AccessPerm_RW_ANY;
110 * attrs.attrIndx = 7; // Use MAIR 7 which has a default of outer and inner
111 * // write-back cacheable
112 *
113 * // Set attributes for memory region of size 32KB starting at
114 * // address 0x20000000 using MPU region Id 0 to store the attributes.
115 * MPU.setRegionMeta(0, 0x20000000, 32768, attrs);
116 * @p
117 *
118 * @p(html)
119 * <h3> Calling Context </h3>
120 * <table border="1" cellpadding="3">
121 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
122 * </colgroup>
123 *
124 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
125 * <th> Task </th><th> Main </th><th> Startup </th></tr>
126 * <!-- -->
127 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td>
128 * <td> Y </td><td> Y </td><td> Y </td></tr>
129 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td>
130 * <td> Y </td><td> Y </td><td> Y </td></tr>
131 * <tr><td> {@link #initRegionAttrs} </td><td> Y </td><td> Y </td>
132 * <td> Y </td><td> Y </td><td> Y </td></tr>
133 * <tr><td> {@link #isEnabled} </td><td> Y </td><td> Y </td>
134 * <td> Y </td><td> Y </td><td> Y </td></tr>
135 * <tr><td> {@link #setMAIR} </td><td> Y </td><td> Y </td>
136 * <td> Y </td><td> Y </td><td> Y </td></tr>
137 * <tr><td> {@link #setRegion} </td><td> Y </td><td> Y </td>
138 * <td> Y </td><td> Y </td><td> Y </td></tr>
139 * <tr><td colspan="6"> Definitions: <br />
140 * <ul>
141 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
142 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
143 * <li> <b>Task</b>: API is callable from a Task thread. </li>
144 * <li> <b>Main</b>: API is callable during any of these phases: </li>
145 * <ul>
146 * <li> In your module startup. </li>
147 * <li> During xdc.runtime.Startup.lastFxns. </li>
148 * <li> During main().</li>
149 * <li> During BIOS.startupFxns.</li>
150 * </ul>
151 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
152 * <ul>
153 * <li> During xdc.runtime.Startup.firstFxns.</li>
154 * <li> In your module startup.</li>
155 * </ul>
156 * </ul>
157 * </td></tr>
158 *
159 * </table>
160 * @p
161 */
162
163 @DirectCall
164 module MPU
165 {
166
167
168 /*! @_nodoc */
169 metaonly struct RegionAttrsView {
170 UInt8 RegionId;
171 Bool Enabled;
172 String BaseAddress;
173 String EndAddress;
174 String Shareable;
175 Bool Executable;
176 String AccessPerm;
177 };
178
179 @Facet
180 metaonly config ViewInfo.Instance rovViewInfo =
181 ViewInfo.create({
182 viewMap: [
183 ['MpuRegionAttrsView', {
184 type: ViewInfo.MODULE_DATA,
185 viewInitFxn: 'viewMpuRegionAttrs',
186 structName: 'RegionAttrsView'
187 }],
188 ]
189 });
190
191 /*!
192 * Memory Protection Unit (MPU) registers. Symbol "MPU_deviceRegs" is
193 * a physical device
194 */
195 struct DeviceRegs {
196 UInt32 TYPE; /*! 0xD90 Type Register */
197 UInt32 CTRL; /*! 0xD94 Control Register */
198 UInt32 RNR; /*! 0xD98 Region Register */
199 UInt32 RBAR; /*! 0xD9C Region Base Address Register */
200 UInt32 RLAR; /*! 0xDA0 Region Base Limit Register */
201 UInt32 RBAR_A1; /*! 0xDA4 MPU RBAR Alias 1 */
202 UInt32 RLAR_A1; /*! 0xDA8 MPU RLAR Alias 1 */
203 UInt32 RBAR_A2; /*! 0xDAC MPU RBAR Alias 2 */
204 UInt32 RLAR_A2; /*! 0xDB0 MPU RLAR Alias 2 */
205 UInt32 RBAR_A3; /*! 0xDB4 MPU RBAR Alias 3 */
206 UInt32 RLAR_A3; /*! 0xDB8 MPU RLAR Alias 3 */
207 UInt32 res0; /*! 0xDBC Reserved */
208 UInt32 MAIR0; /*! 0xDC0 MAIR0 */
209 UInt32 MAIR1; /*! 0xDC4 MAIR1 */
210 };
211
212 extern volatile DeviceRegs deviceRegs;
213
214 /*!
215 * ======== AccessPerm ========
216 * Access Permissions
217 */
218 enum AccessPerm {
219 AccessPerm_RW_PRIV = 0x0, /*! Read/write by privileged code only */
220 AccessPerm_RW_ANY = 0x1, /*! Read/write by any privilege level */
221 AccessPerm_RO_PRIV = 0x2, /*! Read only by privileged code only */
222 AccessPerm_RO_ANY = 0x3 /*! Read only by any privilege level */
223 };
224
225 /*!
226 * ======== Shareable ========
227 * Shareability attribute
228 */
229 enum Shareable {
230 Shareable_NONE = 0x0,
231 Shareable_OUTER = 0x2,
232 Shareable_INNER = 0x3
233 };
234
235 /*!
236 * ======== RegionAttrs ========
237 * Structure for setting protection attributes of a MPU region
238 */
239 struct RegionAttrs {
240 Bool enable; /*! Is MPU region enabled */
241 Shareable shareable; /*! Memory region shareability */
242 Bool executable; /*! Is memory region executable */
243 AccessPerm accessPerm; /*! Access permission */
244 UInt8 attrIndx; /*! Memory attributes index field 0-7 */
245 };
246
247 /*!
248 * ======== defaultAttrs ========
249 * Default region attributes structure
250 *
251 * The default attributes structure marks the memory region as outer and
252 * inner non-cacheable and non-shareable, with read-write access from
253 * privileged code only.
254 */
255 config RegionAttrs defaultAttrs = {
256 enable: true,
257 shareable: Shareable_NONE,
258 executable: true,
259 accessPerm: AccessPerm_RW_PRIV, 260
261 attrIndx: 0 262 263
264 };
265
266 /*!
267 * ======== A_nullPointer ========
268 * Assert raised when a pointer is null
269 */
270 config xdc.runtime.Assert.Id A_nullPointer = {
271 msg: "A_nullPointer: Pointer is null"
272 };
273
274 /*!
275 * ======== A_invalidRegionId ========
276 * Assert raised when an invalid region number is passed to MPU_setRegion()
277 */
278 config xdc.runtime.Assert.Id A_invalidRegionId = {
279 msg: "A_invalidRegionId: MPU Region number passed is invalid."
280 };
281
282 /*!
283 * ======== A_unalignedBaseAddr ========
284 * Assert raised when region's base address is not aligned.
285 */
286 config xdc.runtime.Assert.Id A_unalignedBaseAddr = {
287 msg: "A_unalignedBaseAddr: MPU region base address not aligned."
288 };
289
290 /*!
291 * ======== A_unalignedEndAddr ========
292 * Assert raised when region's end address is not aligned.
293 */
294 config xdc.runtime.Assert.Id A_unalignedEndAddr = {
295 msg: "A_unalignedEndAddr: MPU region end address not aligned."
296 };
297
298 /*!
299 * ======== enableMPU ========
300 * Configuration parameter to enable MPU. Disabled by default.
301 */
302 config Bool enableMPU = false;
303
304 /*!
305 * ======== enableBackgroundRegion ========
306 * Configuration parameter to enable background region.
307 *
308 * If the MPU is enabled and background region is also enabled, any
309 * privileged access that does not map to any MPU memory region is
310 * handled using the default memory map.
311 *
312 * @p(blist)
313 * -See the "Protected Memory System Architecture (PMSA)" chapter
314 * in the ARM v8M Architecture Reference Manual for more info on
315 * the default memory map.
316 * @p
317 */
318 config Bool enableBackgroundRegion = true;
319
320 /*!
321 * ======== MAIR0 ========
322 * Memory attribute 0.
323 *
324 * Default is memory with non-gathering, non-reordering and no early write
325 * acknowledegement property.
326 */
327 config UInt8 MAIR0 = 0x00;
328
329 /*!
330 * ======== MAIR1 ========
331 * Memory attribute 1
332 *
333 * Default is memory with non-gathering, non-reordering and early write
334 * acknowledegement property.
335 */
336 config UInt8 MAIR1 = 0x04;
337
338 /*!
339 * ======== MAIR2 ========
340 * Memory attribute 2
341 *
342 * Default is memory with non-gathering, reordering and early write
343 * acknowledegement property.
344 */
345 config UInt8 MAIR2 = 0x08;
346
347 /*!
348 * ======== MAIR3 ========
349 * Memory attribute 3
350 *
351 * Default is memory with gathering, reordering and early write
352 * acknowledegement property.
353 */
354 config UInt8 MAIR3 = 0x0C;
355
356 /*!
357 * ======== MAIR4 ========
358 * Memory attribute 4
359 *
360 * Default is normal outer & inner non-cacheable memory.
361 */
362 config UInt8 MAIR4 = 0x44;
363
364 /*!
365 * ======== MAIR5 ========
366 * Memory attribute 5
367 *
368 * Default is normal outer non-cacheable, inner write-back cacheable
369 * non-transient memory.
370 */
371 config UInt8 MAIR5 = 0x4F;
372
373 /*!
374 * ======== MAIR6 ========
375 * Memory attribute 6
376 *
377 * Default is normal outer & inner write-through cacheable non-transient
378 * memory.
379 */
380 config UInt8 MAIR6 = 0xBB;
381
382 /*!
383 * ======== MAIR7 ========
384 * Memory attribute 7
385 *
386 * Default is normal outer and inner write-back cacheable non-transient
387 * memory.
388 */
389 config UInt8 MAIR7 = 0xFF;
390
391 /*!
392 * @_nodoc
393 * ======== numRegions ========
394 * Number of MPU regions. Default is determined based on device type.
395 */
396 config UInt8 numRegions;
397
398 /*!
399 * ======== initRegionAttrsMeta ========
400 * Initializes the region attribute structure
401 *
402 * @param(attrs) Pointer to region attribute struct
403 */
404 metaonly Void initRegionAttrsMeta(RegionAttrs *regionAttrs);
405
406 /*!
407 * ======== setRegionMeta ========
408 * Statically sets the MPU region attributes
409 *
410 * @see ti.sysbios.family.arm.r5.MPU
411 *
412 * @param(regionId) MPU region number
413 * @param(regionBaseAddr) MPU region base address
414 * @param(regionEndAddr) MPU region end address
415 * @param(attrs) Protection attributes
416 */
417 metaonly Void setRegionMeta(UInt8 regionId, Ptr regionBaseAddr,
418 Ptr regionEndAddr, RegionAttrs attrs);
419
420 /*!
421 * ======== disable ========
422 * Disables the MPU.
423 *
424 * If the MPU is already disabled, then simply return.
425 */
426 Void disable();
427
428 /*!
429 * ======== enable ========
430 * Enables the MPU.
431 *
432 * If the MPU is already enabled, then simply return.
433 */
434 Void enable();
435
436 /*!
437 * ======== initRegionAttrs() ========
438 * Initializes the region attribute structure
439 *
440 * @param(attrs) Pointer to region attribute struct
441 */
442 Void initRegionAttrs(RegionAttrs *regionAttrs);
443
444 /*!
445 * ======== isEnabled ========
446 * Determines if the MPU is enabled
447 */
448 Bool isEnabled();
449
450 /*!
451 * ======== setMAIR ========
452 * Sets the memory attribute encoding in the MAIRn register.
453 *
454 * MAIR provides the memory attribute encodings to the possible
455 * {@link #RegionAttrs attrIndx} values in a MPU region entry.
456 *
457 * {@link #RegionAttrs attrIndx}[2:0] selects the ATTRn bit-field in
458 * the MAIR register.
459 *
460 * Memory Attribute Indirection Register (MAIR) bit assignments:
461 * @p(code)
462 * |31 | 24|23 | 16|15 | 8|7 | 0|
463 * --------------------------------------------------------------
464 * MAIR0 | ATTR3 | ATTR2 | ATTR1 | ATTR0 |
465 * --------------------------------------------------------------
466 * MAIR1 | ATTR7 | ATTR6 | ATTR5 | ATTR4 |
467 * --------------------------------------------------------------
468 * @p
469 *
470 * SYS/BIOS has 8 MAIR config params (MAIR0, MAIR2, ...) that are
471 * initialized to default value. In order to have a custom memory
472 * attribute, a user can either change the MAIRn config param in
473 * the application's cfg script or call this runtime API.
474 *
475 * For more details on MAIR encodings please refer v8M ARM Architecture
476 * Reference Manual.
477 *
478 * @param(attrIndx) Memory attribute index
479 * @param(attr) Memory attribute encoding
480 */
481 Void setMAIR(UInt8 attrIndx, UInt8 attr);
482
483 /*!
484 * ======== setRegion ========
485 * Sets the MPU region attributes
486 *
487 * @see ti.sysbios.family.arm.v8.MPU
488 *
489 * @param(regionId) MPU region number
490 * @param(regionBaseAddr) MPU region base address
491 * @param(regionEndAddr) MPU region end address
492 * @param(attrs) Protection attributes
493 */
494 Void setRegion(UInt8 regionId, Ptr regionBaseAddr,
495 Ptr regionEndAddr, RegionAttrs *attrs);
496
497 internal:
498
499 500 501
502 struct RegionEntry {
503 UInt32 rbar;
504 UInt32 rlar;
505 };
506
507 508 509 510
511 config RegionEntry regionEntry[];
512
513 514 515 516
517 Void startup();
518
519 /*! Module state */
520 struct Module_State {
521 RegionEntry regionEntry[];
522
523 }
524 }