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