1    /* --COPYRIGHT--,BSD
     2     * Copyright (c) $(CPYYEAR), 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     * --/COPYRIGHT--*/
    32    /*
    33     *  ======== HeapMemMP.xdc ========
    34     *
    35     *! Revision History
    36     *! ================
    37     *! 23-Mar-2010 skp     cdoc cleanup
    38     *! 12-Feb-2010 skp     SDOCM00066723 (Remove 'version' field from Attrs)
    39     *! 09-Sep-2009 skp     09/09/09 code review changes
    40     *! 27-Aug-2009 skp     08/26/09 code review changes
    41     *! 23-Aug-2009 skp     Added static support/ROV views
    42     *! 12-Aug-2009 skp     Created from ti.sysbios.heaps.HeapMem
    43     */
    44    
    45    package ti.sdo.ipc.heaps;
    46    
    47    import ti.sdo.ipc.SharedRegion;
    48    import ti.sdo.ipc.Ipc;
    49    import ti.sdo.ipc.GateMP;
    50    import ti.sdo.utils.NameServer;
    51    
    52    import xdc.rov.ViewInfo;    /* Display local/shared state + FreeBlockView */
    53    
    54    import xdc.runtime.Error;
    55    import xdc.runtime.Assert;
    56    import xdc.runtime.Memory;
    57    import xdc.runtime.Startup;
    58    
    59    /*!
    60     *  ======== HeapMemMP ========
    61     *  Multi-processor variable size buffer heap implementation.
    62     *
    63     *  @p(html)
    64     *  This module has a common header that can be found in the {@link ti.ipc}
    65     *  package.  Application code should include the common header file (not the 
    66     *  RTSC-generated one):
    67     *
    68     *  <PRE>#include &lt;ti/ipc/HeapMemMP.h&gt;</PRE>
    69     *   
    70     *  The RTSC module must be used in the application's RTSC configuration file 
    71     *  (.cfg) if runtime APIs will be used in the application:
    72     *  
    73     *  <PRE>HeapMemMP = xdc.useModule('ti.sdo.ipc.heaps.HeapMemMP');</PRE>
    74     *
    75     *  Documentation for all runtime APIs, instance configuration parameters, 
    76     *  error codes macros and type definitions available to the application 
    77     *  integrator can be found in the 
    78     *  <A HREF="../../../../../doxygen/html/files.html">Doxygen documenation</A>
    79     *  for the IPC product.  However, the documentation presented on this page 
    80     *  should be referred to for information specific to the RTSC module, such as
    81     *  module configuration, Errors, and Asserts.
    82     *  @p
    83     */
    84    @InstanceInitError   /* For NameServer_addUInt32                            */
    85    @InstanceFinalize    /* For finalizing shared memory and removing NS entry  */
    86    
    87    module HeapMemMP inherits xdc.runtime.IHeap {
    88        
    89        /*! @_nodoc */
    90        metaonly struct BasicView {
    91            String          name;
    92            Ptr             buf;
    93            Memory.Size     totalSize;
    94            String          objType;
    95            Ptr             gate;
    96        }
    97        
    98        /*! @_nodoc */
    99        metaonly struct DetailedView {
   100            String          name;
   101            Ptr             buf;
   102            Memory.Size     totalSize;
   103            String          objType;
   104            Ptr             gate;  
   105            Ptr             attrs;
   106            Bool            cacheEnabled;
   107            Memory.Size     totalFreeSize;
   108            Memory.Size     largestFreeSize;
   109        }
   110        
   111        /*! @_nodoc */
   112        metaonly struct FreeBlockView {
   113            String          address;
   114            String          label;
   115            String          size;
   116        }
   117    
   118        /*! @_nodoc */
   119        @Facet
   120        metaonly config ViewInfo.Instance rovViewInfo = 
   121            ViewInfo.create({
   122                viewMap: [
   123                [
   124                    'Basic',
   125                    {
   126                        type: ViewInfo.INSTANCE,
   127                        viewInitFxn: 'viewInitBasic',
   128                        structName: 'BasicView'
   129                    }
   130                ],
   131                [
   132                    'Detailed',
   133                    {
   134                        type: ViewInfo.INSTANCE,
   135                        viewInitFxn: 'viewInitDetailed',
   136                        structName: 'DetailedView'
   137                    }
   138                ],
   139                [
   140                    'FreeList',
   141                    {
   142                        type: ViewInfo.INSTANCE_DATA,
   143                        viewInitFxn: 'viewInitData',
   144                        structName: 'FreeBlockView'
   145                    }
   146                ]
   147                ]
   148            });
   149    
   150        /*!
   151         *  ======== ExtendedStats ========
   152         *  Stats structure for the getExtendedStats API.  
   153         *
   154         *  @field(buf)           Local address of the shared buffer
   155         *                        This may be different from the original buf 
   156         *                        parameter due to alignment requirements.
   157         *  @field(size)          Size of the shared buffer. 
   158         *                        This may be different from the original size 
   159         *                        parameter due to alignment requirements.
   160         */
   161        struct ExtendedStats {
   162            Ptr   buf;
   163            SizeT size;
   164        }
   165      
   166        /*!
   167         *  Assert raised when a block of size 0 is requested.
   168         */
   169        config Assert.Id A_zeroBlock = 
   170            {msg: "A_zeroBlock: Cannot allocate size 0"};
   171        
   172        /*!
   173         *  Assert raised when the requested heap size is too small.
   174         */
   175        config Assert.Id A_heapSize = 
   176            {msg: "A_heapSize: Requested heap size is too small"};     
   177        
   178        /*!
   179         *  Assert raised when the requested alignment is not a power of 2.
   180         */
   181        config Assert.Id A_align = 
   182            {msg: "A_align: Requested align is not a power of 2"};     
   183            
   184        /*!
   185         *  Assert raised when the free detects that an invalid addr or size. 
   186         *
   187         *  This could arise when multiple frees are done on the same buffer or
   188         *  if corruption occurred.
   189         *
   190         *  This also could occur when an alloc is made with size N and the 
   191         *  free for this buffer specifies size M where M > N. Note: not every 
   192         *  case is detectable.
   193         *
   194         *  This assert can also be caused when passing an invalid addr to free
   195         *  or if the size is causing the end of the buffer to be
   196         *  out of the expected range.
   197         */
   198        config Assert.Id A_invalidFree = 
   199            {msg: "A_invalidFree: Invalid free"};
   200            
   201        /*!
   202         *  Raised when requested size exceeds largest free block.
   203         */
   204        config Error.Id E_memory = 
   205            {msg: "E_memory: Out of memory: handle=0x%x, size=%u"};
   206        
   207        /*! 
   208         *  Maximum runtime entries 
   209         *
   210         *  Maximum number of HeapMemMP's that can be dynamically created and
   211         *  added to the NameServer.
   212         *
   213         *  To minimize the amount of runtime allocation, this parameter allows
   214         *  the pre-allocation of memory for the HeapMemMP's NameServer table.
   215         *  The default is to allow growth (i.e. memory allocation when 
   216         *  creating a new instance).
   217         */
   218        metaonly config UInt maxRuntimeEntries = NameServer.ALLOWGROWTH;
   219        
   220        /*! 
   221         *  Maximum length for heap names
   222         */
   223        config UInt maxNameLen = 32;
   224        
   225        /*! 
   226         *  Section name is used to place the names table
   227         *
   228         *  The default value of NULL implies that no explicit placement is 
   229         *  performed.
   230         */
   231        metaonly config String tableSection = null;
   232    
   233    instance:
   234    
   235        /*! 
   236         *  GateMP used for critical region management of the shared memory 
   237         *
   238         *  Using the default value of NULL will result in use of the GateMP
   239         *  system gate for context protection.
   240         */
   241        config GateMP.Handle gate = null; 
   242        
   243        /*! @_nodoc
   244         *  Set to TRUE by the open() call. No one else should touch this!
   245         */
   246        config Bool openFlag = false;
   247    
   248        /*! 
   249         *  Name of this instance.
   250         *
   251         *  The name (if not NULL) must be unique among all HeapMemMP
   252         *  instances in the entire system.  When creating a new
   253         *  heap, it is necessary to supply an instance name.
   254         */
   255        config String name = null;
   256        
   257        /*! 
   258         *  Shared region ID
   259         *
   260         *  The index corresponding to the shared region from which shared memory
   261         *  will be allocated.
   262         */
   263        config UInt16 regionId = 0;
   264    
   265        /*! @_nodoc
   266         *  Physical address of the shared memory
   267         *
   268         *  This value can be left as 'null' unless it is required to place the
   269         *  heap at a specific location in shared memory.  If sharedAddr is null,
   270         *  then shared memory for a new instance will be allocated from the 
   271         *  heap belonging to the region identified by {@link #regionId}.
   272         */
   273        config Ptr sharedAddr = null;
   274        
   275        /*!
   276         *  Size of {@link #sharedBuf}
   277         *
   278         *  This is the size of the buffer to be used in the HeapMemMP instance.  
   279         *  The actual buffer size in the created instance might actually be less
   280         *  than the value supplied in 'sharedBufSize' because of alignment 
   281         *  constraints. 
   282         *
   283         *  It is important to note that the total amount of shared memory required
   284         *  for a HeapMemMP instance will be greater than the size supplied here.
   285         *  Additional space will be consumed by shared instance attributes and
   286         *  alignment-related padding.  Use the {@link #sharedMemReq} or the
   287         *  {@link #sharedMemReqMeta} call to determine the exact amount of shared
   288         *  memory required for an instance for a given sharedBufSize and cache
   289         *  settings.
   290         */
   291        config SizeT sharedBufSize = 0; 
   292    
   293        /*! 
   294         *  ======== getStats ========
   295         *  @a(HeapMemMP)
   296         *  getStats() will lock the heap using the HeapMemMP Gate while it retrieves
   297         *  the HeapMemMP's statistics.
   298         *
   299         *  The returned totalSize reflects the usable size of the buffer, not
   300         *  necessarily the size specified during create.
   301         */
   302        @DirectCall
   303        override Void getStats(xdc.runtime.Memory.Stats *stats);
   304    
   305        @DirectCall
   306        override Ptr alloc(SizeT size, SizeT align, xdc.runtime.Error.Block *eb);
   307    
   308        @DirectCall
   309        override Void free(Ptr block, SizeT size);
   310    
   311    internal:
   312    
   313        /*! Used in the attrs->status field */
   314        const UInt32 CREATED    = 0x07041776;
   315    
   316        /*! 
   317         *  This Params object is used for temporary storage of the
   318         *  module wide parameters that are for setting the NameServer instance.
   319         */
   320        metaonly config NameServer.Params nameSrvPrms;
   321    
   322        /*! Initialize shared memory, adjust alignment, allocate memory for buf */
   323        Void postInit(Object *obj, Error.Block *eb);
   324        
   325        /*! 
   326         * Header maintained at the lower address of every free block. The size of 
   327         * this struct must be a power of 2 
   328         */
   329        struct Header {
   330            SharedRegion.SRPtr  next;  /* SRPtr to next header (Header *)    */
   331            Bits32              size;  /* Size of this segment (Memory.size) */
   332        };
   333        
   334        /*! Structure of attributes in shared memory */    
   335        struct Attrs {
   336            Bits32                  status;     /* Version number                */
   337            SharedRegion.SRPtr      bufPtr;     /* SRPtr to buf                  */
   338            Header                  head;       /* First free block pointer.     */
   339                                                /* The size field will be used   */
   340                                                /* to store original heap size.  */
   341            SharedRegion.SRPtr      gateMPAddr; /* GateMP SRPtr                  */
   342        }
   343    
   344        struct Instance_State {
   345            Attrs               *attrs;         /* Local pointer to attrs        */
   346            GateMP.Handle       gate;           /* Gate for critical regions     */
   347            Ipc.ObjType         objType;        /* Static/Dynamic? open/creator? */
   348            Ptr                 nsKey;          /* Used to remove NS entry       */    
   349            Bool                cacheEnabled;   /* Whether to do cache calls     */
   350            UInt16              regionId;       /* SharedRegion index            */
   351            SizeT               allocSize;      /* Shared memory allocated       */
   352            Char                *buf;           /* Local pointer to buf          */
   353            SizeT               minAlign;       /* Minimum alignment required    */
   354            SizeT               bufSize;        /* Size of usable buffer         */
   355        };
   356        
   357        struct Module_State {
   358            NameServer.Handle       nameServer;
   359        };
   360    }
   361