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.v7r;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    import xdc.runtime.Assert;
    41    
    42    /*!
    43     *  ======== Cache ========
    44     *  ARMv7-R Cache Module
    45     *
    46     *  This module manages the data and instruction caches on Cortex-R5
    47     *  processors. It provides a list of functions that perform cache operations.
    48     *  The functions operate on a per cache line except for the 'All' functions
    49     *  which operate on the entire cache specified.  Any Address that is not
    50     *  aligned to a cache line gets rounded down to the address of the nearest
    51     *  cache line.
    52     *
    53     *  The L1 data and program caches are enabled by default early during the
    54     *  startup sequence (prior to any Module_startup()s).
    55     *  Data caching requires the MPU to be enabled and attributes for the
    56     *  memory region to be set as cacheable.
    57     *  Program caching does not require the MPU to be enabled and therefore
    58     *  occurs when the L1 program cache is enabled.
    59     *
    60     *  (See the {@link ti.sysbios.family.arm.Mpu} module for information
    61     *   about the MPU.)
    62     *
    63     *  Unconstrained Functions
    64     *  All functions
    65     *
    66     *  @p(html)
    67     *  <h3> Calling Context </h3>
    68     *  <table border="1" cellpadding="3">
    69     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    70     *    </colgroup>
    71     *
    72     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    73     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    74     *    <!--                               -->
    75     *    <tr><td> {@link #disable}     </td><td>   Y    </td><td>   Y    </td>
    76     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    77     *    <tr><td> {@link #enable}      </td><td>   Y    </td><td>   Y    </td>
    78     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    79     *    <tr><td> {@link #inv}         </td><td>   Y    </td><td>   Y    </td>
    80     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    81     *    <tr><td> {@link #invL1dAll}   </td><td>   Y    </td><td>   Y    </td>
    82     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    83     *    <tr><td> {@link #invL1pAll}   </td><td>   Y    </td><td>   Y    </td>
    84     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    85     *    <tr><td> {@link #wait}        </td><td>   Y    </td><td>   Y    </td>
    86     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    87     *    <tr><td> {@link #wb}          </td><td>   Y    </td><td>   Y    </td>
    88     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    89     *    <tr><td> {@link #wbAll}      </td><td>   Y    </td><td>   Y    </td>
    90     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    91     *    <tr><td> {@link #wbInv}       </td><td>   Y    </td><td>   Y    </td>
    92     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    93     *    <tr><td> {@link #wbInvAll}   </td><td>   Y    </td><td>   Y    </td>
    94     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    95     *    <tr><td colspan="6"> Definitions: <br />
    96     *       <ul>
    97     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
    98     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
    99     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   100     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   101     *           <ul>
   102     *             <li> In your module startup after this module is started
   103     *   (e.g. Cache_Module_startupDone() returns TRUE). </li>
   104     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   105     *             <li> During main().</li>
   106     *             <li> During BIOS.startupFxns.</li>
   107     *           </ul>
   108     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   109     *           <ul>
   110     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   111     *             <li> In your module startup before this module is started
   112     *   (e.g. Cache_Module_startupDone() returns FALSE).</li>
   113     *           </ul>
   114     *       </ul>
   115     *    </td></tr>
   116     *
   117     *  </table>
   118     *  @p
   119     */
   120    
   121    module Cache inherits ti.sysbios.interfaces.ICache
   122    {
   123        /*!
   124         *  ======== ModView ========
   125         *  @_nodoc
   126         */
   127        metaonly struct CacheInfoView {
   128            String      cache;
   129            SizeT       cacheSize;
   130            SizeT       lineSize;
   131            UInt        ways;
   132            SizeT       waySize;
   133        };
   134    
   135        /*!
   136         *  ======== rovViewInfo ========
   137         *  @_nodoc
   138         */
   139        @Facet
   140        metaonly config ViewInfo.Instance rovViewInfo =
   141            ViewInfo.create({
   142                viewMap: [
   143                    ['Cache Info',  { type: ViewInfo.MODULE_DATA,
   144                                      viewInitFxn: 'viewInitCacheInfo',
   145                                      structName: 'CacheInfoView'}]
   146                ]
   147            });
   148    
   149        /*! Asserted in Cache_lock */
   150        config Assert.Id A_badBlockLength = {
   151            msg: "A_badBlockLength: Block length too large. Must be <= L2 way size."
   152        };
   153    
   154        /*! Asserted in Cache_lock */
   155        config Assert.Id A_blockCrossesPage = {
   156            msg: "A_blockCrossesPage: Memory block crosses L2 way page boundary."
   157        };
   158    
   159        /*!
   160         *  Enable L1 data and program caches.
   161         *
   162         *  To enable a subset of the caches, set this parameter
   163         *  to 'false' and call Cache_enable() within main, passing it only
   164         *  the {@link Cache#Type Cache_Type(s)} to be enabled.
   165         *
   166         *  Data caching requires the MMU and the memory section/page
   167         *  descriptor cacheable attribute to be enabled.
   168         */
   169        config Bool enableCache = true;
   170    
   171        /*!
   172         *  Enable Branch Prediction at startup, default is true.
   173         *
   174         *  This flag controls whether Branch Prediction should be automatically
   175         *  enabled or disabled during system startup.
   176         *
   177         *  @a(NOTE)
   178         *  Upon reset, Cortex-R core's Program Flow Prediction (Branch Prediction)
   179         *  feature is disabled.
   180         */
   181        config Bool branchPredictionEnabled = true;
   182    
   183        /*!
   184         *  ======== disable ========
   185         *  Disables the 'type' cache(s)
   186         *
   187         *  This function internally disables interrupts to ensure the cache
   188         *  operations performed before disabling the cache are not interrupted.
   189         *  Since cache maintenance operations can take a long time, this
   190         *  function may disable interrupts for a long period of time.
   191         *
   192         *  On certain Cortex-R devices, the FIQ interrupt cannot be disabled
   193         *  by software. Therefore, this function only disables IRQ interrupts
   194         *  on such devices. If this function needs to be called to disable
   195         *  interrupts, then care must be take that the FIQ ISR does not
   196         *  interfere with the cache flush maintenance operations performed
   197         *  by this function before disabling the cache.
   198         */
   199        override Void disable(Bits16 type);
   200    
   201        /*! @_nodoc
   202         *  ======== getEnabled ========
   203         *  Get the 'type' bitmask of cache(s) enabled.
   204         */
   205        Bits16 getEnabled();
   206    
   207        /*!
   208         *  ======== invL1dAll ========
   209         *  Invalidate all of L1 data cache.
   210         *
   211         *  This function should be used with caution.  In general, the
   212         *  L1 data cache may contain some stack variable or valid data
   213         *  that should not be invalidated.  This function should be used
   214         *  only when all contents of L1 data cache is unwanted.
   215         */
   216        Void invL1dAll();
   217    
   218        /*!
   219         *  ======== invL1pAll ========
   220         *  Invalidate all of L1 program cache.
   221         */
   222        Void invL1pAll();
   223    
   224        /*!
   225         *  ======== enableBP ========
   226         *  Enable Branch Prediction
   227         *
   228         *  Calling this API will enable branch prediction.
   229         *
   230         *  @a(NOTE)
   231         *  Upon reset, the R5's Program Flow Prediction (Branch Prediction)
   232         *  feature is disabled.
   233         */
   234        Void enableBP();
   235    
   236        /*!
   237         *  ======== disableBP ========
   238         *  Disable Branch Prediction
   239         *
   240         *  Calling this API will disable branch prediction.
   241         *
   242         *  @a(NOTE)
   243         *  Upon reset, the R5's Program Flow Prediction (Branch Prediction)
   244         *  feature is disabled.
   245         */
   246        Void disableBP();
   247    
   248        /*!
   249         *  ======== invBPAll ========
   250         *  Invalidate all branch predictors
   251         *
   252         *  Invalidates all branch predictors on this core. If running in SMP mode,
   253         *  this operation is broadcast to all other cores.
   254         */
   255        Void invBPAll();
   256    
   257    internal:
   258    
   259        /*
   260         *  ======== initModuleState ========
   261         *  Initializes the module state.
   262         *
   263         *  This function initializes module state fields like
   264         *  L1D/L1P cache size and number of cache lines/sets. It
   265         *  is registered as a first function.
   266         */
   267        Void initModuleState();
   268    
   269        /*
   270         *  ======== startup ========
   271         *  startup function to enable cache early during climb-up (run as a reset
   272         *  function)
   273         */
   274        Void startup();
   275    
   276        /*!
   277         *  ======== disableL1d ========
   278         *  Disable L1 data cache
   279         *
   280         *  This function performs a write back invalidate all of
   281         *  L1 data cache before it disables the cache.
   282         */
   283        Void disableL1d();
   284    
   285        /*!
   286         *  ======== disableL1p ========
   287         *  Disable L1 Program cache
   288         *
   289         *  This function performs an invalidate all of L1 program cache
   290         *  before it disables the cache.
   291         */
   292        Void disableL1p();
   293    
   294        /*!
   295         *  ======== enableL1d ========
   296         *  Enable L1 data cache.
   297         */
   298        Void enableL1d();
   299    
   300        /*!
   301         *  ======== enableL1p ========
   302         *  Enable L1 program cache.
   303         */
   304        Void enableL1p();
   305    
   306        /*
   307         *  ======== invL1d ========
   308         *  Invalidates range in L1 data cache.
   309         */
   310        Void invL1d(Ptr blockPtr, SizeT byteCnt, Bool wait);
   311    
   312        /*
   313         *  ======== invL1p ========
   314         *  Invalidates range in L1 program cache.
   315         */
   316        Void invL1p(Ptr blockPtr, SizeT byteCnt, Bool wait);
   317    
   318        /*
   319         *  ======== wbInvAllI ========
   320         *  Write back invalidate all caches
   321         */
   322        Void wbInvAllI();
   323    
   324        /*
   325         *  ======== getCacheLevelInfo ========
   326         *  returns Cache Size Id Register of corresponding Cache level
   327         *
   328         *  level values
   329         *      0 = L1D
   330         *      1 = L1P
   331         */
   332        Bits32 getCacheLevelInfo(UInt level);
   333    
   334        struct Module_State {
   335            UInt8   l1dCacheLineSize;   // Size of L1D cache line in bytes
   336            UInt8   l1pCacheLineSize;   // Size of L1P cache line in bytes
   337            Bits32  l1dInfo;
   338            Bits32  l1pInfo;
   339        }
   340    }