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;
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 many ARM
45 * Cortex-R and Cortex-M devices. It enables the application to partition
46 * the memory into different regions and set protection attributes for
47 * each region.
48 *
49 * The number of memory regions supported is device specific and may vary
50 * on different devices. The Cortex-R4F based RM48L5XX devices for instance
51 * support 16 memory regions.
52 *
53 * Programming a memory region requires specifying the base address and
54 * size of the region, and the region's protection attributes. It is also
55 * possible to overlap different memory regions with higher region numbers
56 * enjoying higher priority than lower region numbers i.e. region 15 has
57 * a higher priority than region 14, and if both were overlapping, the
58 * overlapped memory region's attributes would be defined by region 15's
59 * entry.
60 *
61 * The protection attributes for each region include attributes such as
62 * memory type (strongly-ordered, device or normal), shareability,
63 * cacheability and read-write access permission.
64 *
65 * @a(Memory region attributes)
66 * Memory regions can be configured as different memory types by setting
67 * the {@link #RegionAttrs bufferable}, {@link #RegionAttrs cacheable} and
68 * {@link #RegionAttrs tex} (type extension) fields of the {@link #RegionAttrs}
69 * structure which is passed as an argument to
70 * {@link #setRegion MPU_setRegion()} function. The three memory types
71 * supported by the hardware are "Normal" (cacheable), "Device" and
72 * "Strongly-ordered" memory. "Device" and "Strongly-ordered" memory types
73 * are recommended for mapping peripheral address space like memory-mapped
74 * registers. These two types ensure that the memory accesses to the
75 * peripheral memory are not performed speculatively, are not repeated and
76 * are performed in order. The "Normal" memory type is recommended for mapping
77 * memory regions storing application code and data.
78 *
79 * Here are some common settings for the {@link #RegionAttrs bufferable},
80 * {@link #RegionAttrs cacheable} and {@link #RegionAttrs tex} fields to
81 * define different memory region types:
82 *
83 * @p(code)
84 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
85 * + Memory Type | bufferable | cacheable | tex +
86 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
87 * + Shareable Strongly-ordered memory | false | false | 0 +
88 * +-----------------------------------------+------------+-----------+-----+
89 * + Shareable Device memory | true | false | 0 +
90 * +-----------------------------------------+------------+-----------+-----+
91 * + Outer & Inner Non-cacheable | false | false | 1 +
92 * +-----------------------------------------+------------+-----------+-----+
93 * + Outer & Inner Write-back Write-allocate | true | true | 1 +
94 * + cacheable | | | +
95 * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
96 * @p
97 *
98 * For an exhaustive list of all different memory type settings and a
99 * detailed explanation of the memory region attributes, please read the
100 * 'Protected Memory System Architecture (PMSA)' chapter of the
101 * {@link http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html ARM v7AR Architecture Reference Manual}.
102 *
103 * @a(Changing shareability attributes of a cacheable memory region)
104 * If changing the shareability attribute of a cacheable memory region,
105 * it is possible for coherency problems to arise. In order to avoid possible
106 * coherency errors, the below sequence should be followed to change the
107 * shareability attributes of the memory region:
108 * - Make the memory region Non-cacheable and outer-shareable
109 * - Clean and invalidate the memory region from the cache
110 * - Change the shareability attribute to the desired value
111 *
112 * @a(Examples)
113 * Example showing how to set attributes for a given memory region using
114 * *.cfg script:
115 *
116 * @p(code)
117 * var MPU = xdc.useModule('ti.sysbios.family.arm.MPU');
118 *
119 * // Mark memory region as normal outer and inner write-back
120 * // and write-through cacheable
121 * var attrs = new MPU.RegionAttrs();
122 * MPU.initRegionAttrsMeta(attrs);
123 * attrs.enable = true;
124 * attrs.bufferable = true;
125 * attrs.cacheable = true;
126 * attrs.shareable = false;
127 * attrs.noExecute = false;
128 * attrs.accPerm = 6; // Read-only at PL1 and PL0
129 * attrs.tex = 1;
130 *
131 * // Set attributes for memory region of size 4MB starting at address 0x0
132 * // using MPU region Id 0 to store the attributes.
133 * MPU.setRegionMeta(0, 0x00000000, MPU.RegionSize_4M, attrs);
134 * @p
135 *
136 * @p(html)
137 * <h3> Calling Context </h3>
138 * <table border="1" cellpadding="3">
139 * <colgroup span="1"></colgroup> <colgroup span="5" align="center">
140 * </colgroup>
141 *
142 * <tr><th> Function </th><th> Hwi </th><th> Swi </th>
143 * <th> Task </th><th> Main </th><th> Startup </th></tr>
144 * <!-- -->
145 * <tr><td> {@link #disable} </td><td> Y </td><td> Y </td>
146 * <td> Y </td><td> Y </td><td> Y </td></tr>
147 * <tr><td> {@link #enable} </td><td> Y </td><td> Y </td>
148 * <td> Y </td><td> Y </td><td> Y </td></tr>
149 * <tr><td> {@link #initRegionAttrs} </td><td> Y </td><td> Y </td>
150 * <td> Y </td><td> Y </td><td> Y </td></tr>
151 * <tr><td> {@link #isEnabled} </td><td> Y </td><td> Y </td>
152 * <td> Y </td><td> Y </td><td> Y </td></tr>
153 * <tr><td> {@link #setRegion} </td><td> Y </td><td> Y </td>
154 * <td> Y </td><td> Y </td><td> Y </td></tr>
155 * <tr><td colspan="6"> Definitions: <br />
156 * <ul>
157 * <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
158 * <li> <b>Swi</b>: API is callable from a Swi thread. </li>
159 * <li> <b>Task</b>: API is callable from a Task thread. </li>
160 * <li> <b>Main</b>: API is callable during any of these phases: </li>
161 * <ul>
162 * <li> In your module startup. </li>
163 * <li> During xdc.runtime.Startup.lastFxns. </li>
164 * <li> During main().</li>
165 * <li> During BIOS.startupFxns.</li>
166 * </ul>
167 * <li> <b>Startup</b>: API is callable during any of these phases:</li>
168 * <ul>
169 * <li> During xdc.runtime.Startup.firstFxns.</li>
170 * <li> In your module startup.</li>
171 * </ul>
172 * </ul>
173 * </td></tr>
174 *
175 * </table>
176 * @p
177 */
178
179 @DirectCall
180 module MPU
181 {
182
183
184 /*! @_nodoc */
185 metaonly struct RegionAttrsView {
186 UInt8 RegionIdx;
187 Bool Enabled;
188 String BaseAddress;
189 String Size;
190 Bool Bufferable;
191 Bool Cacheable;
192 Bool Shareable;
193 Bool Noexecute;
194 String AccessPerm;
195 String Tex;
196 String SubregionDisableMask;
197 };
198
199 @Facet
200 metaonly config ViewInfo.Instance rovViewInfo =
201 ViewInfo.create({
202 viewMap: [
203 ['MpuRegionAttrsView', {
204 type: ViewInfo.MODULE_DATA,
205 viewInitFxn: 'viewMpuRegionAttrs',
206 structName: 'RegionAttrsView'
207 }],
208 ]
209 });
210
211 /*!
212 * Memory Protection Unit (MPU) registers. Symbol "MPU_deviceRegs" is
213 * a physical device
214 */
215 struct DeviceRegs {
216 UInt32 TYPE; /*! 0xD90 Type Register */
217 UInt32 CTRL; /*! 0xD94 Control Register */
218 UInt32 RNR; /*! 0xD98 Region Register */
219 UInt32 RBAR; /*! 0xD9C Region Base Address Register */
220 UInt32 RASR; /*! 0xDA0 Region Attribute and Size Register */
221 UInt32 RBAR_A1; /*! 0xDA4 MPU Alias 1 */
222 UInt32 RASR_A1; /*! 0xDA8 MPU Alias 1 */
223 UInt32 RBAR_A2; /*! 0xDAC MPU Alias 2 */
224 UInt32 RASR_A2; /*! 0xDB0 MPU Alias 2 */
225 UInt32 RBAR_A3; /*! 0xDB4 MPU Alias 3 */
226 UInt32 RASR_A3; /*! 0xDB8 MPU Alias 3 */
227 };
228
229 extern volatile DeviceRegs deviceRegs;
230
231 /*!
232 * ======== RegionSize ========
233 */
234 enum RegionSize {
235 RegionSize_32 = 0x8,
236 RegionSize_64 = 0xA,
237 RegionSize_128 = 0xC,
238 RegionSize_256 = 0xE,
239 RegionSize_512 = 0x10,
240 RegionSize_1K = 0x12,
241 RegionSize_2K = 0x14,
242 RegionSize_4K = 0x16,
243 RegionSize_8K = 0x18,
244 RegionSize_16K = 0x1A,
245 RegionSize_32K = 0x1C,
246 RegionSize_64K = 0x1E,
247 RegionSize_128K = 0x20,
248 RegionSize_256K = 0x22,
249 RegionSize_512K = 0x24,
250 RegionSize_1M = 0x26,
251 RegionSize_2M = 0x28,
252 RegionSize_4M = 0x2A,
253 RegionSize_8M = 0x2C,
254 RegionSize_16M = 0x2E,
255 RegionSize_32M = 0x30,
256 RegionSize_64M = 0x32,
257 RegionSize_128M = 0x34,
258 RegionSize_256M = 0x36,
259 RegionSize_512M = 0x38,
260 RegionSize_1G = 0x3A,
261 RegionSize_2G = 0x3C,
262 RegionSize_4G = 0x3E
263 };
264
265
266 /*!
267 * ======== RegionAttrs ========
268 * Structure for setting the region attributes
269 *
270 * The B (Bufferable), C (Cacheable), TEX (Type extension), S (Shareable),
271 * XN (No execute or Execute never) and AP (Access permission) bits in the
272 * memory region entry define the memory region attributes.
273 *
274 * See the 'Memory region attributes' section in the 'Protected Memory
275 * System Architecture (PMSA)' of the ARM v7-AR Architecture Reference
276 * Manual for more details.
277 */
278 struct RegionAttrs {
279 Bool enable; /*! is MPU region enabled */
280 Bool bufferable; /*! is memory region bufferable (B) */
281 Bool cacheable; /*! is memory region cacheable (C) */
282 Bool shareable; /*! is memory region shareable (S) */
283 Bool noExecute; /*! is memory region not executable (XN) */
284 UInt8 accPerm; /*! access permission bits value 0-7
285 (AP[2:0]) */
286 UInt8 tex; /*! memory region attr type extension
287 field (TEX[2:0]) */
288 UInt8 subregionDisableMask; /*! disable mask for all 8 subregions */
289 };
290
291 /*!
292 * ======== defaultAttrs ========
293 * Default region attributes structure
294 *
295 * The default attributes structure marks the memory region as outer and
296 * inner non-cacheable and non-shareable, with read-write access in
297 * privileged mode (PL1) only.
298 */
299 config RegionAttrs defaultAttrs = {
300 enable: true,
301 bufferable: false,
302 cacheable: false,
303 shareable: false,
304 noExecute: false,
305 accPerm: 1,
306 tex: 1,
307 subregionDisableMask: 0
308 };
309
310 /*!
311 * ======== A_nullPointer ========
312 * Assert raised when a pointer is null
313 */
314 config xdc.runtime.Assert.Id A_nullPointer = {
315 msg: "A_nullPointer: Pointer is null"
316 };
317
318 /*!
319 * ======== A_invalidRegionId ========
320 * Assert raised when an invalid region number is passed to MPU_setRegion()
321 */
322 config xdc.runtime.Assert.Id A_invalidRegionId = {
323 msg: "A_invalidRegionId: MPU Region number passed is invalid."
324 };
325
326 /*!
327 * ======== A_unalignedBaseAddr ========
328 * Assert raised when region's base address is not aligned to the region's
329 * size
330 */
331 config xdc.runtime.Assert.Id A_unalignedBaseAddr = {
332 msg: "A_unalignedBaseAddr: MPU region base address not aligned to size."
333 };
334
335 /*!
336 * ======== A_reservedAttrs ========
337 * Assert raised when region's attributes set to a reserved set
338 */
339 config xdc.runtime.Assert.Id A_reservedAttrs = {
340 msg: "A_reservedAttrs: MPU region attributes set to reserved value."
341 };
342
343 /*!
344 * ======== enableMPU ========
345 * Configuration parameter to enable MPU. Disabled by default.
346 */
347
348 config Bool enableMPU = false;
349
350 /*!
351 * ======== enableBackgroundRegion ========
352 * Configuration parameter to enable background region.
353 *
354 * If the MPU is enabled and background region is also enabled, any
355 * privileged access that does not map to any MPU memory region is
356 * handled using the default memory map.
357 *
358 * @p(blist)
359 * -See the "Protected Memory System Architecture (PMSA)" chapter
360 * in the {@link http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html ARM v7AR Architecture Reference Manual}
361 * for more info on the default memory map.
362 * @p
363 */
364
365 config Bool enableBackgroundRegion = true;
366
367 /*!
368 * @_nodoc
369 * ======== numRegions ========
370 * Number of MPU regions. Default is determined based on device type.
371 */
372 config UInt8 numRegions;
373
374 /*!
375 * ======== initRegionAttrsMeta ========
376 * Initializes the region attribute structure
377 *
378 * @param(attrs) Pointer to region attribute struct
379 */
380
381 metaonly Void initRegionAttrsMeta(RegionAttrs *regionAttrs);
382
383 /*!
384 * ======== setRegionMeta ========
385 * Statically sets the MPU region attributes
386 *
387 * @see ti.sysbios.family.arm.r5.MPU
388 *
389 * @param(regionId) MPU region number
390 * @param(regionBaseAddr) MPU region base address
391 * @param(regionSize) MPU region size
392 * @param(attrs) Protection attributes
393 */
394
395 metaonly Void setRegionMeta(UInt8 regionId, Ptr regionBaseAddr,
396 RegionSize regionSize, RegionAttrs attrs);
397
398 /*!
399 * ======== disable ========
400 * Disables the MPU.
401 *
402 * If the MPU is already disabled, then simply return.
403 * Otherwise this function does the following:
404 * @p(blist)
405 * - If the L1 data cache is enabled, write back invalidate all
406 * of L1 data cache.
407 * - If the L1 program cache is enabled, invalidate all of L1
408 * program cache.
409 * @p
410 *
411 * @a(Note)
412 * This function does not change the cache L1 data/program settings.
413 */
414
415 Void disable();
416
417 /*!
418 * ======== enable ========
419 * Enables the MPU.
420 *
421 * If the MPU is already enabled, then simply return.
422 * Otherwise this function does the following:
423 * @p(blist)
424 * If the L1 program cache is enabled, invalidate all of L1
425 * program cache.
426 * @p
427 *
428 * This function enables the MPU on the core it is called from.
429 *
430 * @a(Note)
431 * This function does not change the L1 data/program cache settings.
432 */
433
434 Void enable();
435
436 /*!
437 * @_nodoc
438 * ======== disableBR ========
439 * Disable background region
440 */
441 Void disableBR();
442
443 /*!
444 * @_nodoc
445 * ======== enableBR ========
446 * Enable background region
447 */
448 Void enableBR();
449
450 /*!
451 * ======== initRegionAttrs() ========
452 * Initializes the region attribute structure
453 *
454 * @param(attrs) Pointer to region attribute struct
455 */
456
457 Void initRegionAttrs(RegionAttrs *regionAttrs);
458
459 /*!
460 * ======== isEnabled ========
461 * Determines if the MPU is enabled
462 */
463
464 Bool isEnabled();
465
466 /*!
467 * ======== setRegion ========
468 * Sets the MPU region attributes
469 *
470 * @see ti.sysbios.family.arm.r5.MPU
471 *
472 * @param(regionId) MPU region number
473 * @param(regionBaseAddr) MPU region base address
474 * @param(regionSize) MPU region size
475 * @param(attrs) Protection attributes
476 */
477
478 Void setRegion(UInt8 regionId, Ptr regionBaseAddr,
479 RegionSize regionSize, RegionAttrs *attrs);
480
481 /*!
482 * @_nodoc
483 * ======== setRegionRaw ========
484 * Sets the MPU region attributes
485 *
486 * Unlike MPU_setRegion(), this API takes compact MPU register
487 * values and programs them without interpreting them.
488 *
489 * @param(rbar) MPU region base address
490 * @param(rasr) MPU region attribute and size
491 */
492 Void setRegionRaw(UInt32 rbar, UInt32 rasr);
493
494 /*!
495 * @_nodoc
496 * ======== startup ========
497 * startup function to initialize MPU module
498 */
499 Void startup();
500
501 internal:
502
503 504 505
506 struct RegionEntry {
507 UInt32 baseAddress;
508 UInt32 sizeAndEnable;
509 UInt32 regionAttrs;
510 };
511
512 513 514 515
516 config RegionEntry regionEntry[];
517
518 519 520 521 522 523 524 525 526 527 528
529 config Bool isMemoryMapped;
530
531 532 533 534
535 Void disableAsm();
536
537 538 539 540
541 Void enableAsm();
542
543 544 545 546
547 Void disableBRAsm();
548
549 550 551 552
553 Void enableBRAsm();
554
555 /*!
556 * ======== isEnabledAsm ========
557 * Assembly function that determines if the MPU is enabled
558 */
559 Bool isEnabledAsm();
560
561 562 563 564 565
566 Void setRegionAsm(UInt8 regionId, UInt32 regionBaseAddr, UInt32 regionSize,
567 UInt32 regionAttrs);
568
569 /*! Module state */
570 struct Module_State {
571 RegionEntry regionEntry[];
572
573 }
574 }