1    /*
     2     * Copyright (c) 2012, 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     *  ======== Cache.xdc ========
    34     *
    35     */
    36    
    37    package ti.sysbios.family.arm.a15;
    38    
    39    import xdc.rov.ViewInfo;
    40    
    41    import xdc.runtime.Assert;
    42    
    43    /*!
    44     *  ======== Cache ========
    45     *  ARM Cache Module
    46     *
    47     *  This module manages the data and instruction caches on Cortex A15 
    48     *  processors.
    49     *  It provides a list of functions that perform cache operations.  The
    50     *  functions operate on a per cache line except for the 'All' functions
    51     *  which operate on the entire cache specified.  Any Address that is not
    52     *  aligned to a cache line gets rounded down to the address of
    53     *  the nearest cache line.
    54     *
    55     *  The L1 data and program caches as well as the L2 cache are enabled 
    56     *  by default early during the startup sequence (prior to any 
    57     *  Module_startup()s).  
    58     *  Data caching requires the MMU to be enabled and the cacheable 
    59     *  attribute of the section/page descriptor for a corresponding
    60     *  memory region to be enabled.  
    61     *  Program caching does not require the MMU to be enabled and therefore 
    62     *  occurs when the L1 program cache is enabled.
    63     *
    64     *  Note: See the {@link ti.sysbios.family.arm.a15.Mmu} module for 
    65     *        information about the MMU.
    66     *
    67     *  Unconstrained Functions
    68     *  All functions
    69     *
    70     *  @p(html)
    71     *  <h3> Calling Context </h3>
    72     *  <table border="1" cellpadding="3">
    73     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    74     *    </colgroup>
    75     *
    76     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    77     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    78     *    <!--                               -->
    79     *    <tr><td> {@link #disable}     </td><td>   Y    </td><td>   Y    </td>
    80     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    81     *    <tr><td> {@link #enable}      </td><td>   Y    </td><td>   Y    </td>
    82     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    83     *    <tr><td> {@link #inv}         </td><td>   Y    </td><td>   Y    </td>
    84     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    85     *    <tr><td> {@link #invL1dAll}   </td><td>   Y    </td><td>   Y    </td>
    86     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    87     *    <tr><td> {@link #invL1pAll}   </td><td>   Y    </td><td>   Y    </td>
    88     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    89     *    <tr><td> {@link #wait}        </td><td>   Y    </td><td>   Y    </td>
    90     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    91     *    <tr><td> {@link #wb}          </td><td>   Y    </td><td>   Y    </td>
    92     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    93     *    <tr><td> {@link #wbInv}       </td><td>   Y    </td><td>   Y    </td>
    94     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    95     *    <tr><td> {@link #wbInvL1dAll} </td><td>   Y    </td><td>   Y    </td>
    96     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    97     *    <tr><td> {@link #wbL1dAll}    </td><td>   Y    </td><td>   Y    </td>
    98     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    99     *    <tr><td> {@link #load}       </td><td>   Y    </td><td>   Y     </td>
   100     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   101     *    <tr><td colspan="6"> Definitions: <br />
   102     *       <ul>
   103     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   104     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   105     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   106     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   107     *           <ul>
   108     *             <li> In your module startup after this module is started 
   109     *   (e.g. Cache_Module_startupDone() returns TRUE). </li>
   110     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   111     *             <li> During main().</li>
   112     *             <li> During BIOS.startupFxns.</li>
   113     *           </ul>
   114     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   115     *           <ul>
   116     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   117     *             <li> In your module startup before this module is started 
   118     *   (e.g. Cache_Module_startupDone() returns FALSE).</li>
   119     *           </ul>
   120     *       </ul>
   121     *    </td></tr>
   122     *
   123     *  </table>
   124     *  @p
   125     */
   126    
   127    module Cache inherits ti.sysbios.interfaces.ICache
   128    {
   129        /*!
   130         *  Size of L1 data cache Line in bytes
   131         */
   132        const UInt sizeL1dCacheLine = 64;
   133    
   134        /*!
   135         *  Size of L1 program cache Line in bytes
   136         */
   137        const UInt sizeL1pCacheLine = 64;
   138        
   139        /*!
   140         *  Size of L2 cache Line in bytes
   141         */
   142        const UInt sizeL2CacheLine = 64;
   143    
   144        /*!
   145         *  ======== ModView ========
   146         *  @_nodoc
   147         */
   148        metaonly struct CacheInfoView {
   149            String      cache;
   150            SizeT       cacheSize;
   151            SizeT       lineSize;
   152            UInt        ways;
   153            SizeT       waySize;
   154        };
   155    
   156        /*!
   157         *  ======== rovViewInfo ========
   158         *  @_nodoc
   159         */
   160        @Facet
   161        metaonly config ViewInfo.Instance rovViewInfo = 
   162            ViewInfo.create({
   163                viewMap: [
   164                    ['Cache Info',  { type: ViewInfo.MODULE_DATA,   
   165                                      viewInitFxn: 'viewInitCacheInfo',  
   166                                      structName: 'CacheInfoView'}]
   167                ]
   168            });
   169    
   170        /*! Asserted in Cache_lock */
   171        config Assert.Id A_badBlockLength = {
   172            msg: "A_badBlockLength: Block length too large. Must be <= L2 way size."
   173        };
   174    
   175        /*! Asserted in Cache_lock */
   176        config Assert.Id A_blockCrossesPage = {
   177            msg: "A_blockCrossesPage: Memory block crosses L2 way page boundary."
   178        };
   179    
   180        /*!
   181         *  Enable L1 and L2 data and program caches.
   182         *
   183         *  To enable a subset of the caches, set this parameter
   184         *  to 'false' and call Cache_enable() within main, passing it only 
   185         *  the {@link Cache#Type Cache_Type(s)} to be enabled.
   186         *
   187         *  Data caching requires the MMU and the memory section/page
   188         *  descriptor cacheable attribute to be enabled.
   189         */
   190        config Bool enableCache = true;
   191        
   192        /*!
   193         *  Enable Branch Prediction at startup, default is true.
   194         *
   195         *  This flag controls whether Branch Prediction should be automatically
   196         *  enabled or disabled during system startup.
   197         *
   198         *  @a(NOTE)
   199         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction) 
   200         *  feature is disabled.
   201         */
   202        config Bool branchPredictionEnabled = true;
   203        
   204        /*! @_nodoc
   205         *  ======== getEnabled ========
   206         *  Get the 'type' bitmask of cache(s) enabled.
   207         */
   208        @DirectCall
   209        Bits16 getEnabled();
   210    
   211        /*!
   212         *  ======== invL1dAll ========
   213         *  Invalidate all of L1 data cache.
   214         *
   215         *  This function should be used with caution.  In general, the
   216         *  L1 data cache may contain some stack variable or valid data
   217         *  that should not be invalidated.  This function should be used
   218         *  only when all contents of L1 data cache is unwanted.
   219         */
   220        @DirectCall
   221        Void invL1dAll();
   222    
   223        /*!
   224         *  ======== invL1pAll ========
   225         *  Invalidate all of L1 program cache.
   226         */
   227        @DirectCall
   228        Void invL1pAll();
   229     
   230        /*!
   231         *  ======== preLoad ========
   232         *  Loads a memory block into the L2 cache.
   233         *
   234         *  A block of memory is loaded into the L2 cache.
   235         *
   236         *  The memory block is loaded into cache one L2 cache line at time.
   237         *
   238         *  The byteCnt argument must be less than or equal to an L2 cache
   239         *  size. An assert is generated if this rule is violated.
   240         *
   241         *  Except for the normal L1 instruction cache behavior 
   242         *  during code execution, the L1 instruction cache is
   243         *  unaffected by this API.
   244         *  The L1 data cache will be temporarily polluted by the contents
   245         *  of the referenced memory block.
   246         *
   247         *  @a(NOTE)
   248         *  Interrupts are disabled for the entire time the memory block 
   249         *  is being loaded into cache. For this reason, use of this API 
   250         *  is probably best at system intialization time 
   251         *  (ie: within 'main()').
   252         *
   253         *  @param(blockPtr) start address of range to be loaded
   254         *  @param(byteCnt)  number of bytes to be loaded
   255         */
   256        @DirectCall
   257        Void preLoad(Ptr blockPtr, SizeT byteCnt);
   258     
   259        /*!
   260         *  ======== enableBP ========
   261         *  Enable Branch Prediction
   262         *
   263         *  Calling this API will enable branch prediction.
   264         *
   265         *  @a(NOTE)
   266         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction) 
   267         *  feature is disabled.
   268         */
   269        @DirectCall
   270        Void enableBP();
   271    
   272        /*!
   273         *  ======== disableBP ========
   274         *  Disable Branch Prediction
   275         *
   276         *  Calling this API will disable branch prediction.
   277         *
   278         *  @a(NOTE)
   279         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction) 
   280         *  feature is disabled.
   281         */
   282        @DirectCall
   283        Void disableBP();
   284    
   285        /*!
   286         *  @_nodoc
   287         *  ======== enablePmc ========
   288         *  Enable 3 PMC event counters and map them to L2 cache refill event,
   289         *  L2 cache access event and cycle event.
   290         *
   291         *  For debug purposes only.
   292         */
   293        @DirectCall
   294        Void enablePmc();
   295    
   296        /*!
   297         *  @_nodoc
   298         *  ======== resetPmc ========
   299         *  Stop and reset all PMC event counters being used. Restart the 
   300         *  counters again.
   301         *
   302         *  For debug purposes only.
   303         */
   304        @DirectCall
   305        Void resetPmc();
   306    
   307        /*!
   308         *  @_nodoc
   309         *  ======== getPmcMiss ========
   310         *  Read the PMC event counter register corresponding to L2 cache 
   311         *  refill event.
   312         *
   313         *  For debug purposes only.
   314         */
   315        @DirectCall
   316        UInt getPmcMiss();
   317    
   318        /*!
   319         *  @_nodoc
   320         *  ======== getPmcAxs ========
   321         *  Read the PMC event counter register corresponding to L2 cache 
   322         *  access event.
   323         *
   324         *  For debug purposes only.
   325         */
   326        @DirectCall
   327        UInt getPmcAxs();
   328    
   329        /*!
   330         *  @_nodoc
   331         *  ======== getPmcCycle ========
   332         *  Read the PMC event counter register corresponding to cycle event.
   333         *
   334         *  For debug purposes only.
   335         */
   336        @DirectCall
   337        UInt getPmcCycle();
   338    
   339    internal:
   340    
   341        /*!
   342         *  ======== startup ========
   343         *  startup function to enable cache early during climb-up
   344         */
   345        Void startup();
   346    
   347        /*!
   348         *  ======== disableD ========
   349         *  Disable data cache
   350         *
   351         *  This function disables the L1 data cache before performing
   352         *  a "write back invalidate all" of data and instruction caches.
   353         *
   354         *  The L2 unified cache cannot be disabled on Cortex-A15.
   355         *  Disabling the L1 data cache effectively disables the L2 unified
   356         *  cache for all data caching purposes (on the current core in a
   357         *  Cortex-A15 multi-core system).
   358         */
   359        Void disableD();
   360     
   361        /*!
   362         *  ======== disableP ========
   363         *  Disable instruction cache
   364         *
   365         *  This function disables the L1 instruction cache before 
   366         *  performing a "invalidate all" of the whole instruction
   367         *  cache.
   368         *
   369         *  The L2 unified cache cannot be disabled on Cortex-A15.
   370         *  Disabling the L1 instruction cache effectively disables the
   371         *  L2 unified cache for all instruction caching purposes (on
   372         *  the current core in a Cortex-A15 multi-core system).
   373         */
   374        Void disableP();
   375    
   376        /*!
   377         *  ======== enableD ========
   378         *  Enable data cache.
   379         *
   380         *  This function enables the L1 data cache.
   381         *
   382         *  Enabling the L1 data cache effectively enables the L2 unified
   383         *  cache for all data caching purposes (on the current core in a
   384         *  Cortex-A15 multi-core system).
   385         */
   386        Void enableD();
   387    
   388        /*!
   389         *  ======== enableP ========
   390         *  Enable instruction cache.
   391         *
   392         *  This function enables the L1 instruction cache.
   393         *
   394         *  Enabling the L1 instruction cache effectively enables the
   395         *  L2 unified cache for all instruction caching purposes (on
   396         *  the current core in a Cortex-A15 multi-core system).
   397         *
   398         *  If the MMU is disabled and the L1 instruction cache is enabled,
   399         *  no new instructions will be cached in the L2 unified cache.
   400         *  However, code already cached in the L2 cache will be fetched.
   401         */
   402        Void enableP();
   403    
   404        /*!
   405         *  ======== invL1d ========
   406         *  Invalidates range in L1 data cache.
   407         */
   408        Void invL1d(Ptr blockPtr, SizeT byteCnt, Bool wait);
   409    
   410        /*!
   411         *  ======== invL1p ========
   412         *  Invalidates range in L1 program cache.
   413         */
   414        Void invL1p(Ptr blockPtr, SizeT byteCnt, Bool wait);
   415    
   416        /*!
   417         *  ======== preFetch ========
   418         *  load a block of memory into the L2 cache.
   419         */
   420        Void preFetch(Ptr blockPtr, SizeT byteCnt);
   421    
   422        /*!
   423         *  ======== getCacheLevelInfo ========
   424         *  returns Cache Size Id Register of corresponding Cache level
   425         *
   426         *  level values
   427         *      0 = L1D
   428         *      1 = L1P
   429         *      2 = L2
   430         */
   431        Bits32 getCacheLevelInfo(UInt level);
   432    
   433        Void exit(Int status);
   434    
   435        struct Module_State {
   436            Bits32  l1dInfo;
   437            Bits32  l1pInfo;
   438            Bits32  l2Info;
   439            SizeT   l2WaySize;
   440        }
   441    }