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