1    /*
     2     * Copyright (c) 2017-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.v8a;
    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 ARMv8A
    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.v8a.Mmu} module for information
    64     *   about the MMU.)
    65     *
    66     *  Note: The invalidate instruction is treated by A53/A57/A72 as a
    67     *  clean/invalidate instruction. Therefore, calls to Cache_inv()
    68     *  will behave like Cache_wbInv().
    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 #invL1pAll}   </td><td>   Y    </td><td>   Y    </td>
    89     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    90     *    <tr><td> {@link #wait}        </td><td>   Y    </td><td>   Y    </td>
    91     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    92     *    <tr><td> {@link #wb}          </td><td>   Y    </td><td>   Y    </td>
    93     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    94     *    <tr><td> {@link #wbAll}          </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 #wbInvAll}       </td><td>   Y    </td><td>   Y    </td>
    99     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   100     *    <tr><td colspan="6"> Definitions: <br />
   101     *       <ul>
   102     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   103     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   104     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   105     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   106     *           <ul>
   107     *             <li> In your module startup after this module is started
   108     *   (e.g. Cache_Module_startupDone() returns TRUE). </li>
   109     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   110     *             <li> During main().</li>
   111     *             <li> During BIOS.startupFxns.</li>
   112     *           </ul>
   113     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   114     *           <ul>
   115     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   116     *             <li> In your module startup before this module is started
   117     *   (e.g. Cache_Module_startupDone() returns FALSE).</li>
   118     *           </ul>
   119     *       </ul>
   120     *    </td></tr>
   121     *
   122     *  </table>
   123     *  @p
   124     */
   125    
   126    @ModuleStartup
   127    
   128    module Cache inherits ti.sysbios.interfaces.ICache
   129    {
   130        /*!
   131         *  ======== ModView ========
   132         *  @_nodoc
   133         */
   134        metaonly struct CacheInfoView {
   135            String      cache;
   136            SizeT       cacheSize;
   137            SizeT       lineSize;
   138            UInt        ways;
   139            SizeT       waySize;
   140        };
   141    
   142        /*!
   143         *  ======== rovViewInfo ========
   144         *  @_nodoc
   145         */
   146        @Facet
   147        metaonly config ViewInfo.Instance rovViewInfo =
   148            ViewInfo.create({
   149                viewMap: [
   150                    ['Cache Info',  { type: ViewInfo.MODULE_DATA,
   151                                      viewInitFxn: 'viewInitCacheInfo',
   152                                      structName: 'CacheInfoView'}]
   153                ]
   154            });
   155    
   156        /*!
   157         *  Enable L1 and L2 data and program caches.
   158         *
   159         *  To enable a subset of the caches, set this parameter
   160         *  to 'false' and call Cache_enable() within main, passing it only
   161         *  the {@link Cache#Type Cache_Type(s)} to be enabled.
   162         *
   163         *  Data caching requires the MMU and the memory section/page
   164         *  descriptor cacheable attribute to be enabled.
   165         */
   166        override config Bool enableCache = true;
   167    
   168        /*! @_nodoc
   169         *  ======== getEnabled ========
   170         *  Get the 'type' bitmask of cache(s) enabled.
   171         */
   172        Bits16 getEnabled();
   173    
   174        /*!
   175         *  ======== invL1pAll ========
   176         *  Invalidate all of L1 program cache.
   177         */
   178        Void invL1pAll();
   179    
   180        /*!
   181         *  ======== wbAll ========
   182         *
   183         *  Performs a global write back by set/way of one or more levels of cache.
   184         *  The cache maintenance operations performed during this sequence are not
   185         *  broadcast to other CPUs within the same shareability domain. Unless all
   186         *  memory locations are regarded as non-cacheable on other CPUs, it is not
   187         *  possible to prevent locations from being allocated into the cache by
   188         *  other CPUs while this cache manintenance operation is in progress.
   189         */
   190        override Void wbAll();
   191    
   192        /*!
   193         *  ======== wbInvAll ========
   194         *
   195         *  Performs a global write back and invalidate by set/way of one or more
   196         *  levels of cache. The cache maintenance operations performed during this
   197         *  sequence are not broadcast to other CPUs within the same shareability
   198         *  domain. Unless all memory locations are regarded as non-cacheable by
   199         *  other CPUs, it is not possible to prevent locations from being
   200         *  allocated into the cache by other CPUs while this cache manintenance
   201         *  operation is in progress.
   202         */
   203        override Void wbInvAll();
   204    
   205        /*!
   206         *  @_nodoc
   207         *  ======== startup ========
   208         *  startup function to enable cache early during climb-up
   209         */
   210        Void startup();
   211    
   212    internal:
   213    
   214        /*
   215         *  ======== initModuleState ========
   216         *  Initializes the module state.
   217         *
   218         *  This function initializes module state fields like
   219         *  L1/L2 cache size and number of cache lines/sets. It
   220         *  is registered as a first function.
   221         */
   222        Void initModuleState();
   223    
   224        /*
   225         *  ======== disableL1D ========
   226         *  Disable data cache
   227         *
   228         *  This function disables the L1 data cache before performing
   229         *  a "write back invalidate all" of data and instruction caches.
   230         *
   231         *  The L2 unified cache cannot be disabled on ARMv8A devices.
   232         *  Disabling the L1 data cache effectively disables the L2 unified
   233         *  cache for all data caching purposes (on the current core in a
   234         *  ARMv8A multi-core system).
   235         */
   236        Void disableL1D();
   237    
   238        /*
   239         *  ======== disableL1P ========
   240         *  Disable instruction cache
   241         *
   242         *  This function disables the L1 instruction cache before
   243         *  performing a "invalidate all" of the whole instruction
   244         *  cache.
   245         *
   246         *  The L2 unified cache cannot be disabled on ARMv8A devices.
   247         *  Disabling the L1 instruction cache effectively disables the
   248         *  L2 unified cache for all instruction caching purposes (on
   249         *  the current core in a ARMv8A multi-core system).
   250         */
   251        Void disableL1P();
   252    
   253        /*
   254         *  ======== enableL1D ========
   255         *  Enable data cache.
   256         *
   257         *  This function enables the L1 data cache.
   258         *
   259         *  Enabling the L1 data cache effectively enables the L2 unified
   260         *  cache for all data caching purposes (on the current core in a
   261         *  ARMv8A multi-core system).
   262         */
   263        Void enableL1D();
   264    
   265        /*
   266         *  ======== enableL1P ========
   267         *  Enable instruction cache.
   268         *
   269         *  This function enables the L1 instruction cache.
   270         *
   271         *  Enabling the L1 instruction cache effectively enables the
   272         *  L2 unified cache for all instruction caching purposes (on
   273         *  the current core in a ARMv8A multi-core system).
   274         *
   275         *  If the MMU is disabled and the L1 instruction cache is enabled,
   276         *  no new instructions will be cached in the L2 unified cache.
   277         *  However, code already cached in the L2 cache will be fetched.
   278         */
   279        Void enableL1P();
   280    
   281        /*
   282         *  ======== enableSmp ========
   283         *  Set CPUECTLR_EL1.SMPEN bit.
   284         */
   285        Void enableSmp();
   286    
   287        /*
   288         *  ======== invL1d ========
   289         *  Invalidates range in L1 data cache.
   290         */
   291        Void invL1d(Ptr blockPtr, SizeT byteCnt, Bool wait);
   292    
   293        /*
   294         *  ======== invL1p ========
   295         *  Invalidates range in L1 program cache.
   296         */
   297        Void invL1p(Ptr blockPtr, SizeT byteCnt, Bool wait);
   298    
   299        /*
   300         *  ======== getCacheLevelInfo ========
   301         *  returns Cache Size Id Register of corresponding Cache level
   302         *
   303         *  level values
   304         *      0 = L1D
   305         *      1 = L1P
   306         *      2 = L2
   307         */
   308        Bits32 getCacheLevelInfo(UInt level);
   309    
   310        struct Module_State {
   311            Bits32  l1dInfo;
   312            Bits32  l1pInfo;
   313            Bits32  l2Info;
   314        }
   315    }