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.a15.smp;
    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 implemented as a clean/invalidate
    67     *  instruction on A15. Therefore, calls to Cache_inv()/Cache_invAll()
    68     *  will behave 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 #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 #wbInv}       </td><td>   Y    </td><td>   Y    </td>
    95     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    96     *    <tr><td> {@link #wbInvAll} </td><td>   Y    </td><td>   Y    </td>
    97     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    98     *    <tr><td> {@link #wbAll}    </td><td>   Y    </td><td>   Y    </td>
    99     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   100     *    <tr><td> {@link #wbInvAllLoUIS} </td><td>   Y    </td><td>   Y    </td>
   101     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   102     *    <tr><td> {@link #wbAllLoUIS}    </td><td>   Y    </td><td>   Y    </td>
   103     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   104     *    <tr><td> {@link #preLoad}    </td><td>   Y    </td><td>   Y     </td>
   105     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
   106     *    <tr><td colspan="6"> Definitions: <br />
   107     *       <ul>
   108     *         <li> <b>Hwi</b>: API is callable from a Hwi thread. </li>
   109     *         <li> <b>Swi</b>: API is callable from a Swi thread. </li>
   110     *         <li> <b>Task</b>: API is callable from a Task thread. </li>
   111     *         <li> <b>Main</b>: API is callable during any of these phases: </li>
   112     *           <ul>
   113     *             <li> In your module startup after this module is started
   114     *   (e.g. Cache_Module_startupDone() returns TRUE). </li>
   115     *             <li> During xdc.runtime.Startup.lastFxns. </li>
   116     *             <li> During main().</li>
   117     *             <li> During BIOS.startupFxns.</li>
   118     *           </ul>
   119     *         <li> <b>Startup</b>: API is callable during any of these phases:</li>
   120     *           <ul>
   121     *             <li> During xdc.runtime.Startup.firstFxns.</li>
   122     *             <li> In your module startup before this module is started
   123     *   (e.g. Cache_Module_startupDone() returns FALSE).</li>
   124     *           </ul>
   125     *       </ul>
   126     *    </td></tr>
   127     *
   128     *  </table>
   129     *  @p
   130     */
   131    
   132    module Cache inherits ti.sysbios.interfaces.ICache
   133    {
   134        /*!
   135         *  Size of L1 data cache Line in bytes
   136         */
   137        const UInt sizeL1dCacheLine = 64;
   138    
   139        /*!
   140         *  Size of L1 program cache Line in bytes
   141         */
   142        const UInt sizeL1pCacheLine = 64;
   143    
   144        /*!
   145         *  Size of L2 cache Line in bytes
   146         */
   147        const UInt sizeL2CacheLine = 64;
   148    
   149        /*!
   150         *  ======== ModView ========
   151         *  @_nodoc
   152         */
   153        metaonly struct CacheInfoView {
   154            String      cache;
   155            SizeT       cacheSize;
   156            SizeT       lineSize;
   157            UInt        ways;
   158            SizeT       waySize;
   159        };
   160    
   161        /*!
   162         *  ======== rovViewInfo ========
   163         *  @_nodoc
   164         */
   165        @Facet
   166        metaonly config ViewInfo.Instance rovViewInfo =
   167            ViewInfo.create({
   168                viewMap: [
   169                    ['Cache Info',  { type: ViewInfo.MODULE_DATA,
   170                                      viewInitFxn: 'viewInitCacheInfo',
   171                                      structName: 'CacheInfoView'}]
   172                ]
   173            });
   174    
   175        /*! Asserted in Cache_lock */
   176        config Assert.Id A_badBlockLength = {
   177            msg: "A_badBlockLength: Block length too large. Must be <= L2 way size."
   178        };
   179    
   180        /*! Asserted in Cache_lock */
   181        config Assert.Id A_blockCrossesPage = {
   182            msg: "A_blockCrossesPage: Memory block crosses L2 way page boundary."
   183        };
   184    
   185        /*!
   186         *  ======== A_cacheDisableUnsupported ========
   187         *  Assert raised when attempting to disable L1 data or L2 unified cache
   188         *
   189         *  When running in SMP mode, the inter-core lock is implemented using
   190         *  ldrex/strex instructions and requires the hardware to implement a
   191         *  global monitor to work. Some devices like Keystone 2, do not implement
   192         *  a global monitor (only a local monitor). On such devices, the
   193         *  cache coherency logic (snoop control unit) along with the local monitors
   194         *  can effectively work like a global monitor. Therefore, it is important
   195         *  that the caches are not disabled as that would disable cache coherency
   196         *  on the particular core and cause the inter-core lock to not work.
   197         */
   198        config xdc.runtime.Assert.Id A_cacheDisableUnsupported  = {
   199            msg: "A_cacheDisableUnsupported: Disabling the L1 data or L2 unified cache from user code is not supported. Cache disable/enable is internally managed by the kernel."
   200        };
   201    
   202        /*!
   203         *  ======== A_cacheEnableUnsupported ========
   204         *  Assert raised when attempting to enable L1 data or L2 unified cache
   205         *
   206         *  It is not recommended for the user code to anable/disable the caches
   207         *  when running in SMP mode. Please see the documentation
   208         *  {@link #A_cacheDisableUnsupported here} for more details.
   209         */
   210        config xdc.runtime.Assert.Id A_cacheEnableUnsupported  = {
   211            msg: "A_cacheEnableUnsupported: Enabling the L1 data or L2 unified cache from user code is not supported. Cache disable/enable is internally managed by the kernel."
   212        };
   213    
   214        /*!
   215         *  ======== enable ========
   216         *  Enables all cache(s)
   217         *
   218         *  This function is not fully supported when running in SMP mode. Only
   219         *  L1 program cache enable is supported. Attempting to enable the L1
   220         *  data and/or L2 cache will cause an assertion failure. The caches are
   221         *  enabled during the startup sequence if {@link #enableCache enableCache}
   222         *  config param is set to true. Since disabling the caches at runtime
   223         *  is not fully supported, the cache enable function is not fully
   224         *  supported.
   225         *
   226         *  Please see {@link #disable Cache_disable()} cdoc for more a detailed
   227         *  explanation of why disabling the caches is harmful and not supported.
   228         */
   229        override Void enable(Bits16 type);
   230    
   231        /*!
   232         *  ======== disable ========
   233         *  Disables the 'type' cache(s)
   234         *
   235         *  This function is not fully supported when running in SMP mode. Only
   236         *  L1 program cache disable is supported. Attempting to disable the L1
   237         *  data and/or L2 cache will cause an assertion failure.
   238         *
   239         *  Here's a brief explanation of why caches should not be disabled.
   240         *  When running in SMP mode, the inter-core lock is implemented using
   241         *  ldrex/strex instructions and requires the hardware to implement a
   242         *  global monitor to work properly. Some devices like Keystone 2,
   243         *  do not implement a global monitor (only a local monitor). On such
   244         *  devices, the cache coherency logic (snoop control unit) along with
   245         *  the local monitors can effectively work like a global monitor.
   246         *  Therefore, it is important that the caches are not disabled as that
   247         *  would disable cache coherency on the particular core and cause the
   248         *  inter-core lock to not work.
   249         */
   250        override Void disable(Bits16 type);
   251    
   252        /*!
   253         *  ======== enableCache ========
   254         *  Enable L1 and L2 data and program caches.
   255         *
   256         *  To enable a subset of the caches, set this parameter
   257         *  to 'false' and call Cache_enable() within main, passing it only
   258         *  the {@link Cache#Type Cache_Type(s)} to be enabled.
   259         *
   260         *  Data caching requires the MMU and the memory section/page
   261         *  descriptor cacheable attribute to be enabled.
   262         */
   263        override config Bool enableCache = true;
   264    
   265        /*!
   266         *  ======== branchPredictionEnabled ========
   267         *  Enable Branch Prediction at startup, default is true.
   268         *
   269         *  This flag controls whether Branch Prediction should be automatically
   270         *  enabled or disabled during system startup.
   271         *
   272         *  @a(NOTE)
   273         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction)
   274         *  feature is disabled.
   275         */
   276        config Bool branchPredictionEnabled = true;
   277    
   278        /*!
   279         *  ======== errata798870 ========
   280         *  Enable workaround for ARM errata 798870.
   281         *
   282         *  Errata 798870 brief description:
   283         *  A memory read can stall indefinitely in the L2 cache
   284         */
   285        config Bool errata798870 = false;
   286    
   287        /*! @_nodoc
   288         *  ======== getEnabled ========
   289         *  Get the 'type' bitmask of cache(s) enabled.
   290         */
   291        Bits16 getEnabled();
   292    
   293        /*!
   294         *  ======== invL1pAll ========
   295         *  Invalidate all of L1 program cache.
   296         */
   297        Void invL1pAll();
   298    
   299        /*!
   300         *  @_nodoc
   301         *  ======== invBPAll ========
   302         *  Invalidate all branch predictors.
   303         */
   304        Void invBPAll();
   305    
   306        /*!
   307         *  ======== preLoad ========
   308         *  Loads a memory block into the L2 cache.
   309         *
   310         *  A block of memory is loaded into the L2 cache.
   311         *
   312         *  The memory block is loaded into cache one L2 cache line at time.
   313         *
   314         *  The byteCnt argument must be less than or equal to an L2 cache
   315         *  size. An assert is generated if this rule is violated.
   316         *
   317         *  Except for the normal L1 instruction cache behavior
   318         *  during code execution, the L1 instruction cache is
   319         *  unaffected by this API.
   320         *  The L1 data cache will be temporarily polluted by the contents
   321         *  of the referenced memory block.
   322         *
   323         *  @a(NOTE)
   324         *  Interrupts are disabled for the entire time the memory block
   325         *  is being loaded into cache. For this reason, use of this API
   326         *  is probably best at system intialization time
   327         *  (ie: within 'main()').
   328         *
   329         *  @param(blockPtr) start address of range to be loaded
   330         *  @param(byteCnt)  number of bytes to be loaded
   331         */
   332        Void preLoad(Ptr blockPtr, SizeT byteCnt);
   333    
   334        /*!
   335         *  ======== enableBP ========
   336         *  Enable Branch Prediction
   337         *
   338         *  Calling this API will enable branch prediction.
   339         *
   340         *  @a(NOTE)
   341         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction)
   342         *  feature is disabled.
   343         */
   344        Void enableBP();
   345    
   346        /*!
   347         *  ======== disableBP ========
   348         *  Disable Branch Prediction
   349         *
   350         *  Calling this API will disable branch prediction.
   351         *
   352         *  @a(NOTE)
   353         *  Upon reset, the A15's Program Flow Prediction (Branch Prediction)
   354         *  feature is disabled.
   355         */
   356        Void disableBP();
   357    
   358        /*!
   359         *
   360         *  ======== wbAll ========
   361         *  Write back all caches
   362         *
   363         *  This function writes back the data cache to the point of coherency.
   364         *  On a Cortex-A15, point of coherency is the main memory implying that
   365         *  this function will write back the L1 data cache (on this core) followed
   366         *  by the L2 unified cache that is shared by all cores in the MPCore
   367         *  sub-system.
   368         *
   369         *  When running in SMP mode, it is not recommended to call this function
   370         *  as it does not guarantee that the L1 data caches on all other cores
   371         *  will be written back before writing back the unified L2 cache. This
   372         *  function should only be called if all other cores are in a power down
   373         *  state or if their local L1 caches are disabled i.e. they do not have
   374         *  any dirty L1 cache lines.
   375         */
   376        override Void wbAll();
   377    
   378        /*!
   379         *  ======== wbInvAll ========
   380         *  Write back invalidate all caches
   381         *
   382         *  This function writes back and invalidates the data cache to the point
   383         *  of coherency. On a Cortex-A15, point of coherency is the main memory
   384         *  implying that this function will write back and invalidate the L1 data
   385         *  cache (on this core) followed by the L2 unified cache that is shared
   386         *  by all cores in the MPCore sub-system.
   387         *
   388         *  When running in SMP mode, it is not recommended to call this function
   389         *  as it does not guarantee that the L1 data caches on all other cores
   390         *  will be flushed before flushing the unified L2 cache. This function
   391         *  should only be called if all other cores are in a power down state or
   392         *  if their local L1 caches are disabled i.e. they do not have any dirty
   393         *  L1 cache lines.
   394         */
   395        override Void wbInvAll();
   396    
   397        /*!
   398         *  ======== wbAllLoUIS ========
   399         *  Write back data cache to PoU for an Inner Shareable domain
   400         *
   401         *  This function writes back the L1 data cache. There is no effect
   402         *  on program cache. All data cache lines are left valid.
   403         *
   404         *  On Cortex-A15, this function will write back the local CPU's
   405         *  L1 data cache to the L2 cache but not beyond. Calling this function
   406         *  has no affect on the local L1 caches of all other cores in the MPCore
   407         *  sub-system. This API should be called with Hwis and/or Tasking disabled
   408         *  to guarantee the write back operation is complete.
   409         */
   410        Void wbAllLoUIS();
   411    
   412        /*!
   413         *  ======== wbInvAllLoUIS ========
   414         *  Write back invalidate data cache to PoU for an Inner Shareable domain
   415         *
   416         *  On Cortex-A15, this function will write back and invalidate the local
   417         *  CPU's L1 data cache to the L2 cache but not beyond. Calling this
   418         *  function has no affect on the local L1 caches of all other cores in the
   419         *  MPCore sub-system. This API should be called with Hwis and/or Tasking
   420         *  disabled to guarantee the write back invalidate operation is complete.
   421         */
   422        Void wbInvAllLoUIS();
   423    
   424        /*!
   425         *  @_nodoc
   426         *  ======== startup ========
   427         *  startup function to enable cache early during climb-up
   428         */
   429        Void startup();
   430    
   431    internal:
   432    
   433        /*
   434         *  ======== initModuleState ========
   435         *  Initializes the module state.
   436         *
   437         *  This function initializes module state fields like
   438         *  L1/L2 cache size and number of cache lines/sets. It
   439         *  is registered as a first function.
   440         */
   441        Void initModuleState();
   442    
   443        /*!
   444         *  ======== disableL1D ========
   445         *  Disable L1 data cache on this core
   446         *
   447         *  This function disables the L1 data cache before performing
   448         *  a "write back invalidate all" of the cache.
   449         */
   450        Void disableL1D();
   451    
   452        /*!
   453         *  ======== disableL1P ========
   454         *  Disable instruction cache on this core
   455         *
   456         *  This function disables the L1 instruction cache before
   457         *  performing an "invalidate all" of the whole instruction
   458         *  cache.
   459         */
   460        Void disableL1P();
   461    
   462        /*!
   463         *  ======== enableL1D ========
   464         *  Enable data cache on this core
   465         *
   466         *  This function enables the L1 data cache.
   467         *
   468         *  Enabling the L1 data cache effectively enables the L2 unified
   469         *  cache for all data caching purposes (on the current core in a
   470         *  Cortex-A15 multi-core system).
   471         */
   472        Void enableL1D();
   473    
   474        /*!
   475         *  ======== enableL1P ========
   476         *  Enable instruction cache on this core
   477         *
   478         *  This function enables the L1 instruction cache.
   479         *
   480         *  Enabling the L1 instruction cache effectively enables the
   481         *  L2 unified cache for all instruction caching purposes (on
   482         *  the current core in a Cortex-A15 multi-core system).
   483         *
   484         *  The L1 instruction cache can be enabled even if the MMU is
   485         *  disabled and will cache instructions. However, if the MMU
   486         *  is disabled and the L1 instruction cache is enabled, no new
   487         *  instructions will be cached in the L2 unified cache. However,
   488         *  code already cached in the L2 cache will be fetched.
   489         */
   490        Void enableL1P();
   491    
   492        /*!
   493         *  ======== invL1d ========
   494         *  Invalidates range in L1 data cache.
   495         *
   496         *  The range of addresses operated on gets quantized to whole
   497         *  cache lines.
   498         */
   499        Void invL1d(Ptr blockPtr, SizeT byteCnt, Bool wait);
   500    
   501        /*!
   502         *  ======== invL1p ========
   503         *  Invalidates range in L1 program cache.
   504         *
   505         *  The range of addresses operated on gets quantized to whole
   506         *  cache lines.
   507         */
   508        Void invL1p(Ptr blockPtr, SizeT byteCnt, Bool wait);
   509    
   510        /*!
   511         *  ======== preFetch ========
   512         *  load a block of memory into the L2 cache.
   513         */
   514        Void preFetch(Ptr blockPtr, SizeT byteCnt);
   515    
   516        /*!
   517         *  ======== getCacheLevelInfo ========
   518         *  returns Cache Size Id Register of corresponding Cache level
   519         *
   520         *  level values
   521         *      0 = L1D
   522         *      1 = L1P
   523         *      2 = L2
   524         */
   525        Bits32 getCacheLevelInfo(UInt level);
   526    
   527        /*!
   528         *  ======== getL2AuxControlReg ========
   529         *  Get current L2 Aux Control register contents
   530         */
   531        Bits32 getL2AuxControlReg();
   532    
   533        /*
   534         *  ======== setL2AuxControlReg ========
   535         *  Write to L2ACTLR using ROM API
   536         *
   537         *  Note: This API is only for OMAP5 and J6 devices as Keystone 2
   538         *  devices do not support the same ROM API interface.
   539         */
   540        Void setL2AuxControlReg(Bits32 arg);
   541    
   542        struct Module_State {
   543            Bits32  l1dInfo;
   544            Bits32  l1pInfo;
   545            Bits32  l2Info;
   546            SizeT   l2WaySize;
   547        }
   548    }