1    /*
     2     * Copyright (c) 2015-2019, 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        override config Bool enableCache = true;
   170    
   171        /*!
   172         *  ======== disable ========
   173         *  Disables the 'type' cache(s)
   174         *
   175         *  This function internally disables interrupts to ensure the cache
   176         *  operations performed before disabling the cache are not interrupted.
   177         *  Since cache maintenance operations can take a long time, this
   178         *  function may disable interrupts for a long period of time.
   179         *
   180         *  On certain Cortex-R devices, the FIQ interrupt cannot be disabled
   181         *  by software. Therefore, this function only disables IRQ interrupts
   182         *  on such devices. If this function needs to be called to disable
   183         *  interrupts, then care must be take that the FIQ ISR does not
   184         *  interfere with the cache flush maintenance operations performed
   185         *  by this function before disabling the cache.
   186         */
   187        override Void disable(Bits16 type);
   188    
   189        /*! @_nodoc
   190         *  ======== getEnabled ========
   191         *  Get the 'type' bitmask of cache(s) enabled.
   192         */
   193        Bits16 getEnabled();
   194    
   195        /*!
   196         *  ======== invL1dAll ========
   197         *  Invalidate all of L1 data cache.
   198         *
   199         *  This function should be used with caution.  In general, the
   200         *  L1 data cache may contain some stack variable or valid data
   201         *  that should not be invalidated.  This function should be used
   202         *  only when all contents of L1 data cache is unwanted.
   203         */
   204        Void invL1dAll();
   205    
   206        /*!
   207         *  ======== invL1pAll ========
   208         *  Invalidate all of L1 program cache.
   209         */
   210        Void invL1pAll();
   211    
   212        /*!
   213         *  ======== invBPAll ========
   214         *  Invalidate all branch predictors
   215         */
   216        Void invBPAll();
   217    
   218    internal:
   219    
   220        /*
   221         *  ======== initModuleState ========
   222         *  Initializes the module state.
   223         *
   224         *  This function initializes module state fields like
   225         *  L1D/L1P cache size and number of cache lines/sets. It
   226         *  is registered as a first function.
   227         */
   228        Void initModuleState();
   229    
   230        /*
   231         *  ======== startup ========
   232         *  startup function to enable cache early during climb-up (run as a reset
   233         *  function)
   234         */
   235        Void startup();
   236    
   237        /*!
   238         *  ======== disableL1d ========
   239         *  Disable L1 data cache
   240         *
   241         *  This function performs a write back invalidate all of
   242         *  L1 data cache before it disables the cache.
   243         */
   244        Void disableL1d();
   245    
   246        /*!
   247         *  ======== disableL1p ========
   248         *  Disable L1 Program cache
   249         *
   250         *  This function performs an invalidate all of L1 program cache
   251         *  before it disables the cache.
   252         */
   253        Void disableL1p();
   254    
   255        /*!
   256         *  ======== enableL1d ========
   257         *  Enable L1 data cache.
   258         */
   259        Void enableL1d();
   260    
   261        /*!
   262         *  ======== enableL1p ========
   263         *  Enable L1 program cache.
   264         */
   265        Void enableL1p();
   266    
   267        /*
   268         *  ======== invL1d ========
   269         *  Invalidates range in L1 data cache.
   270         */
   271        Void invL1d(Ptr blockPtr, SizeT byteCnt, Bool wait);
   272    
   273        /*
   274         *  ======== invL1p ========
   275         *  Invalidates range in L1 program cache.
   276         */
   277        Void invL1p(Ptr blockPtr, SizeT byteCnt, Bool wait);
   278    
   279        /*
   280         *  ======== wbInvAllI ========
   281         *  Write back invalidate all caches
   282         */
   283        Void wbInvAllI();
   284    
   285        /*
   286         *  ======== getCacheLevelInfo ========
   287         *  returns Cache Size Id Register of corresponding Cache level
   288         *
   289         *  level values
   290         *      0 = L1D
   291         *      1 = L1P
   292         */
   293        Bits32 getCacheLevelInfo(UInt level);
   294    
   295        struct Module_State {
   296            UInt32  l1dCacheLineSize;   // Size of L1D cache line in bytes
   297            UInt32  l1pCacheLineSize;   // Size of L1P cache line in bytes
   298            Bits32  l1dInfo;
   299            Bits32  l1pInfo;
   300        }
   301    }