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.c7x;
37
38 /*!
39 * ======== Mmu ========
40 * Memory Management Unit (MMU) Manager
41 *
42 * This module allows the C7x processor to map a 64-bit virtual address
43 * to a 48-bit physical address and enable/disable the MMU. It does this
44 * through translation tables in memory.
45 *
46 * Every application must register a Mmu init function (see {@link #initFunc})
47 * that contains calls to Mmu_map() to configure the MMU.
48 *
49 * *.cfg:
50 * @p(code)
51 * var Mmu = xdc.useModule('ti.sysbios.family.c7x.Mmu');
52 * Mmu.initFunc = "&Mmu_initFuncDefault";
53 * @p
54 *
55 * Example {@link #initFuncDefault Mmu_initFuncDefault()} provided
56 * function for J7 devices:
57 * @p(code)
58 * ...
59 *
60 * Void Mmu_initFuncDefault()
61 * {
62 * Bool ret;
63 * Mmu_MapAttrs attrs;
64 *
65 * Mmu_initMapAttrs(&attrs);
66 *
67 * // MAIR0 has a default memory type that is non-gathering and
68 * // non-reordering with no early write acknowledegement property.
69 * // In other words, strongly ordered memory type.
70 * attrs.attrIndx = Mmu_AttrIndx_MAIR0;
71 *
72 * // Map GICv3 registers
73 * ret = Mmu_map(0x01800000, 0x01800000, 0x00100000, &attrs);
74 * if (!ret) {
75 * goto fail;
76 * }
77 *
78 * // Map DMTimer registers
79 * ret = Mmu_map(0x02400000, 0x02400000, 0x000c0000, &attrs);
80 * if (!ret) {
81 * goto fail;
82 * }
83 *
84 * // Map UART registers
85 * ret = Mmu_map(0x02800000, 0x02800000, 0x00001000, &attrs);
86 * if (!ret) {
87 * goto fail;
88 * }
89 *
90 * // Map System Timer registers
91 * ret = Mmu_map(0x2A430000, 0x2A430000, 0x00001000, &attrs);
92 * if (!ret) {
93 * goto fail;
94 * }
95 *
96 * // MAIR7 has a default attribute type of Inner and Outer
97 * // write-back cacheable
98 * attrs.attrIndx = Mmu_AttrIndx_MAIR7;
99 *
100 * //Map MSMC SRAM
101 * ret = Mmu_map(0x70000000, 0x70000000, 0x00200000, &attrs);
102 * if (!ret) {
103 * goto fail;
104 * }
105 *
106 * return;
107 *
108 * fail:
109 * System_printf("Mmu config failed.\n");
110 * while (1);
111 * }
112 *
113 * @p
114 */
115
116 @DirectCall
117 @Template ("./Mmu.xdt")
118
119 module Mmu
120 {
121 const UInt8 PA_MAX_WIDTH = 48;
122
123 124 125
126 const UInt8 PA_SIZE_ENCODING = 0x5;
127
128
129
130
131
132 /*!
133 * ======== AttrIndx ========
134 * Memory attribute register (MAIR) index
135 *
136 * SYS/BIOS defines default values for MAIR register. See {@link #MAIR0},
137 * {@link #MAIR1}, {@link #MAIR2}, {@link #MAIR3}, {@link #MAIR4},
138 * {@link #MAIR5}, {@link #MAIR6} & {@link #MAIR7} for more info on the
139 * memory type defined by each MAIR register.
140 */
141 enum AttrIndx {
142 AttrIndx_MAIR0 = 0,
143 AttrIndx_MAIR1,
144 AttrIndx_MAIR2,
145 AttrIndx_MAIR3,
146 AttrIndx_MAIR4,
147 AttrIndx_MAIR5,
148 AttrIndx_MAIR6,
149 AttrIndx_MAIR7
150 };
151
152 /*!
153 * @_nodoc
154 * ======== DescriptorType ========
155 * Different descriptor type encodings:
156 * @p(blist)
157 * - Invalid or Fault entry (0b00 or 0b10)
158 * - Block descriptor entry (0b01)
159 * - Table descriptor entry (0b11)
160 * @p
161 */
162 enum DescriptorType {
163 DescriptorType_INVALID0 = 0, /*! Virtual address is unmapped */
164 DescriptorType_BLOCK = 1, /*! Block descriptor */
165 DescriptorType_INVALID1 = 2, /*! Virtual address is unmapped */
166 DescriptorType_TABLE = 3 /*! Next-level table address */
167 };
168
169 /*!
170 * ======== GranuleSize ========
171 * Memory translation {@link #granuleSize} granule size
172 */
173 enum GranuleSize {
174 GranuleSize_4KB = 0x1000,
175 GranuleSize_16KB = 0x4000,
176 GranuleSize_64KB = 0x10000
177 };
178
179 /*!
180 * ======== Shareable ========
181 * Shareability attribute
182 */
183 enum Shareable {
184 Shareable_NONE = 0x0,
185 Shareable_OUTER = 0x2,
186 Shareable_INNER = 0x3
187 };
188
189 /*!
190 * ======== AccessPerm ========
191 * Access Permissions
192 */
193 enum AccessPerm {
194 AccessPerm_PRIV_RW_USER_NONE = 0x0, 195
196 AccessPerm_PRIV_RW_USER_RW = 0x1, 197
198 AccessPerm_PRIV_RO_USER_NONE = 0x2, 199
200 AccessPerm_PRIV_RO_USER_RO = 0x3 201
202 };
203
204 /*! Mmu init function type definition. */
205 typedef Void (*InitFuncPtr)(void);
206
207 /*!
208 * ======== MapAttrs ========
209 * Structure containing attributes for memory map entry
210 */
211 struct MapAttrs {
212 Bool ns;
213 AccessPerm accessPerm; /*! privileged & user access permissions */
214 Bool privExecute; /*! privileged execute permission */
215 Bool userExecute; /*! user execute permission */
216 Shareable shareable; /*! shareability field value 0-3 */
217 AttrIndx attrIndx; /*! stage 1 memory attributes index field
218 for the indicated MAIRn reg value 0-7 */
219 Bool global; /*! global mmu entry ? (used by kernel
220 when memory protection extensions are
221 enabled) */
222 };
223
224
225
226 /*!
227 * ======== A_nullPointer ========
228 * Assert raised when a pointer is null
229 */
230 config xdc.runtime.Assert.Id A_nullPointer = {
231 msg: "A_nullPointer: Pointer is null"
232 };
233
234 /*!
235 * ======== A_vaddrOutOfRange ========
236 * Assert raised when virtual address passed is out of range
237 */
238 config xdc.runtime.Assert.Id A_vaddrOutOfRange = {
239 msg: "A_vaddrOutOfRange: Virtual address is out of range"
240 };
241
242 /*!
243 * ======== A_paddrOutOfRange ========
244 * Assert raised when physical address passed is out of range
245 */
246 config xdc.runtime.Assert.Id A_paddrOutOfRange = {
247 msg: "A_paddrOutOfRange: Physical address is out of range"
248 };
249
250 /*!
251 * ======== A_unalignedVaddr ========
252 * Assert raised if unaligned virtual address passed to Mmu_map().
253 */
254 config xdc.runtime.Assert.Id A_unalignedVaddr =
255 {msg: "A_unalignedVaddr: Virtual address not page aligned"};
256
257 /*!
258 * ======== A_unalignedPaddr ========
259 * Assert raised if unaligned physical address passed to Mmu_map().
260 */
261
262 config xdc.runtime.Assert.Id A_unalignedPaddr =
263 {msg: "A_unalignedPaddr: Physical address not page aligned"};
264
265 /*!
266 * ======== A_unalignedSize ========
267 * Assert raised if unaligned size passed to Mmu_map().
268 */
269 config xdc.runtime.Assert.Id A_unalignedSize =
270 {msg: "A_unalignedSize: Mmu mapping size not page aligned"};
271
272 /*!
273 * ======== defaultMapAttrs ========
274 * default descriptor attributes structure
275 */
276 config MapAttrs defaultMapAttrs = {
277 ns: 1,
278 accessPerm: AccessPerm_PRIV_RW_USER_NONE,
279 privExecute: true,
280 userExecute: false,
281 shareable: Shareable_OUTER,
282 attrIndx: AttrIndx_MAIR0,
283 global: true
284 };
285
286 /*!
287 * ======== enableMMU ========
288 * Configuration parameter to enable MMU.
289 */
290 config Bool enableMMU = true;
291
292 /*!
293 * ======== granuleSize ========
294 * Memory translation granule size. Default is 4KB.
295 *
296 * The granule size determines the smallest page size that can be
297 * mapped with the MMU.
298 */
299 config GranuleSize granuleSize = GranuleSize_4KB;
300
301 /*!
302 * ======== MAIR0 ========
303 * Memory attribute 0.
304 *
305 * Default is memory with non-gathering, non-reordering and no early write
306 * acknowledegement property.
307 */
308 config UInt8 MAIR0 = 0x00;
309
310 /*!
311 * ======== MAIR1 ========
312 * Memory attribute 1
313 *
314 * Default is memory with non-gathering, non-reordering and early write
315 * acknowledegement property.
316 */
317 config UInt8 MAIR1 = 0x04;
318
319 /*!
320 * ======== MAIR2 ========
321 * Memory attribute 2
322 *
323 * Default is memory with non-gathering, reordering and early write
324 * acknowledegement property.
325 */
326 config UInt8 MAIR2 = 0x08;
327
328 /*!
329 * ======== MAIR3 ========
330 * Memory attribute 3
331 *
332 * Default is memory with gathering, reordering and early write
333 * acknowledegement property.
334 */
335 config UInt8 MAIR3 = 0x0C;
336
337 /*!
338 * ======== MAIR4 ========
339 * Memory attribute 4
340 *
341 * Default is normal inner & outer non-cacheable memory.
342 */
343 config UInt8 MAIR4 = 0x44;
344
345 /*!
346 * ======== MAIR5 ========
347 * Memory attribute 5
348 *
349 * Default is normal outer non-cacheable, inner write-back cacheable
350 * non-transient memory.
351 */
352 config UInt8 MAIR5 = 0x4F;
353
354 /*!
355 * ======== MAIR6 ========
356 * Memory attribute 6
357 *
358 * Default is normal outer & inner write-through cacheable non-transient
359 * memory.
360 */
361 config UInt8 MAIR6 = 0xBB;
362
363 /*!
364 * ======== MAIR7 ========
365 * Memory attribute 7
366 *
367 * Default is normal outer and inner write-back cacheable non-transient
368 * memory.
369 */
370 config UInt8 MAIR7 = 0x7D;
371
372 /*!
373 * ======== initFunc ========
374 * MMU init function pointer
375 *
376 * This config param is initialized to point to an init function that
377 * will perform MMU configuration using the {@link #map} runtime APIs
378 * provided by this module. The init function is called before
379 * C initialization i.e. before the data section is initialized.
380 * Therefore, care must be taken to not rely on any initialized
381 * data variables.
382 *
383 * By default, the {@link #initFuncDefault Mmu_initFuncDefault} function
384 * designed for use with AM65x devices is used if the application doesn't
385 * provide its own implementation.
386 */
387 config InitFuncPtr initFunc = initFuncDefault;
388
389 /*!
390 * ======== tableMemory ========
391 * Memory segment in which to place Mmu tables
392 *
393 * If set to a non-empty string, this config param identifies the memory
394 * segment in which the Mmu tables are placed.
395 *
396 * To prevent placement of the Mmu tables altogether, set to empty
397 * string "".
398 */
399 config String tableMemory = "DDR";
400
401 /*!
402 * ======== tableMemory_NS ========
403 * Memory segment in which to place Mmu tables
404 *
405 * If set to a non-empty string, this config param identifies the memory
406 * segment in which the Mmu tables are placed.
407 *
408 * To prevent placement of the Mmu tables altogether, set to empty
409 * string "".
410 */
411 config String tableMemory_NS = "MSMC";
412
413 /*!
414 * ======== tableArraySection ========
415 * Contains a table array and some state variables.
416 * This section is uninitialized.
417 *
418 * Note: Memory containing the table array must be marked as inner &
419 * and outer shareable, and inner and outer write-back write-allocate
420 * cacheable.
421 */
422 metaonly config String tableArraySection =
423 ".data.ti_sysbios_family_c7x_Mmu_tableArray";
424
425 /*!
426 * ======== tableArraySection_NS ========
427 * Contains a table array and some state variables.
428 * This section is uninitialized.
429 *
430 * Note: Memory containing the table array must be marked as inner &
431 * and outer shareable, and inner and outer write-back write-allocate
432 * cacheable.
433 */
434 metaonly config String tableArraySection_NS =
435 ".data.ti_sysbios_family_c7x_Mmu_tableArray_NS";
436
437 /*!
438 * ======== tableArrayLen ========
439 * Length of array of MMU tables
440 *
441 * MMU module allocates memory for MMU table from a table array.
442 * This config param controls number of MMU tables supported.
443 * Each table in the array is the size of the MMU table and aligned
444 * to the table's size.
445 *
446 * @a(Note)
447 * MMU table size is same as translation granule size (see
448 * {@link #granuleSize})
449 */
450 config UInt tableArrayLen = 16;
451
452 /*!
453 * ======== enable ========
454 * Enables the MMU.
455 *
456 * If the MMU is already enabled, then simply return.
457 * Otherwise this function does the following:
458 * @p(blist)
459 * If the L1 program cache is enabled, invalidate all of L1
460 * program cache.
461 * @p
462 *
463 * This function enables the MMU on the core it is called from.
464 *
465 * @a(Note)
466 * This function does not change the L1 data/program cache settings.
467 */
468 Void enable();
469
470 /*!
471 * ======== initMapAttrs() ========
472 * Initializes the map attribute structure
473 *
474 * @param(attrs) Pointer to map attribute struct
475 */
476 Void initMapAttrs(MapAttrs *descAttrs);
477
478 /*!
479 * ======== isEnabled ========
480 * Determines if the MMU is enabled
481 */
482 Bool isEnabled();
483
484 /*!
485 * ======== map ========
486 * Add a mapping to MMU table
487 *
488 * This API adds a mapping for the given virtual and physical
489 * address to the MMU table and sets the memory attributes
490 * as per the attributes passed to the function.
491 *
492 * This API internally disables interrupts before updating the
493 * MMU table. The interrupts may be disabled for a long period
494 * of time. It is therefore recommended to either call this
495 * API in the Mmu.initFunc or in main().
496 *
497 * The smallest mapping size (page size) supported is determined
498 * by the {@link #granuleSize}. The largess mapping size supported
499 * is 2^{@link #PA_MAX_WIDTH}-1.
500 *
501 * @param(vaddr) Virtual address (aligned to {@link #granuleSize})
502 * @param(paddr) Physical address (aligned to {@link #granuleSize})
503 * @param(size) Region size (aligned to {@link #granuleSize})
504 * @param(attrs) Memory region attributes
505 * @b(returns) Status (True-success, False-failed)
506 */
507 Bool map(UInt64 vaddr, UInt64 paddr, SizeT size, MapAttrs *attrs, Bool secure);
508
509 /*!
510 * ======== setMAIR ========
511 * Sets the memory attribute encoding in the MAIRn register.
512 *
513 * MAIR provides the memory attribute encodings to the possible
514 * {@link #DescriptorAttrs attrIndx} values in a long-descriptor format
515 * translation table entry for stage 1 translations.
516 *
517 * {@link #DescriptorAttrs attrIndx}[2:0] selects the ATTRn bit-field in
518 * the MAIR register.
519 *
520 * Memory Attribute Indirection Register (MAIR) bit assignments:
521 * @p(code)
522 * --------------------------------------------------------------
523 * |63 | 56|55 | 48|47 | 40|39 | 32|
524 * --------------------------------------------------------------
525 * MAIR | ATTR7 | ATTR6 | ATTR5 | ATTR4 |
526 * --------------------------------------------------------------
527 * |31 | 24|23 | 16|15 | 8|7 | 0|
528 * --------------------------------------------------------------
529 * MAIR | ATTR3 | ATTR2 | ATTR1 | ATTR0 |
530 * --------------------------------------------------------------
531 * @p
532 *
533 * SYS/BIOS has 8 MAIR config params (MAIR0, MAIR2, ...) that are
534 * initialized to default value. In order to have a custom memory
535 * attribute, a user can either change the MAIRn config param in
536 * the application's cfg script or call this runtime API.
537 *
538 * For more details on MAIR encodings please refer
539 * {@link https://developer.arm.com/docs/ddi0487/latest/arm-architecture-reference-manual-armv8-for-armv8-a-architecture-profile v8A ARM Architecture Reference Manual}
540 *
541 * @param(attrIndx) Memory attribute index
542 * @param(attr) Memory attribute encoding
543 *
544 * @a(Note)
545 * This function only invalidates the TLB and does not flush the cache.
546 * If the cacheability attribute of a region of memory is changed by
547 * modifying the MAIR entry for the region, the application needs to
548 * flush and invalidate the region of memory from the cache.
549 */
550 Void setMAIR(UInt8 attrIndx, UInt8 attr);
551
552 /*!
553 * @_nodoc
554 * ======== startup ========
555 * startup function to initialize MMU module
556 */
557 Void startup();
558
559 /*!
560 * ======== tlbInvAll ========
561 * Invalidate entire TLB (both data and instruction)
562 */
563 Void tlbInvAll(UInt64 type);
564
565 /*!
566 * ======== initFuncDefault ========
567 * default Mmu.initFunc implementation.
568 *
569 * provides Mmu regions for the AM65x's GIC, DMTimer, UART, SYSTIMER,
570 * and MSMC memory.
571 */
572 Void initFuncDefault();
573
574 internal:
575
576 577 578
579 struct ConfigInfo {
580 UInt64 indexMask;
581 UInt32 tableLength;
582 UInt8 tableOffset[4];
583 UInt8 granuleSizeBits;
584 UInt8 indexBits;
585 Bool noLevel0Table;
586 };
587
588 589 590
591 Void disable();
592
593 594 595
596 Void disableI();
597
598 599 600
601 Void enableI();
602
603 604 605
606 Void enableI_secure();
607
608 609 610 611 612 613
614 config ConfigInfo configInfo;
615
616 617 618
619 Void addBlockEntry(UInt8 level, UInt64 *tablePtr, UInt16 tableIdx,
620 UInt64 paddr, MapAttrs *attrs);
621
622 623 624
625 UInt64* addTableEntry(UInt64 *tablePtr, UInt16 tableIdx, MapAttrs *attrs, Bool secure);
626
627 628 629
630 UInt64* allocTable(Bool secure);
631
632 633 634
635 Void freeTable(UInt64 *table);
636
637 638 639
640 Void init(Ptr tableAddr, Bool secure);
641
642 643 644
645 Void readBlockEntry(UInt8 level, UInt64 *tablePtr, UInt16 tableIdx,
646 UInt64 *paddr, MapAttrs *attrs);
647
648 649 650
651 Void setMAIRAsm(UInt8 attrIndx, UInt8 attr);
652
653 654 655
656 Bool tableWalk(UInt8 level, UInt64 *tablePtr, UInt64 *vaddr, UInt64 *paddr,
657 SizeT *size, MapAttrs *attrs, Bool secure);
658
659 660 661
662 Void setTCR(UInt64 regVal, Bool secure);
663
664 /*! Module state */
665 struct Module_State {
666 }
667 }