1    /*
     2     * Copyright (c) 2013, Texas Instruments Incorporated
     3     * All rights reserved.
     4     *
     5     * Redistribution and use in source and binary forms, with or without
     6     * modification, are permitted provided that the following conditions
     7     * are met:
     8     *
     9     * *  Redistributions of source code must retain the above copyright
    10     *    notice, this list of conditions and the following disclaimer.
    11     *
    12     * *  Redistributions in binary form must reproduce the above copyright
    13     *    notice, this list of conditions and the following disclaimer in the
    14     *    documentation and/or other materials provided with the distribution.
    15     *
    16     * *  Neither the name of Texas Instruments Incorporated nor the names of
    17     *    its contributors may be used to endorse or promote products derived
    18     *    from this software without specific prior written permission.
    19     *
    20     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    21     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    22     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    23     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    24     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    25     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    26     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
    27     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
    28     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
    29     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    30     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    31     */
    32    /*
    33     *  ======== Mmu.xdc ========
    34     */
    35    
    36    package ti.sysbios.family.arm.a15;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    /*!
    41     *  ======== Mmu ========
    42     *  Memory Management Unit Manager.
    43     *
    44     *  This module allows the ARM processor to map a 32-bit virtual address
    45     *  to a 40-bit physical address (supports Large physical address extensions)
    46     *  and enable/disable the MMU. It does this through translation tables
    47     *  in memory. The MMU hardware supports upto 3-levels of translation tables.
    48     *  This module only supports the first 2 levels of translation tables.
    49     *  The level1 translation table is a 32B descriptor table comprising of
    50     *  four 64bit entries. There can be upto 4 level2 translation tables,
    51     *  each 4KB in size and comprising of 512 64bit entries.
    52     *
    53     *  Each entry in the level1 table either gives the base address and
    54     *  defines the attributes of a memory area of size 1GB or gives the
    55     *  address of the next level of translation table and some attributes
    56     *  for that translation.
    57     *
    58     *  Each entry in the level2 table either gives the base address and
    59     *  defines the attributes of a memory area of size 2MB or gives the
    60     *  address of the next level of translation table and some attributes
    61     *  for that translation.
    62     *
    63     *  By default, the MMU level1 and level2 translation tables are initialized
    64     *  with cache-enabled entries for every memory-segment defined in the
    65     *  platform (see {@link #cachePlatformMemory}). Cache-disabled entries are
    66     *  also added for the peripheral addresses used by SYS/BIOS
    67     *  (i.e. Timers, Interrupt controller).
    68     *
    69     *  The level1 translation table is placed in an output section called
    70     *  "ti.sysbios.family.arm.a15.mmuFirstLevelTableSection". Each of the
    71     *  level2 translation table is placed in output sections called
    72     *  "ti.sysbios.family.arm.a15.mmuSecondLevelTableSection0",
    73     *  "ti.sysbios.family.arm.a15.mmuSecondLevelTableSection1",
    74     *  "ti.sysbios.family.arm.a15.mmuSecondLevelTableSection2", and
    75     *  "ti.sysbios.family.arm.a15.mmuSecondLevelTableSection3". These
    76     *  sections are placed into the platform's default dataMemory and
    77     *  in order to minimize object file size,
    78     *  specified to not be initialized via the "NOLOAD" type on GNU compilers
    79     *  and "NOINIT" on TI compilers.
    80     *
    81     *  This module does not manage the third level descriptor tables.
    82     *
    83     *  The following is an example of how to place the MMU table
    84     *  and how to enable L1/L2 data caching for the address range
    85     *  0x80000000-0x90000000 in the *.cfg file:
    86     *
    87     *  @p(code)
    88     *
    89     *    var Mmu = xdc.useModule('ti.sysbios.family.arm.a15.Mmu');
    90     *
    91     *    // descriptor attribute structure
    92     *    var attrs = new Mmu.DescriptorAttrs();
    93     *
    94     *    Mmu.initDescAttrsMeta(attrs);
    95     *    attrs.type = Mmu.DescriptorType_BLOCK;    // BLOCK descriptor
    96     *    attrs.shareable = 3;                      // inner-sharerable
    97     *    attrs.attrIndx = 2;                       // MAIR0 Byte2 describes
    98     *                                              // memory attributes for
    99     *                                              // this level2 entry
   100     *
   101     *    // write memory region attribute in mairRegAttr[2] i.e. MAIR0 Reg Byte2
   102     *    Mmu.setMAIRMeta(2, 0xFF);              // Mark mem regions as cacheable
   103     *
   104     *    // Set the descriptor for each entry in the address range
   105     *    for (var i=0x80000000; i < 0x90000000; i = i + 0x00200000) {
   106     *        // Each 'BLOCK' descriptor entry spans a 2MB address range
   107     *        Mmu.setSecondLevelDescMeta(i, i, attrs);
   108     *    }
   109     *
   110     *    var memmap = Program.cpu.memoryMap;
   111     *    var DDR = null;
   112     *
   113     *    // Find DDR in memory map
   114     *    for (var i=0; i < memmap.length; i++) {
   115     *        if (memmap[i].name == "DDR") {
   116     *            DDR = memmap[i];
   117     *        }
   118     *    }
   119     *
   120     *    // Place the MMU table in the DDR memory segment if it exists
   121     *    if (DDR != null) {
   122     *        var sectionName =
   123     *                  "ti.sysbios.family.arm.a15.mmuSecondLevelTableSection2";
   124     *        Program.sectMap[sectionName] = new Program.SectionSpec();
   125     *        Program.sectMap[sectionName].type = "NOLOAD";
   126     *        Program.sectMap[sectionName].loadSegment = "DDR";
   127     *    }
   128     *    else {
   129     *        print("No DDR memory segment was found");
   130     *    }
   131     *
   132     *  @p
   133     *
   134     *  The following example demonstrates how to add a peripheral's address
   135     *  to the MMU table so that it can be accessed by code at runtime:
   136     *
   137     *  @p(code)
   138     *    var Cache = xdc.useModule('ti.sysbios.family.arm.a15.Cache');
   139     *    var Mmu = xdc.useModule('ti.sysbios.family.arm.a15.Mmu');
   140     *
   141     *    // Enable the cache
   142     *    Cache.enableCache = true;
   143     *
   144     *    // Enable the MMU (Required for L1/L2 data caching)
   145     *    Mmu.enableMMU = true;
   146     *
   147     *    // descriptor attribute structure
   148     *    var peripheralAttrs = new Mmu.DescriptorAttrs();
   149     *
   150     *    Mmu.initDescAttrsMeta(peripheralAttrs);
   151     *
   152     *    peripheralAttrs.type = Mmu.DescriptorType_BLOCK;  // BLOCK descriptor
   153     *    peripheralAttrs.noExecute = true;                 // not executable
   154     *    peripheralAttrs.accPerm = 0;                      // read/write at PL1
   155     *    peripheralAttrs.attrIndx = 1;                     // MAIR0 Byte1 describes
   156     *                                                      // memory attributes for
   157     *                                                      // each BLOCK MMU entry
   158     *
   159     *    // write memory region attribute in mairRegAttr[1] i.e. MAIR0 Reg Byte1
   160     *    Mmu.setMAIRMeta(1, 0x0);    // Mark mem regions as strongly ordered memory
   161     *
   162     *    // Define the base address of the 2 MB page
   163     *    // the peripheral resides in.
   164     *    var peripheralBaseAddr = 0xa0400000;
   165     *
   166     *    // Configure the corresponding MMU page descriptor accordingly
   167     *    Mmu.setSecondLevelDescMeta(peripheralBaseAddr,
   168     *                               peripheralBaseAddr,
   169     *                               peripheralAttrs);
   170     *  @p
   171     *
   172     *  The following example demonstrates how to modify the first level MMU entry
   173     *  at runtime. This example changes the descriptor type of the first level
   174     *  table entry from Table (default) to Block (maps memory region of size 1GB).
   175     *
   176     *  @p(code)
   177     *  ...
   178     *
   179     *  Void main(Int argc, Char * argv[])
   180     *  {
   181     *      Mmu_DescriptorAttrs attrs;
   182     *      Mmu_initDescAttrs(&attrs);
   183     *
   184     *      attrs.type = Mmu_DescriptorType_BLOCK;
   185     *      attrs.shareable = 0;            // non-shareable
   186     *      attrs.accPerm = 1;              // read/write at any privelege level
   187     *      attrs.attrIndx = 3;             // Use MAIR0 Register Byte 3 for
   188     *                                      // determining the memory attributes
   189     *                                      // for each MMU entry
   190     *
   191     *      // attrIndx[2] = 0b0 selects MAIR0
   192     *      // attrIndx[1:0] = 0b11 selects Byte 3 in MAIR0
   193     *      //
   194     *      // A value of 0x4F is written to Byte 3 of MAIR0. This marks the memory
   195     *      // as Normal Memory that is outer non-cacheable and inner write-back
   196     *      // cacheable for both reads and writes.
   197     *
   198     *      Mmu_setMAIR(3, 0x4F);
   199     *
   200     *      // Update the first level table's MMU entry for 0x80000000 with the
   201     *      // new attributes.
   202     *      Mmu_setFirstLevelDesc((Ptr)0x80000000, (UInt64)0x80000000, &attrs);
   203     *  }
   204     *
   205     *  @p
   206     *
   207     *  The following example demonstrates how to modify the memory attributes
   208     *  for a second level MMU entry at runtime.
   209     *
   210     *  @p(code)
   211     *  ...
   212     *
   213     *  Void main(Int argc, Char * argv[])
   214     *  {
   215     *      Mmu_DescriptorAttrs attrs;
   216     *      Mmu_initDescAttrs(&attrs);
   217     *
   218     *      attrs.type = Mmu_DescriptorType_BLOCK;
   219     *      attrs.shareable = 0;            // non-shareable
   220     *      attrs.accPerm = 1;              // read/write at any privelege level
   221     *      attrs.attrIndx = 4;             // Use MAIR1 Register Byte 0 for
   222     *                                      // determining the memory attributes
   223     *                                      // for each MMU entry
   224     *
   225     *      // attrIndx[2] = 0b1 selects MAIR1
   226     *      // attrIndx[1:0] = 0b00 selects Byte 0 in MAIR1
   227     *      //
   228     *      // A value of 0x4F is written to Byte 0 of MAIR1. This marks the memory
   229     *      // as Normal Memory that is outer non-cacheable and inner write-back
   230     *      // cacheable for both reads and writes.
   231     *
   232     *      Mmu_setMAIR(4, 0x4F);
   233     *
   234     *      // Update the MMU entry for 0x80000000 with the new attributes.
   235     *      Mmu_setSecondLevelDesc((Ptr)0x80000000, (UInt64)0x80000000, &attrs);
   236     *  }
   237     *
   238     *  @p
   239     *
   240     *  Notes:
   241     *  @p(blist)
   242     *      -There are size and alignment requirements on the third
   243     *       level descriptor tables depending on the page size.
   244     *      -See the {@link http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html ARM v7AR Architecture Reference Manual}
   245     *       for more info.
   246     *  @p
   247     *
   248     */
   249    
   250    @Template ("./Mmu.xdt") /* generate function to init MMU page table */
   251    @ModuleStartup
   252    
   253    module Mmu
   254    {
   255        const UInt NUM_LEVEL1_ENTRIES = 4;
   256    
   257        const UInt NUM_LEVEL2_ENTRIES = 512;
   258    
   259        // -------- ROV views --------
   260    
   261        /*! @_nodoc */
   262        metaonly struct PageView {
   263            String      Type;
   264            String      AddrVirtual;
   265            String      AddrPhysical;
   266            String      NextLevelTablePtr;
   267            Bool        NSTable;
   268            String      APTable;
   269            Bool        XNTable;
   270            Bool        PXNTable;
   271            Bool        NoExecute;
   272            Bool        PrivNoExecute;
   273            Bool        Contiguous;
   274            Bool        NotGlobal;
   275            Bool        AccessFlag;
   276            String      Shareable;
   277            String      AccessPerm;
   278            Bool        NonSecure;
   279            String      MemAttr;
   280            String      AttrIndx;
   281        };
   282    
   283        @Facet
   284        metaonly config ViewInfo.Instance rovViewInfo =
   285            ViewInfo.create({
   286                viewMap: [
   287                    ['Level1View', {
   288                        type: ViewInfo.MODULE_DATA,
   289                        viewInitFxn: 'viewLevel1Page',
   290                        structName: 'PageView'
   291                    }],
   292                    ['Level2View', {
   293                        type: ViewInfo.TREE_TABLE,
   294                        viewInitFxn: 'viewLevel2Page',
   295                        structName: 'PageView'
   296                    }]
   297               ]
   298           });
   299    
   300        /*!
   301         *  ======== First and Second Level descriptors ========
   302         *
   303         *  Different descriptor type encodings:
   304         *  @p(blist)
   305         *  - Invalid or Fault entry (0b00 or 0b10)
   306         *  - Block descriptor entry (0b01)
   307         *  - Table descriptor entry (0b11)
   308         *  @p
   309         *
   310         *  If a First-level table contains only one entry, it would be skipped,
   311         *  and the TTBR points to the Second-level table. This happens if the
   312         *  VA address range is 30 bits or less.
   313         */
   314        enum DescriptorType {
   315            DescriptorType_INVALID0 = 0,   /*! Virtual address is unmapped     */
   316            DescriptorType_BLOCK = 1,      /*! Block descriptor                */
   317            DescriptorType_INVALID1 = 2,   /*! Virtual address is unmapped     */
   318            DescriptorType_TABLE = 3       /*! Next-level table address        */
   319        };
   320    
   321        /*!
   322         *  Structure for setting first and second level descriptor entries
   323         *
   324         *  nsTable, apTable, xnTable and pxnTable fields are used only for
   325         *  DescriptorType.TABLE
   326         *
   327         *  noExecute, privNoExecute, contiguous, notGlobal, accessFlag, shareable,
   328         *  accPerm, nonSecure and attrIndx fields are used only for
   329         *  DescriptorType.BLOCK
   330         */
   331        struct DescriptorAttrs {
   332            DescriptorType type;    /*! first level descriptor type             */
   333            Bool  nsTable;          /*! security level for subsequent levels    */
   334            UInt8 apTable;          /*! access perm limit for subsequent levels */
   335            Bool  xnTable;          /*! XN limit for subsequent levels          */
   336            Bool  pxnTable;         /*! PXN limit for subsequent levels         */
   337            Bool  noExecute;        /*! execute-never bit                       */
   338            Bool  privNoExecute;    /*! privileged execute-never bit            */
   339            Bool  contiguous;       /*! hint bit indicating 16 adjacent table
   340                                        entries point to contiguos memory       */
   341            Bool  notGlobal;        /*! not global bit                          */
   342            Bool  accessFlag;       /*! access flag                             */
   343            UInt8 shareable;        /*! shareability field value 0-3            */
   344            UInt8 accPerm;          /*! access permission bits value 0-3        */
   345            Bool  nonSecure;        /*! non-secure bit                          */
   346            UInt8 attrIndx;         /*! stage 1 memory attributes index field for
   347                                        the indicated MAIRn register value 0-7  */
   348            UInt8 reserved;         /*! Bits[58:55] reserved for software use   */
   349        };
   350    
   351        /*!
   352         *  ======== A_nullPointer ========
   353         *  Assert raised when a pointer is null
   354         */
   355        config xdc.runtime.Assert.Id A_nullPointer  = {
   356            msg: "A_nullPointer: Pointer is null"
   357        };
   358    
   359        /*!
   360         *  ======== A_unknownDescType ========
   361         *  Assert raised when the descriptor type is not recognized.
   362         */
   363        config xdc.runtime.Assert.Id A_unknownDescType =
   364            {msg: "A_unknownDescType: Descriptor type is not recognized"};
   365    
   366        /*! default descriptor attributes structure */
   367        config DescriptorAttrs defaultAttrs = {
   368            type: DescriptorType_TABLE, /* TABLE descriptor */
   369            nsTable: false,         /* security level for subsequent levels    */
   370            apTable: 0,             /* access perm limit for subsequent levels */
   371            xnTable: false,         /* XN limit for subsequent levels          */
   372            pxnTable: false,        /* PXN limit for subsequent levels         */
   373            noExecute: false,       /* execute-never bit                       */
   374            privNoExecute: false,   /* privileged execute-never bit            */
   375            contiguous: false,      /* hint bit indicating 16 adjacent table
   376                                       entries point to contiguos memory       */
   377            notGlobal: false,       /* not global bit                          */
   378            accessFlag: true,       /* access flag                             */
   379            shareable: 0,           /* shareability field                      */
   380            accPerm: 0,             /* access permission bits                  */
   381            nonSecure: false,       /* non-secure bit                          */
   382            attrIndx: 0,            /* stage 1 memory attributes index field
   383                                       for the indicated MAIRn register        */
   384            reserved: 0             /* Bits[58:55] reserved for software use   */
   385        };
   386    
   387        /*!
   388         *  ======== enableMMU ========
   389         *  Configuration parameter to enable MMU.
   390         */
   391        config Bool enableMMU = true;
   392    
   393        /*!
   394         *  ======== cachePlatformMemory ========
   395         *  Flag to automatically mark platform's code/data/stack memory as
   396         *  cacheable in MMU descriptor table
   397         *
   398         *  By default, all memory regions defined in the platform an
   399         *  application is built with are marked as cacheable.
   400         *
   401         *  @see xdc.bld.Program#platform
   402         *
   403         *  If manual configuration of memory regions is required, set
   404         *  this config parameter to 'false'.
   405         */
   406        metaonly config Bool cachePlatformMemory = true;
   407    
   408        /*!
   409         *  ======== setMAIRMeta ========
   410         *  Statically sets the memory attribute encoding in the MAIRn register.
   411         *
   412         *  MAIR0 and MAIR1 provide the memory attribute encodings to the possible
   413         *  {@link #DescriptorAttrs attrIndx} values in a Long-descriptor format
   414         *  translation table entry for stage 1 translations (see {@link #setMAIR}
   415         *  for more details).
   416         *
   417         *  @param(attrIndx)     Select appropriate MAIR register (0 or 1)
   418         *                       and byte offset within selected register
   419         *  @param(attr)         Memory attribute encoding
   420         */
   421        metaonly Void setMAIRMeta(UInt attrIndx, UInt attr);
   422    
   423        /*!
   424         *  ======== initDescAttrsMeta ========
   425         *  Initializes the descriptor attribute structure
   426         *
   427         *   @param(attrs)        Pointer to descriptor attribute struct
   428         */
   429        metaonly Void initDescAttrsMeta(DescriptorAttrs *descAttrs);
   430    
   431        /*!
   432         *  ======== setFirstLevelDescMeta ========
   433         *  Statically sets the descriptor for the virtual address.
   434         *
   435         *  The first level table entry for the virtual address is mapped
   436         *  to the physical address with the attributes specified. The
   437         *  descriptor table is effective when the MMU is enabled.
   438         *
   439         *  @see ti.sysbios.family.arm.a15.Mmu
   440         *
   441         *  @param(virtualAddr)  The modified virtual address
   442         *  @param(phyAddr)      The physical address
   443         *  @param(attrs)        Pointer to first level descriptor attribute struct
   444         */
   445        metaonly Void setFirstLevelDescMeta(Ptr virtualAddr, UInt64 phyAddr,
   446                                            DescriptorAttrs attrs);
   447    
   448        /*!
   449         *  ======== setSecondLevelDescMeta ========
   450         *  Statically sets the descriptor for the virtual address.
   451         *
   452         *  The second level table entry for the virtual address is mapped
   453         *  to the physical address with the attributes specified. The
   454         *  descriptor table is effective when the MMU is enabled.
   455         *
   456         *  @see ti.sysbios.family.arm.a15.Mmu
   457         *
   458         *  @param(virtualAddr)  The modified virtual address
   459         *  @param(phyAddr)      The physical address
   460         *  @param(attrs)        Pointer to second level descriptor attribute struct
   461         */
   462        metaonly Void setSecondLevelDescMeta(Ptr virtualAddr, UInt64 phyAddr,
   463                                            DescriptorAttrs attrs);
   464    
   465        /*!
   466         *  ======== disable ========
   467         *  Disables the MMU.
   468         *
   469         *  If the MMU is already disabled, then simply return.
   470         *  Otherwise this function does the following:
   471         *  @p(blist)
   472         *  - If the L1 data cache is enabled, write back invalidate all
   473         *  of L1 data cache.
   474         *  - If the L1 program cache is enabled, invalidate all of L1
   475         *  program cache.
   476         *  @p
   477         *
   478         *  @a(Note)
   479         *  This function does not change the cache L1 data/program settings.
   480         */
   481        @DirectCall
   482        Void disable();
   483    
   484        /*!
   485         *  ======== enable ========
   486         *  Enables the MMU.
   487         *
   488         *  If the MMU is already enabled, then simply return.
   489         *  Otherwise this function does the following:
   490         *  @p(blist)
   491         *  If the L1 program cache is enabled, invalidate all of L1
   492         *  program cache.
   493         *  @p
   494         *
   495         *  @a(Note)
   496         *  This function does not change the L1 data/program cache settings.
   497         */
   498        @DirectCall
   499        Void enable();
   500    
   501        /*!
   502         *  ======== initDescAttrs() ========
   503         *  Initializes the descriptor attribute structure
   504         *
   505         *  @param(attrs)      Pointer to descriptor attribute struct
   506         */
   507        @DirectCall
   508        Void initDescAttrs(DescriptorAttrs *descAttrs);
   509    
   510        /*!
   511         *  ======== isEnabled ========
   512         *  Determines if the MMU is enabled
   513         */
   514        @DirectCall
   515        Bool isEnabled();
   516    
   517        /*!
   518         *  ======== setMAIR ========
   519         *  Sets the memory attribute encoding in the MAIRn register.
   520         *
   521         *  MAIR0 and MAIR1 provide the memory attribute encodings to the possible
   522         *  {@link #DescriptorAttrs attrIndx} values in a long-descriptor format
   523         *  translation table entry for stage 1 translations.
   524         *
   525         *  {@link #DescriptorAttrs attrIndx}[1:0] selects the ATTRn bit-field in
   526         *  the selected MAIR register.
   527         *
   528         *  {@link #DescriptorAttrs attrIndx}[2] selects the MAIR register.
   529         *  @p(blist)
   530         *   - If {@link #DescriptorAttrs attrIndx}[2] == 0, use MAIR0
   531         *   - If {@link #DescriptorAttrs attrIndx}[2] == 1, use MAIR1
   532         *  @p
   533         *
   534         *  Memory Attribute Indirection Register (MAIR) 0 and 1 bit assignments:
   535         *  @p(code)
   536         *        |31     |    24|23     |     16|15     |      8|7      |      0|
   537         *         --------------------------------------------------------------
   538         *  MAIR0 |     ATTR3    |     ATTR2     |     ATTR1     |     ATTR0     |
   539         *         --------------------------------------------------------------
   540         *  MAIR1 |     ATTR7    |     ATTR6     |     ATTR5     |     ATTR4     |
   541         *         --------------------------------------------------------------
   542         *  @p
   543         *
   544         *  SYS/BIOS assigns the following defaults to MAIR0 ATTR0, ATTR1 and ATTR2:
   545         *  @p(code)
   546         *  ATTR0 -> 0x44 (mark memory region as non-cacheable normal memory)
   547         *  ATTR1 -> 0x00 (mark memory region as strongly ordered and non-cacheable)
   548         *  ATTR2 -> 0xFF (mark memory region as normal memory, RW cacheable and
   549         *  RW allocate)
   550         *  @p
   551         *
   552         *  The level1 and level2 MMU Table entries use the above default
   553         *  attributes created by this module and should preferably not be
   554         *  changed. Please note that if the default value assigned to ATTR0 is
   555         *  changed, then the {@link #cachePlatformMemory} config param may not
   556         *  behave correctly as it uses this attribute to mark the memory as
   557         *  non-cacheable normal memory. If ATTR1 or ATTR2 are changed, it will
   558         *  affect all existing MMU Table entries which use ATTR1 or ATTR2.
   559         *
   560         *  For more details on MAIR0 and MAIR1 encodings please refer
   561         *  {@link http://infocenter.arm.com/help/topic/com.arm.doc.ddi0406c/index.html v7A ARM Architecture Reference Manual}
   562         *
   563         *  @param(attrIndx)     Select appropriate MAIR register (0 or 1)
   564         *                       and byte offset within the selected register
   565         *  @param(attr)         Memory attribute encoding
   566         */
   567        @DirectCall
   568        Void setMAIR(UInt attrIndx, UInt attr);
   569    
   570        /*!
   571         *  ======== setFirstLevelDesc ========
   572         *  Sets the descriptor for the virtual address.
   573         *
   574         *  The first level table entry for the virtual address is mapped
   575         *  to the physical address with the attributes specified. The
   576         *  descriptor table is effective when the MMU is enabled.
   577         *
   578         *  @see ti.sysbios.family.arm.a15.Mmu
   579         *
   580         *  @param(virtualAddr) The modified virtual address
   581         *  @param(phyAddr)     The physical address
   582         *  @param(attrs)       Pointer to first level descriptor attribute struct
   583         */
   584        @DirectCall
   585        Void setFirstLevelDesc(Ptr virtualAddr, UInt64 phyAddr,
   586                               DescriptorAttrs *attrs);
   587    
   588        /*!
   589         *  ======== setSecondLevelDesc ========
   590         *  Sets the descriptor for the virtual address.
   591         *
   592         *  The second level table entry for the virtual address is mapped
   593         *  to the physical address with the attributes specified. The
   594         *  descriptor table is effective when the MMU is enabled.
   595         *
   596         *  @see ti.sysbios.family.arm.a15.Mmu
   597         *
   598         *  @param(virtualAddr) The modified virtual address
   599         *  @param(phyAddr)     The physical address
   600         *  @param(attrs)       Pointer to second level descriptor attribute struct
   601         */
   602        @DirectCall
   603        Void setSecondLevelDesc(Ptr virtualAddr, UInt64 phyAddr,
   604                                DescriptorAttrs *attrs);
   605    
   606    internal:
   607    
   608        /*! static array to hold first level dscriptor table */
   609        metaonly config UInt32 firstLevelTableBuf[];
   610    
   611        /*! static array to hold second level dscriptor table */
   612        metaonly config UInt32 secondLevelTableBuf[NUM_LEVEL1_ENTRIES][];
   613    
   614        /*!
   615         *  Memory Attribute Indirection Register 0 and 1
   616         */
   617        config UInt mairRegAttr[8];
   618    
   619        /*!
   620         *  ======== init ========
   621         *  initialize mmu registers
   622         */
   623        Void init();
   624    
   625        /*!
   626         *  ======== enableAsm ========
   627         *  Assembly function to enable the MMU.
   628         */
   629        Void enableAsm();
   630    
   631        /*!
   632         *  ======== disableAsm ========
   633         *  Assembly function to disable the MMU.
   634         */
   635        Void disableAsm();
   636    
   637        /*!
   638         *  ======== writeMAIRAsm ========
   639         */
   640        Void writeMAIRAsm(UInt attrIndx, UInt attr);
   641    
   642        /*! function generated to initialize first level descriptor table */
   643        Void initFirstLevelTableBuf(UInt64 *firstLevelTableBuf,
   644                                    UInt64 **secondLevelTableBuf);
   645    
   646        /*! function generated to initialize second level descriptor table */
   647        Void initSecondLevelTableBuf(UInt64 **secondLevelTableBuf);
   648    
   649        /*! Module state */
   650        struct Module_State {
   651            /*
   652             *  32 Byte array for first-level descriptors
   653             */
   654            UInt64 firstLevelTableBuf[];
   655    
   656            /*
   657             *  4 KByte array for second-level descriptors
   658             */
   659            UInt64 secondLevelTableBuf[NUM_LEVEL1_ENTRIES][];
   660    
   661            /*
   662             *  Memory Attribute Indirection Register 0 and 1
   663             */
   664            UInt mairRegAttr[8];
   665        }
   666    }