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 * ======== enableMPU ========
337 * Configuration parameter to enable MPU. Disabled by default.
338 */
339 config Bool enableMPU = false;
340
341 /*!
342 * ======== enableBackgroundRegion ========
343 * Configuration parameter to enable background region.
344 *
345 * If the MPU is enabled and background region is also enabled, any
346 * privileged access that does not map to any MPU memory region is
347 * handled using the default memory map.
348 *
349 * @p(blist)
350 * -See the "Protected Memory System Architecture (PMSA)" chapter
351 * in the {@link http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html ARM v7AR Architecture Reference Manual}
352 * for more info on the default memory map.
353 * @p
354 */
355 config Bool enableBackgroundRegion = true;
356
357 /*!
358 * @_nodoc
359 * ======== numRegions ========
360 * Number of MPU regions. Default is determined based on device type.
361 */
362 config UInt8 numRegions;
363
364 /*!
365 * ======== initRegionAttrsMeta ========
366 * Initializes the region attribute structure
367 *
368 * @param(attrs) Pointer to region attribute struct
369 */
370 metaonly Void initRegionAttrsMeta(RegionAttrs *regionAttrs);
371
372 /*!
373 * ======== setRegionMeta ========
374 * Statically sets the MPU region attributes
375 *
376 * @see ti.sysbios.family.arm.r5.MPU
377 *
378 * @param(regionId) MPU region number
379 * @param(regionBaseAddr) MPU region base address
380 * @param(regionSize) MPU region size
381 * @param(attrs) Protection attributes
382 */
383 metaonly Void setRegionMeta(UInt8 regionId, Ptr regionBaseAddr,
384 RegionSize regionSize, RegionAttrs attrs);
385
386 /*!
387 * ======== disable ========
388 * Disables the MPU.
389 *
390 * If the MPU is already disabled, then simply return.
391 * Otherwise this function does the following:
392 * @p(blist)
393 * - If the L1 data cache is enabled, write back invalidate all
394 * of L1 data cache.
395 * - If the L1 program cache is enabled, invalidate all of L1
396 * program cache.
397 * @p
398 *
399 * @a(Note)
400 * This function does not change the cache L1 data/program settings.
401 */
402 Void disable();
403
404 /*!
405 * ======== enable ========
406 * Enables the MPU.
407 *
408 * If the MPU is already enabled, then simply return.
409 * Otherwise this function does the following:
410 * @p(blist)
411 * If the L1 program cache is enabled, invalidate all of L1
412 * program cache.
413 * @p
414 *
415 * This function enables the MPU on the core it is called from.
416 *
417 * @a(Note)
418 * This function does not change the L1 data/program cache settings.
419 */
420 Void enable();
421
422 /*!
423 * @_nodoc
424 * ======== disableBR ========
425 * Disable background region
426 */
427 Void disableBR();
428
429 /*!
430 * @_nodoc
431 * ======== enableBR ========
432 * Enable background region
433 */
434 Void enableBR();
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 * ======== setRegion ========
452 * Sets the MPU region attributes
453 *
454 * @see ti.sysbios.family.arm.r5.MPU
455 *
456 * @param(regionId) MPU region number
457 * @param(regionBaseAddr) MPU region base address
458 * @param(regionSize) MPU region size
459 * @param(attrs) Protection attributes
460 */
461 Void setRegion(UInt8 regionId, Ptr regionBaseAddr,
462 RegionSize regionSize, RegionAttrs *attrs);
463
464 /*!
465 * @_nodoc
466 * ======== startup ========
467 * startup function to initialize MPU module
468 */
469 Void startup();
470
471 internal:
472
473 474 475
476 struct RegionEntry {
477 UInt32 baseAddress;
478 UInt32 sizeAndEnable;
479 UInt32 regionAttrs;
480 };
481
482 483 484 485
486 config RegionEntry regionEntry[];
487
488 489 490 491 492 493 494 495 496 497 498
499 config Bool isMemoryMapped;
500
501 502 503 504
505 Void disableAsm();
506
507 508 509 510
511 Void enableAsm();
512
513 514 515 516
517 Void disableBRAsm();
518
519 520 521 522
523 Void enableBRAsm();
524
525 /*!
526 * ======== isEnabledAsm ========
527 * Assembly function that determines if the MPU is enabled
528 */
529 Bool isEnabledAsm();
530
531 532 533 534 535
536 Void setRegionAsm(UInt8 regionId, UInt32 regionBaseAddr, UInt32 regionSize,
537 UInt32 regionAttrs);
538
539 /*! Module state */
540 struct Module_State {
541 RegionEntry regionEntry[];
542
543 }
544 }