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