1    /*
     2     * Copyright (c) 2014, 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    package ti.sysbios.hal.unicache;
    36    
    37    import xdc.rov.ViewInfo;
    38    import xdc.runtime.Error;
    39    import xdc.runtime.Types;
    40    
    41    import ti.sysbios.interfaces.ICache;
    42    import ti.sysbios.hal.Hwi;
    43    
    44    /*!
    45     *  ======== Cache ========
    46     *  The unicache Cache module used by the omap4 Tesla and Ducati cores
    47     *
    48     *  The Tesla and Ducati UniCaches do not support separate program and
    49     *  data caches. Therefore none of the unique Cache_Type L1P/L1D/L2P/L2D
    50     *  operations can be precisely supported. The APIs in this module ignore
    51     *  the P/D and observe only the L1/L2 designations (ie Cache_Type_L1P
    52     *  is functionally equivalent to Cache_Type_L1D and Cache_Type_L1).
    53     *
    54     *  @a(Restrictions)
    55     *  When used within a dual M3 core (Ducati arrangement), care must be
    56     *  taken when initializing this shared resource.
    57     *  The "Shared Resources" note provided
    58     *  in the {@link ti.sysbios.family.arm.ducati ducati} package discusses
    59     *  the management of the various hardware and software resources
    60     *  shared by the two M3 cores.
    61     *
    62     *  As the unicache is shared between the two M3 cores, it should only
    63     *  be initialized and enabled once.
    64     *  It is intended that Core 0 will {@link #configureCache configure}
    65     *  the unicache at startup and then either {@link #enableCache enable}
    66     *  it at that time or later on by manually invoking
    67     *  {@link #enable Cache_enable()}.
    68     *
    69     *  The unicache Cache module is a Gated module. In a dual M3 core (Ducati)
    70     *  environment, the unicache Cache module employs a
    71     *  {@link ti.sysbios.family.arm.ducati.GateDualCore GateDualCore} gate
    72     *  to arbitrate the usage of the shared unicache registers. In a non
    73     *  shared environment such as the C64T core in an OMAP4 device, a
    74     *  {@link ti.sysbios.gates.GateHwi GateHwi} gate is used to avoid multi
    75     *  thread conflicts.
    76     *
    77     *  @a
    78     *
    79     *  @p(html)
    80     *  <h3> Calling Context </h3>
    81     *  <table border="1" cellpadding="3">
    82     *    <colgroup span="1"></colgroup> <colgroup span="5" align="center">
    83     *    </colgroup>
    84     *
    85     *    <tr><th> Function                 </th><th>  Hwi   </th><th>  Swi   </th>
    86     *    <th>  Task  </th><th>  Main  </th><th>  Startup  </th></tr>
    87     *    <!--                                                                  -->
    88     *    <tr><td> {@link #disable}     </td><td>   Y    </td><td>   Y    </td>
    89     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    90     *    <tr><td> {@link #enable}      </td><td>   Y    </td><td>   Y    </td>
    91     *    <td>   Y    </td><td>   Y    </td><td>   Y    </td></tr>
    92     *    <tr><td> {@link #inv}         </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 #wait}        </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    @Gated
   127    
   128    module Cache inherits ti.sysbios.interfaces.ICache
   129    {
   130    
   131        // -------- Module Types --------
   132    
   133        /*!
   134         *  Runtime representation of the Cache registers
   135         */
   136        struct CACHE {
   137            UInt32 L1_INFO;         /* 0000 */
   138            UInt32 L1_CONFIG;       /* 0004 */
   139            UInt32 L1_INT;          /* 0008 */
   140            UInt32 L1_OCP;          /* 000C */
   141            UInt32 L1_MAINT;        /* 0010 */
   142            Ptr    L1_MTSTART;      /* 0014 */
   143            Ptr    L1_MTEND;        /* 0018 */
   144            Ptr    L1_CTADDR;       /* 001c */
   145            UInt32 L1_CTDATA;       /* 0020 */
   146    
   147            UInt32 Reserved[0x77];  /* 0024 - 001fc */
   148    
   149            UInt32 L2_INFO;         /* 0200 */
   150            UInt32 L2_CONFIG;       /* 0204 */
   151            UInt32 L2_INT;          /* 0208 */
   152            UInt32 L2_OCP;          /* 020C */
   153            UInt32 L2_MAINT;        /* 0210 */
   154            Ptr    L2_MTSTART;      /* 0214 */
   155            Ptr    L2_MTEND;        /* 0218 */
   156            Ptr    L2_CTADDR;       /* 021c */
   157            UInt32 L2_CTDATA;       /* 0220 */
   158        };
   159    
   160        /*!
   161         *  This device's unicache register set address.
   162         *  Initialized internally according to build target/device.
   163         */
   164        extern volatile CACHE cache;
   165    
   166        /*!
   167         *  OCP Interface Configuration Register Settings.
   168         */
   169        struct OCPConfig {
   170            UInt8 wrap;
   171            UInt8 wrbuffer;
   172            UInt8 prefetch;
   173            UInt8 cleanbuf;
   174        }
   175    
   176        /*!
   177         *  CONFIG Configuration Register Settings.
   178         */
   179        struct SecurityConfig {
   180            UInt8 secure;
   181            UInt8 nbypass;
   182            UInt8 secint;
   183            UInt8 secport;
   184            UInt8 secmain;
   185        }
   186    
   187        // -------- ROV view --------
   188    
   189        /*! @_nodoc */
   190        metaonly struct ModuleView {
   191            Bool        cacheEnabled;
   192        };
   193    
   194        /*! @_nodoc */
   195        @Facet
   196        metaonly config ViewInfo.Instance rovViewInfo =
   197            ViewInfo.create({
   198                viewMap: [
   199                    ['Module',   {type: ViewInfo.MODULE,   viewInitFxn: 'viewInitModule',   structName: 'ModuleView'}],
   200               ]
   201           });
   202    
   203        // Errors
   204    
   205        /*!
   206         *  Error raised when a Cache interrupt occurs
   207         *  Reason bits are contents of Cache Interrupt Register
   208         */
   209        config Error.Id E_exception = {
   210            msg: "E_exception: L%d reason: 0x%x"
   211        };
   212    
   213        // -------- Configuration Parameters --------
   214    
   215        /*!
   216         *  L1_OCP register settings
   217         */
   218        metaonly config OCPConfig ocpL1 = {
   219            wrap : 0,
   220            wrbuffer : 0,
   221            prefetch : 0
   222        };
   223    
   224        /*!
   225         *  L1_CONFIG register settings
   226         */
   227        metaonly config SecurityConfig configL1 = {
   228            secure : 0,
   229            nbypass : 0,
   230            secint : 1,
   231            secport : 1,
   232            secmain : 1
   233        };
   234    
   235        /*!
   236         *  L2_OCP register settings
   237         */
   238        metaonly config OCPConfig ocpL2 = {
   239            wrap : 0,
   240            wrbuffer : 0,
   241            prefetch : 0,
   242            cleanbuf : 0
   243        };
   244    
   245        /*!
   246         *  L2_CONFIG register settings
   247         */
   248        metaonly config SecurityConfig configL2 = {
   249            secure : 0,
   250            nbypass : 0,
   251            secint : 1,
   252            secport : 1,
   253            secmain : 1
   254        };
   255    
   256        /*!
   257         *  Configure cache at startup?
   258         *
   259         *  It is possible to configure the Cache at startup and not
   260         *  {@link #enableCache enable} it.
   261         *  However, it is not possible to enable the Cache at startup
   262         *  without configuring it.
   263         *
   264         *  Enabling the Cache will automatically enable configuring
   265         *  the Cache.
   266         */
   267        config Bool configureCache = false;
   268    
   269        /*!
   270         *  Enable cache at startup?
   271         *
   272         *  Enabling the Cache at startup will force
   273         *  {@link #configureCache configuring} the Cache at startup.
   274         */
   275        config Bool enableCache = false;
   276    
   277        /*!
   278         *  Maximum buffer size to use discrete cache line operations with.
   279         *
   280         *  For buffers below a certain size, cache maintenance operations are
   281         *  more efficient if performed on single cache lines at a time
   282         *  rather than on an entire region.
   283         *
   284         *  For buffer sizes equal to or less than this setting, the {@link #inv},
   285         *  {@link #wb}, and {@link #wbInv} APIs will use a series of individual
   286         *  cache line operations. For buffer sizes large than this setting, a
   287         *  a single block mode operation will be performed.
   288         *
   289         *  For M3 cores, the default setting is 1024 bytes.
   290         *  For 64T cores, the default setting is 4096 bytes.
   291         */
   292        config SizeT maxLineModeBufSize;
   293    
   294        /*!
   295         *  L1 Interrupt Handler.
   296         *  Default is set to an internal L1 interrupt handler
   297         */
   298        metaonly config Hwi.FuncPtr l1InterruptHandler;
   299    
   300        /*!
   301         *  L1 Interrupt number.
   302         *  Default is device unique but can be set in the user config file.
   303         */
   304        metaonly config UInt l1InterruptNumber;
   305    
   306        /*!
   307         *  L1 Interrupt priority.
   308         *  Default is device unique but can be set in the user config file.
   309         */
   310        metaonly config UInt l1InterruptPriority;
   311    
   312        /*!
   313         *  L2 Interrupt Handler.
   314         *  Default is set to an internal L2 interrupt handler
   315         */
   316        metaonly config Hwi.FuncPtr l2InterruptHandler;
   317    
   318        /*!
   319         *  L2 Interrupt number.
   320         *  Default is device unique but can be set in the user config file.
   321         */
   322        metaonly config UInt l2InterruptNumber;
   323    
   324        /*!
   325         *  L2 Interrupt priority.
   326         *  Default is device unique but can be set in the user config file.
   327         */
   328        metaonly config UInt l2InterruptPriority;
   329    
   330        // -------- Module Functions --------
   331    
   332        /*!
   333         *  ======== lock ========
   334         *  Locks a memory block into the cache.
   335         *
   336         *  @param(blockPtr) start address of range to be locked
   337         *  @param(byteCnt)  number of bytes to be locked
   338         *  @param(type)     bit mask of Cache type
   339         *  @param(wait)     wait until the operation is completed
   340         */
   341        Void lock(Ptr blockPtr, SizeT byteCnt, Bits16 type, Bool wait);
   342    
   343        /*!
   344         *  ======== unlock ========
   345         *  Unlocks a cached memory block.
   346         *
   347         *  @param(blockPtr) start address of range to be locked
   348         *  @param(byteCnt)  number of bytes to be locked
   349         *  @param(type)     bit mask of Cache type
   350         *  @param(wait)     wait until the operation is completed
   351         */
   352        Void unlock(Ptr blockPtr, SizeT byteCnt, Bits16 type, Bool wait);
   353    
   354        /*!
   355         *  ======== preload ========
   356         *  Loads a memory block into the cache.
   357         *
   358         *  @param(blockPtr) start address of range to be loaded
   359         *  @param(byteCnt)  number of bytes to be loaded
   360         *  @param(type)     bit mask of Cache type
   361         *  @param(wait)     wait until the operation is completed
   362         */
   363        Void preload(Ptr blockPtr, SizeT byteCnt, Bits16 type, Bool wait);
   364    
   365        /*!
   366         *  ======== preloadLock ========
   367         *  Loads and locks a memory block into the cache.
   368         *
   369         *  @param(blockPtr) start address of range to be loaded
   370         *  @param(byteCnt)  number of bytes to be loaded
   371         *  @param(type)     bit mask of Cache type
   372         *  @param(wait)     wait until the operation is completed
   373         */
   374        Void preloadLock(Ptr blockPtr, SizeT byteCnt, Bits16 type, Bool wait);
   375    
   376        /*!
   377         *  ======== wbAll ========
   378         *  Write back all caches
   379         *
   380         *  Perform a global write back.
   381         *  All cache lines are left valid in L1 and L2 caches and the data in L1
   382         *  cache is written back to L2 or external.  All cache lines are left
   383         *  valid in L2 cache and the data in L2 cache is written back to
   384         *  external.
   385         *  Waits for completion.
   386         */
   387        override Void wbAll();
   388    
   389        /*!
   390         *  ======== invAll ========
   391         *  Invalidate all caches
   392         *
   393         *  Perform a global invalidate.  All cache lines are
   394         *  invalidated in L1 and L2 caches.
   395         *  Waits for completion.
   396         */
   397        Void invAll();
   398    
   399        /*!
   400         *  ======== wbInvAll ========
   401         *  Write back invalidate all caches
   402         *
   403         *  Perform a global write back.
   404         *  Then perform a global invalidate.
   405         *  All cache lines are invalidated in L1 and L2 caches.
   406         *  Waits for completion.
   407         */
   408        override Void wbInvAll();
   409    
   410        /*!
   411         *  ======== read ========
   412         *  Read a block of memory from the cache.
   413         *  Only whole numbers of 32 bit words are transferred.
   414         *  byteCnt is divided by 4 to convert to number of words.
   415         *
   416         *  @param(blockPtr) start address of range to be loaded
   417         *  @param(byteCnt)  number of bytes to be loaded
   418         *  @param(type)     bit mask of Cache type
   419         *  @param(destBuf)  address of destination buffer
   420         */
   421        Void read(Ptr blockPtr, SizeT byteCnt, Bits16 type, Ptr destBuf);
   422    
   423        /*!
   424         *  @_nodoc
   425         *  ======== dumpRegs ========
   426         *  formatted dump of cache registers
   427         */
   428        Void dumpRegs();
   429    
   430    internal:
   431    
   432        /* initial L1 register settings */
   433        config Bits32 l1ocpConfig;
   434        config Bits32 l1secConfig;
   435    
   436        /* initial L2 register settings */
   437        config Bits32 l2ocpConfig;
   438        config Bits32 l2secConfig;
   439    
   440        /* device-specific L2 support enabled flag */
   441        readonly config Bool l2CacheSupported;
   442    
   443        /* base address of Cache registers */
   444        metaonly config Ptr baseAddr;
   445    
   446        /*!
   447         *  ======== seizeRegs ========
   448         *  seize the cache registers
   449         */
   450        UInt seizeRegs();
   451    
   452        /*!
   453         *  ======== releaseRegs ========
   454         *  release the cache registers
   455         */
   456        Void releaseRegs(UInt key);
   457    
   458        /*
   459         *  ======== ISR ========
   460         *  Cache Interrupt Service Routine
   461         */
   462        Void ISR(UArg level);
   463    
   464        /*
   465         *  ======== invAllI ========
   466         *  Invalidate all caches
   467         *
   468         *  Perform a global invalidate.  All cache lines are
   469         *  invalidated in L1 and L2 caches.
   470         *  Waits for completion.
   471         *
   472         *  This function does not seize the cache regs before
   473         *  accessing them.
   474         */
   475        Void invAllI();
   476    
   477        /*!
   478         *  ======== printInfo ========
   479         *  formatted dump of cache registers helper
   480         */
   481        Void printInfo(UInt info, UInt level);
   482    
   483        /*!
   484         *  ======== printConfig ========
   485         *  formatted dump of cache registers helper
   486         */
   487        Void printConfig(UInt cfg, UInt level);
   488    
   489        /*!
   490         *  ======== printOCP ========
   491         *  formatted dump of cache registers helper
   492         */
   493        Void printOCP(UInt cfg, UInt level);
   494    
   495        /*!
   496         *  ======== startup ========
   497         *  startup function to enable cache early during climb-up
   498         */
   499        Void startup();
   500    }