1    /*
     2     * Copyright (c) 2014, 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.shared.vayu;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    import xdc.runtime.Assert;
    41    
    42    /*!
    43     *  ======== Mmu ========
    44     *  DSP Memory Management Unit (MMU0) Manager.
    45     *
    46     *  This module allows the processor to map a virtual address to a
    47     *  different physical address and enable/disable the MMU.  It does this
    48     *  through a translation table in memory.  The translation table is
    49     *  16KB and manages only the first level descriptor table.  Each entry
    50     *  in the table defines the memory translation of a page of size 1MB
    51     *  (or 16MB if using supersections).
    52     *
    53     *  By default, the MMU translation table is initialized with
    54     *  entries for every memory segment defined in the platform.
    55     *  Entries are also added for the peripheral addresses used by
    56     *  SYS/BIOS (i.e. Timers, Interrupt controller).
    57     *
    58     *  The translation table is placed in
    59     *  an output section called "ti.sysbios.family.shared.vayu.mmuTableSection".
    60     *  This section is placed into the platform's default dataMemory and
    61     *  in order to minimize object file size, specified to not be initialized
    62     *  via the "NOLOAD" type on GNU compilers and "NOINIT" on TI compilers.
    63     *
    64     *  This module does not manage the second level descriptor tables.
    65     *  A 'SECTION' mapped access requires only a first level fetch.  In
    66     *  this case, there is no need for a second level descriptor table.
    67     *  A 'PAGE_TABLE' mapped access requires a second level
    68     *  descriptor table which can be supplied by the user.
    69     *
    70     *  The following is an example of how to place the MMU table
    71     *  for the address range 0x80000000-0x90000000 in the *.cfg file:
    72     *
    73     *  @p(code)
    74     *
    75     *    var Mmu = xdc.useModule('ti.sysbios.family.shared.vayu.Mmu');
    76     *
    77     *    // Enable the MMU
    78     *    Mmu.enableMMU = true;
    79     *
    80     *    // descriptor attribute structure
    81     *    var attrs = {
    82     *        type: Mmu.FirstLevelDesc_SECTION,  // SECTION descriptor
    83     *        supersection: false
    84     *    };
    85     *
    86     *    // Set the descriptor for each entry in the address range
    87     *    for (var i=0x80000000; i < 0x90000000; i = i + 0x00100000) {
    88     *        // Each 'SECTION' descriptor entry spans a 1MB address range
    89     *        Mmu.setFirstLevelDescMeta(i, i, attrs);
    90     *    }
    91     *
    92     *    var memmap = Program.cpu.memoryMap;
    93     *    var DDR = null;
    94     *
    95     *    // Find DDR in memory map
    96     *    for (var i=0; i < memmap.length; i++) {
    97     *        if (memmap[i].name == "DDR") {
    98     *            DDR = memmap[i];
    99     *        }
   100     *    }
   101     *
   102     *    // Place the MMU table in the DDR memory segment if it exists
   103     *    if (DDR != null) {
   104     *        var sectionName = "ti.sysbios.family.shared.vayu.mmuTableSection";
   105     *        Program.sectMap[sectionName] = new Program.SectionSpec();
   106     *        Program.sectMap[sectionName].type = "NOINIT"; // NOLOAD for GNU Tools
   107     *        Program.sectMap[sectionName].loadSegment = "DDR";
   108     *    }
   109     *    else {
   110     *        print("No DDR memory segment was found");
   111     *    }
   112     *
   113     *  @p
   114     *
   115     *  The following is an example of how to add TLB entries and lock them:
   116     *
   117     *  @p(code)
   118     *  #include <ti/sysbios/family/shared/vayu/Mmu.h>
   119     *
   120     *  Int main()
   121     *  {
   122     *      Int i, j;
   123     *      Bool ret;
   124     *
   125     *      // Add and lock 16 TLB entries. Once the entries are locked, they
   126     *      // cannot be evicted by the table walking logic when the MMU is enabled.
   127     *      for (i = 0x90000000, j = 0; j < 16; i+= 0x1000, j++) {
   128     *          ret = Mmu_writeTLBEntry((Ptr)i, (Ptr)i, Mmu_PageSize_SMALL);
   129     *          if (!ret) {
   130     *              // FAILED: Could not lock TLB entry. TLB is full with locked
   131     *              // entries.
   132     *              ...
   133     *          }
   134     *      }
   135     *      ...
   136     *      BIOS_start();
   137     *  }
   138     *  @p
   139     *
   140     *  The following is an example of how to unlock and clear TLB entries:
   141     *
   142     *  @p(code)
   143     *  #include <ti/sysbios/family/shared/vayu/Mmu.h>
   144     *
   145     *  Int func()
   146     *  {
   147     *      Int i, j;
   148     *
   149     *      // Unlock all TLB entries by setting locked entries base value to 0
   150     *      Mmu_setTLBLockBaseValue(0);
   151     *
   152     *      // Clear (or flush) TLB entries pointed to by given virtual address.
   153     *      for (i = 0x90000000, j = 0; j < 16; i+= 0x1000, j++) {
   154     *          Mmu_clearTLBEntry((Ptr)i);
   155     *      }
   156     *      ...
   157     *  }
   158     *  @p
   159     *
   160     *  The following example shows how to add a second level descriptor table:
   161     *
   162     *  @p(code)
   163     *  #include <ti/sysbios/BIOS.h>
   164     *  #include <ti/sysbios/family/shared/vayu/Mmu.h>
   165     *
   166     *  #define MMU_LEVEL2DESC_LARGEPAGE    0x1
   167     *  #define MMU_LEVEL2DESC_SMALLPAGE    0x2
   168     *
   169     *  #pragma DATA_ALIGN(mmuL2Table, 4096);    // align to 4KB
   170     *
   171     *  UInt32 mmuL2Table[256];
   172     *
   173     *  Void main(Int argc, Char * argv[])
   174     *  {
   175     *      Mmu_FirstLevelDescAttrs attrs;
   176     *      Int i, j;
   177     *
   178     *      // initialize the second level descriptors
   179     *      for (i = 0x80000000, j = 0; j < 256; i+= 0x1000, j++) {
   180     *          mmuL2Table[j] = (i & 0xFFFFF000) | MMU_LEVEL2DESC_SMALLPAGE;
   181     *
   182     *          // For large pages use below line instead:
   183     *          // mmuL2Table[j] = (i & 0xFFFF0000) | MMU_LEVEL2DESC_LARGEPAGE;
   184     *      }
   185     *
   186     *      // first level descriptor properites
   187     *      Mmu_initDescAttrs(&attrs);
   188     *      attrs.type = Mmu_FirstLevelDesc_PAGE_TABLE; // set to a page table descriptor
   189     *
   190     *      // Set the first level descriptor for the virtual address 0x80000000.
   191     *      // No need to disable the MMU. The API should internally disable and
   192     *      // re-enable it.
   193     *      Mmu_setFirstLevelDesc((Ptr)0x80000000, &mmuL2Table, &attrs);
   194     *
   195     *      BIOS_start();
   196     *  }
   197     *
   198     *  ...
   199     *  @p
   200     *
   201     *  Notes:
   202     *  @p(blist)
   203     *      -There are size and alignment requirements on the second
   204     *       level descriptor tables depending on the page size.
   205     *      -See the SoC Reference Manual for more info.
   206     *  @p
   207     *
   208     *  @p(html)
   209     *  <h3> Calling Context </h3>
   210     *  <table border="1" cellpadding="3">
   211     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
   212     *    </colgroup>
   213     *
   214     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
   215     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
   216     *    <!--                               -->
   217     *    <tr><td> {@link #clearTLBEntry}</td><td>   N    </td><td>   Y    </td>
   218     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   219     *    <tr><td> {@link #disable}    </td><td>   N    </td><td>   Y    </td>
   220     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   221     *    <tr><td> {@link #enable}     </td><td>   N    </td><td>   Y    </td>
   222     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   223     *    <tr><td> {@link #initDescAttrs}   </td><td>   Y    </td><td>   Y    </td>
   224     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   225     *    <tr><td> {@link #isEnabled}   </td><td>   Y    </td><td>   Y    </td>
   226     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   227     *    <tr><td> {@link #setFirstLevelDesc}</td><td>   N    </td><td>   Y    </td>
   228     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   229     *    <tr><td> {@link #setTLBLockBaseValue}</td><td>   N    </td><td>   Y  </td>
   230     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   231     *    <tr><td> {@link #writeTLBEntry}</td><td>   N    </td><td>   Y    </td>
   232     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   233     *    <tr><td colspan="6"> Definitions: <br />
   234     *       <ul>
   235     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   236     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   237     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   238     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   239     *           <ul>
   240     *             <li> In your module startup after this module is started
   241     *   (e.g. Cache_Module_startupDone() returns TRUE). </li>
   242     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   243     *             <li> During main().</li>
   244     *             <li> During BIOS.startupFxns.</li>
   245     *           </ul>
   246     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   247     *           <ul>
   248     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   249     *             <li> In your module startup before this module is started
   250     *   (e.g. Cache_Module_startupDone() returns FALSE).</li>
   251     *           </ul>
   252     *       </ul>
   253     *    </td></tr>
   254     *
   255     *  </table>
   256     *  @p
   257     */
   258    
   259    @Template ("./Mmu.xdt") /* generate function to init MMU page table */
   260    @ModuleStartup          /* call to initTableBuf() in startup */
   261    @DirectCall
   262    
   263    module Mmu
   264    {
   265        // -------- ROV views --------
   266    
   267        /*! @_nodoc */
   268        metaonly struct PageView {
   269            String      Type;
   270            Ptr         AddrVirtual;
   271            Ptr         AddrPhysical;
   272            Ptr         Level2TablePtr;
   273            Bool        SuperSection;
   274        };
   275    
   276        @Facet
   277        metaonly config ViewInfo.Instance rovViewInfo =
   278            ViewInfo.create({
   279                viewMap: [
   280                    ['0x0-0x7FFFFFFF', {
   281                        type: ViewInfo.MODULE_DATA,
   282                        viewInitFxn: 'viewPages1',
   283                        structName: 'PageView'
   284                    }],
   285                    ['0x80000000-0x9FFFFFFF', {
   286                        type: ViewInfo.MODULE_DATA,
   287                        viewInitFxn: 'viewPages2',
   288                        structName: 'PageView'
   289                    }],
   290                    ['0xA0000000-0xBFFFFFFF', {
   291                        type: ViewInfo.MODULE_DATA,
   292                        viewInitFxn: 'viewPages3',
   293                        structName: 'PageView'
   294                    }],
   295                    ['0xC0000000-0xDFFFFFFF', {
   296                        type: ViewInfo.MODULE_DATA,
   297                        viewInitFxn: 'viewPages4',
   298                        structName: 'PageView'
   299                    }],
   300                    ['0xE0000000-0xFFFFFFFF', {
   301                        type: ViewInfo.MODULE_DATA,
   302                        viewInitFxn: 'viewPages5',
   303                        structName: 'PageView'
   304                    }]
   305               ]
   306           });
   307    
   308        /*!
   309         *  First Level descriptors
   310         *
   311         *  Different descriptor type encodings:
   312         *  0b00    ->  Invalid or Fault entry
   313         *  0b01    ->  Page table entry
   314         *  0b10    ->  Section descriptor
   315         */
   316        enum FirstLevelDesc {
   317            FirstLevelDesc_FAULT = 0,      /*! Virtual address is unmapped     */
   318            FirstLevelDesc_PAGE_TABLE = 1, /*! Page table addr descriptor      */
   319            FirstLevelDesc_SECTION = 2     /*! Section descriptor              */
   320        };
   321    
   322        /*!
   323         *  Page size
   324         */
   325        enum PageSize {
   326            PageSize_SECTION = 0,          /*! Section (1 MB) */
   327            PageSize_LARGE = 1,            /*! Large page (64 KB) */
   328            PageSize_SMALL = 2,            /*! Small page (4 KB) */
   329            PageSize_SUPERSECTION = 3      /*! Supersection (16 MB) */
   330        };
   331    
   332        /*!
   333         *  Structure for setting first level descriptor entries
   334         *
   335         *  See the 'Memory Management Units' section of the device TRM for
   336         *  more details.
   337         */
   338        struct FirstLevelDescAttrs {
   339            FirstLevelDesc type;    /*! first level descriptor type             */
   340            Bool supersection;      /*! is a supersection                       */
   341        };
   342    
   343        // Asserts
   344    
   345        /*!
   346         *  ======== A_nullPointer ========
   347         *  Assert raised when a pointer is null
   348         */
   349        config Assert.Id A_nullPointer  = {
   350            msg: "A_nullPointer: Pointer is null"
   351        };
   352    
   353        /*!
   354         *  ======== A_unknownDescType ========
   355         *  Assert raised when the descriptor type is not recognized.
   356         */
   357        config Assert.Id A_unknownDescType = {
   358            msg: "A_unknownDescType: Descriptor type is not recognized"
   359        };
   360    
   361        /*!
   362         *  ======== A_baseValueOutOfRange ========
   363         *  Assert raised when TLB lock entries base value out of range
   364         */
   365        config Assert.Id A_baseValueOutOfRange  = {
   366            msg: "A_baseValueOutOfRange: TLB lock entries base value out of range"
   367        };
   368    
   369        /*! default descriptor attributes structure */
   370        config FirstLevelDescAttrs defaultAttrs = {
   371            type: FirstLevelDesc_SECTION,   /* SECTION descriptor */
   372            supersection: false,            /* false by default   */
   373        };
   374    
   375        /*!
   376         *  ======== enableMMU ========
   377         *  Configuration parameter to enable MMU.
   378         */
   379        config Bool enableMMU = false;
   380    
   381        /*!
   382         *  ======== baseAddr ========
   383         *  MMU base address.
   384         *
   385         *  If not specified, will be automatically set at runtime.
   386         */
   387        config Regs *baseAddr = null;
   388    
   389        /*!
   390         *  @_nodoc
   391         *  MMU Registers.
   392         */
   393        struct Regs {
   394            UInt32 REVISION;            /*! 0x000 */
   395            UInt32 hole1[3];            /*! 0x004-0x00C */
   396            UInt32 SYSCONFIG;           /*! 0x010 */
   397            UInt32 SYSSTATUS;           /*! 0x014 */
   398            UInt32 IRQSTATUS;           /*! 0x018 */
   399            UInt32 IRQENABLE;           /*! 0x01C */
   400            UInt32 hole2[8];            /*! 0x020-0x03C */
   401            UInt32 WALKING_ST;          /*! 0x040 */
   402            UInt32 CNTL;                /*! 0x044 */
   403            UInt32 FAULT_AD;            /*! 0x048 */
   404            UInt32 TTB;                 /*! 0x04C */
   405            UInt32 LOCK;                /*! 0x050 */
   406            UInt32 LD_TLB;              /*! 0x054 */
   407            UInt32 CAM;                 /*! 0x058 */
   408            UInt32 RAM;                 /*! 0x05C */
   409            UInt32 GFLUSH;              /*! 0x060 */
   410            UInt32 FLUSH_ENTRY;         /*! 0x064 */
   411            UInt32 READ_CAM;            /*! 0x068 */
   412            UInt32 READ_RAM;            /*! 0x06C */
   413            UInt32 EMU_FAULT_AD;        /*! 0x070 */
   414            UInt32 hole3[3];            /*! 0x074-0x07C */
   415            UInt32 FAULT_PC;            /*! 0x080 */
   416            UInt32 FAULT_STATUS;        /*! 0x084 */
   417            UInt32 GPR;                 /*! 0x088 */
   418            UInt32 BYPASS_REGION1_ADDR; /*! 0x090 */
   419            UInt32 BYPASS_REGION1_SIZE; /*! 0x094 */
   420            UInt32 BYPASS_REGION2_ADDR; /*! 0x098 */
   421            UInt32 BYPASS_REGION2_SIZE; /*! 0x09C */
   422            UInt32 BYPASS_REGION3_ADDR; /*! 0x0A0 */
   423            UInt32 BYPASS_REGION3_SIZE; /*! 0x0A4 */
   424            UInt32 BYPASS_REGION4_ADDR; /*! 0x0A8 */
   425            UInt32 BYPASS_REGION4_SIZE; /*! 0x0AC */
   426        };
   427    
   428        /*!
   429         *  ======== numTLBEntries ========
   430         *  Number of TLB Cache entries.
   431         */
   432        config UInt numTLBEntries = 32;
   433    
   434        /*!
   435         *  ======== setFirstLevelDescMeta ========
   436         *  Statically sets the descriptor for the virtual address.
   437         *
   438         *  The first level table entry for the virtual address is mapped
   439         *  to the physical address or points to the level 2 descriptor
   440         *  table. The descriptor table is effective when the MMU is enabled.
   441         *
   442         *  @param(virtualAddr)  The modified virtual address
   443         *  @param(phyAddr)      The physical address
   444         *  @param(attrs)        Pointer to first level descriptor attribute struct
   445         */
   446        metaonly Void setFirstLevelDescMeta(Ptr virtualAddr, Ptr phyAddr,
   447                                            FirstLevelDescAttrs attrs);
   448    
   449        /*!
   450         *  ======== disable ========
   451         *  Disables the mmu.
   452         *
   453         *  If the MMU is already disabled, then simply return.
   454         *  Otherwise this function does the following:
   455         *  If the L1 data cache is enabled, write back invalidate all
   456         *  of L1 data cache.  If the L1 program cache is enabled,
   457         *  invalidate all of L1 program cache. This function does not
   458         *  change the cache L1 data/program settings. If the L2 unified
   459         *  cache is enabled, it is written back and invalidated.
   460         *  This function also disables the table walking logic and
   461         *  performs a global TLB flush. The global TLB flush does not
   462         *  affect protected TLB entries.
   463         *
   464         *  @a(Note)
   465         *  The MMU hardware does not permit disabling the MMU
   466         *  while an interrupt is pending. If this API is called with
   467         *  an interrupt still pending, the MMU will generate an error.
   468         */
   469        Void disable();
   470    
   471        /*!
   472         *  ======== enable ========
   473         *  Enables the MMU.
   474         *
   475         *  If the MMU is already enabled, then simply return.
   476         *  Otherwise this function does the following:
   477         *  If the L1 program cache is enabled, invalidate all of L1
   478         *  program cache.  This function does not change the L1
   479         *  data/program cache settings. If the L2 unified cache is
   480         *  enabled, it is written back and invalidated.
   481         *  This function also explicitly enables the table walking
   482         *  logic and performs a global TLB flush. The global TLB
   483         *  flush does not affect protected TLB entries.
   484         */
   485        Void enable();
   486    
   487        /*!
   488         *  ======== initDescAttrs() ========
   489         *  Initializes the first level descriptor attribute structure
   490         *
   491         *  @param(attrs)      Pointer to first level descriptor attribute struct
   492         */
   493        Void initDescAttrs(FirstLevelDescAttrs *attrs);
   494    
   495        /*!
   496         *  ======== isEnabled ========
   497         *  Determines if the MMU is enabled
   498         */
   499        Bool isEnabled();
   500    
   501        /*!
   502         *  ======== setFirstLevelDesc ========
   503         *  Sets the descriptor for the virtual address.
   504         *
   505         *  The first level table entry for the virtual address is mapped
   506         *  to the physical address with the attributes specified. The
   507         *  descriptor table is effective when the MMU is enabled.
   508         *
   509         *  @a(Note)
   510         *  This API internally disables and re-enables the MMU.
   511         *  Since the MMU hardware does not permit disabling the MMU
   512         *  while an interrupt is pending, this API should not be called
   513         *  with any interrupts still pending. It is recommended to
   514         *  call this function from within main() before calling
   515         *  BIOS_start().
   516         *
   517         *  @param(virtualAddr)  The modified virtual address
   518         *  @param(phyAddr)      The physical address
   519         *  @param(attrs)        Pointer to first level descriptor attribute struct
   520         */
   521        Void setFirstLevelDesc(Ptr virtualAddr, Ptr phyAddr,
   522                               FirstLevelDescAttrs *attrs);
   523    
   524        /*!
   525         *  ======== writeTLBEntry ========
   526         *  Manually adds a TLB entry and locks it
   527         *
   528         *  This function ready the TLB lock base value and uses it to
   529         *  select a victim TLB entry to write to. Once the new TLB
   530         *  entry is written, it increments the TLB lock base value to
   531         *  lock the entry. The TLB entries added using this function
   532         *  are marked as protected and therefore are not affected by
   533         *  global TLB flush operations.
   534         *
   535         *  @a(Note)
   536         *  Due to the mechanism used to lock TLB entries, it is
   537         *  not possible to unlock a random locked TLB entry. All TLB
   538         *  entries in front need to be unlocked first. For example,
   539         *  if the first 4 TLB entries (i.e. TLB index 0, 1, 2 & 3) are
   540         *  locked and the second TLB entry (i.e. TLB index 1) needs to
   541         *  be unlocked, then the TLB entries with indices 1, 2 & 3
   542         *  have to all be unlocked in order to unlock TLB entry
   543         *  with index 1. This can be done by calling
   544         *  {@link #setTLBLockBaseValue}() function.
   545         *
   546         *  @a(Note)
   547         *  This API internally disables and re-enables the MMU.
   548         *  Since the MMU hardware does not permit disabling the MMU
   549         *  while an interrupt is pending, this API should not be called
   550         *  with any interrupts still pending. It is recommended to
   551         *  call this function from within main() before calling
   552         *  BIOS_start().
   553         *
   554         *  @param(virtualAddr)  The modified virtual address
   555         *  @param(phyAddr)      The physical address
   556         *  @param(size)         TLB page size.
   557         *  @b(returns)          TRUE - Entry succesfully written and locked, OR,
   558         *                       FALSE - Write failed. No free TLB entries.
   559         */
   560        Bool writeTLBEntry(Ptr virtualAddr, Ptr physicalAddr, PageSize size);
   561    
   562        /*!
   563         *  ======== clearTLBEntry ========
   564         *  Clears (or flushes) a TLB entry
   565         *
   566         *  This function flushes all TLB entries (including protected
   567         *  entries) pointed to by the given virtual address. It can be
   568         *  used to delete a TLB entry after it has been unlocked.
   569         *
   570         *  @a(Note)
   571         *  This API internally disables and re-enables the MMU.
   572         *  Since the MMU hardware does not permit disabling the MMU
   573         *  while an interrupt is pending, this API should not be called
   574         *  with any interrupts still pending.
   575         *
   576         *  @param(virtualAddr)  The modified virtual Address
   577         */
   578        Void clearTLBEntry(Ptr virtualAddr);
   579    
   580        /*!
   581         *  ======== setTLBLockBaseValue ========
   582         *  Sets the TLB locked entries base value to the given value.
   583         *
   584         *  First n TLB entries (with n < total number of TLB entries) can be
   585         *  protected from being overwritten with new translations. n is equal
   586         *  to the TLB locked entries base value.
   587         *
   588         *  This function can be used to unlock TLB entries. Once an
   589         *  entry is unlocked, it can be cleared using {@link #clearTLBEntry}()
   590         *  function.
   591         *
   592         *  @a(Note)
   593         *  This API internally disables and re-enables the MMU.
   594         *  Since the MMU hardware does not permit disabling the MMU
   595         *  while an interrupt is pending, this API should not be called
   596         *  with any interrupts still pending.
   597         *
   598         *  @param(basevalue)    TLB locked entries base value
   599         */
   600        Void setTLBLockBaseValue(UInt basevalue);
   601    
   602    internal:
   603    
   604        /*! static array to hold first level dscriptor table */
   605        metaonly config UInt32 tableBuf[];
   606    
   607        /*!
   608         *  ======== init ========
   609         *  initialize mmu registers
   610         */
   611        Void init();
   612    
   613        /*! function generated to initialize first level descriptor table */
   614        Void initTableBuf(UInt32 *mmuTableBuf);
   615    
   616        /*! Module state */
   617        struct Module_State {
   618            volatile Regs *regs;
   619            UInt32        tableBuf[];  /*! 16KB array for first-level descriptors */
   620        }
   621    }