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     *  ======== SharedRegion.xdc ========
    34     *
    35     */
    36    
    37    package ti.sdo.ipc;
    38    
    39    import xdc.runtime.Error;
    40    import xdc.runtime.IHeap;
    41    import xdc.rov.ViewInfo;
    42    
    43    /*!
    44     *  ======== SharedRegion ========
    45     *  Shared memory manager and address translator.
    46     *
    47     *  @p(html)
    48     *  This module has a common header that can be found in the {@link ti.ipc}
    49     *  package.  Application code should include the common header file (not the
    50     *  RTSC-generated one):
    51     *
    52     *  <PRE>#include &lt;ti/ipc/SharedRegion.h&gt;</PRE>
    53     *
    54     *  The RTSC module must be used in the application's RTSC configuration file
    55     *  (.cfg) if runtime APIs will be used in the application:
    56     *
    57     *  <PRE>SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');</PRE>
    58     *
    59     *  Documentation for all runtime APIs, instance configuration parameters,
    60     *  error codes macros and type definitions available to the application
    61     *  integrator can be found in the
    62     *  <A HREF="../../../../doxygen/html/files.html">Doxygen documenation</A>
    63     *  for the IPC product.  However, the documentation presented on this page
    64     *  should be referred to for information specific to the RTSC module, such as
    65     *  module configuration, Errors, and Asserts.
    66     *  @p
    67     *
    68     *  The SharedRegion module is designed to be used in a multi-processor
    69     *  environment in which memory regions are shared and accessed
    70     *  across different processors. The module itself does not use any shared
    71     *  memory, because all module state is stored locally.  SharedRegion
    72     *  APIs use the system gate for thread protection.
    73     *
    74     *  This module creates and stores a local shared memory region table.  The
    75     *  table contains the processor's view for every shared region in the system.
    76     *  The table must not contain any overlapping regions.  Each processor's
    77     *  view of a particular shared memory region is determined by the region id.
    78     *  In cases where a processor cannot access a certain shared memory region,
    79     *  that shared memory region should be left invalid for that processor.
    80     *  Note:  The {@link #numEntries} must be the same on all processors.
    81     *
    82     *  Each shared region contains the following:
    83     *  @p(blist)
    84     *  -base:          The base address
    85     *  -len:           The length
    86     *  -name:          The name of the region
    87     *  -isValid:       Whether the region is valid
    88     *  -ownerProcId:   The id of the processor which owns the region
    89     *  -cacheEnable:   Whether the region is cacheable
    90     *  -cacheLineSize: The cache line size
    91     *  -createHeap:    Whether a heap is created for the region.
    92     *  @p
    93     *
    94     *  A region is added statically using the {@link #setEntryMeta} API.
    95     *  The length of a region must be the same across all processors.
    96     *  The owner of the region can be specified.  If specified, the owner
    97     *  manages the shared region.  It creates a HeapMemMP instance which spans
    98     *  the full size of the region.  The other processors open the same HeapMemMP
    99     *  instance.
   100     *
   101     *  Note: Prior to calling Ipc_start(), If a SharedRegion's 'isValid'
   102     *  is true and 'createHeap' is true then the owner of the SharedRegion
   103     *  must be the same as the owner of SharedRegion 0.
   104     *
   105     *  An example of a SharedRegion configuration is as follows:
   106     *
   107     *  @p(code)
   108     *
   109     * var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
   110     * SharedRegion.setEntryMeta(0,
   111     *     { base: 0x80000000,
   112     *       len: 0x20000,
   113     *       ownerProcId: 0,
   114     *       isValid: true,
   115     *       cacheLineSize: 64,
   116     *       name: "DDR2",
   117     *     });
   118     *
   119     *  @p
   120     *
   121     *  The shared region table along with a shared region pointer (SRPtr)
   122     *  is used to do address translation at runtime. The shared region
   123     *  pointer is a 32-bit portable pointer composed of an id and offset.
   124     *  The most significant bits of a SRPtr are used for the id.
   125     *  The id corresponds to the index of the entry in the table.
   126     *  The offset is the offset from the base of the shared memory region.
   127     *  The number of entries in the table determines the number of bits to
   128     *  use for the id.  Increasing the number of entries increases the
   129     *  range of ids but decreases the range of the offset.
   130     *
   131     *  Note:  Region 0 must be visible by all processors.  Region 0 is used for
   132     *         synchonizing the processors, creating the default GateMP, and
   133     *         creating Notify and MessageQ transport instances.  The HeapMemMP
   134     *         created in Region 0 is the length of the region minus memory
   135     *         reserved for creating these internal instances.
   136     *
   137     *  Refer to the doxygen documentation for run-time API documenation.
   138     *
   139     */
   140    
   141    module SharedRegion
   142    {
   143        /*!
   144         *  ======== RegionView ========
   145         *  @_nodoc
   146         */
   147        metaonly struct RegionView {
   148            UInt16       id;
   149            String       base;
   150            String       end;
   151            String       len;
   152            UInt16       ownerProcId;
   153            Bool         cacheEnable;
   154            Bool         isValid;
   155            UInt16       cacheLineSize;
   156            SizeT        reservedSize;
   157            Ptr          heap;
   158            String       name;
   159        };
   160    
   161        /*!
   162         *  ======== rovViewInfo ========
   163         *  @_nodoc
   164         */
   165        @Facet
   166        metaonly config xdc.rov.ViewInfo.Instance rovViewInfo =
   167            xdc.rov.ViewInfo.create({
   168                viewMap: [
   169                    ['Regions',
   170                        {
   171                            type: xdc.rov.ViewInfo.MODULE_DATA,
   172                            viewInitFxn: 'viewInitRegions',
   173                            structName: 'RegionView'
   174                        }
   175                    ]
   176                ]
   177            });
   178    
   179        /*!
   180         *  Definition of shared region pointer type
   181         */
   182        typedef Bits32 SRPtr;
   183    
   184        /*!
   185         *  Assert raised when the id is larger than numEntries.
   186         */
   187        config xdc.runtime.Assert.Id A_idTooLarge =
   188            {msg: "A_idTooLarge: id cannot be larger than numEntries"};
   189    
   190        /*!
   191         *  Assert raised when an address is out of the range of the region id.
   192         */
   193        config xdc.runtime.Assert.Id A_addrOutOfRange =
   194            {msg: "A_addrOutOfRange: Address is out of region id's range"};
   195    
   196        /*!
   197         *  Assert raised when attempting to clear region 0
   198         */
   199        config xdc.runtime.Assert.Id A_region0Clear =
   200            {msg: "A_region0Clear: Region 0 cannot be cleared"};
   201    
   202        /*!
   203         *  Assert raised when region zero is invalid
   204         */
   205        config xdc.runtime.Assert.Id A_region0Invalid =
   206            {msg: "A_region0Invalid: Region zero is invalid"};
   207    
   208        /*!
   209         *  Assert raised when region is invalid
   210         */
   211        config xdc.runtime.Assert.Id A_regionInvalid =
   212            {msg: "A_regionInvalid: Region is invalid"};
   213    
   214        /*!
   215         *  Assert raised when the trying to reserve too much memory.
   216         */
   217        config xdc.runtime.Assert.Id A_reserveTooMuch =
   218            {msg: "A_reserveTooMuch: Trying to reserve too much memory"};
   219    
   220        /*!
   221         *  Assert raised when cache enabled but cache line size = 0.
   222         */
   223        config xdc.runtime.Assert.Id A_cacheLineSizeIsZero =
   224            {msg: "A_cacheLineSizeIsZero: cache line size cannot be zero"};
   225    
   226        /*!
   227         *  Assert raised when a new entry overlaps an existing one.
   228         */
   229        config xdc.runtime.Assert.Id A_overlap  =
   230            {msg: "A_overlap: Shared region overlaps"};
   231    
   232        /*!
   233         *  Assert raised when a valid table entry already exists.
   234         */
   235        config xdc.runtime.Assert.Id A_alreadyExists =
   236            {msg: "A_alreadyExists: Trying to overwrite an existing valid entry"};
   237    
   238        /*!
   239         *  Assert raised when trying to use a heap for a region that has no heap
   240         */
   241        config xdc.runtime.Assert.Id A_noHeap =
   242            {msg: "A_noHeap: Region has no heap"};
   243    
   244        /*!
   245         *  ======== Entry ========
   246         *  Structure for specifying a region.
   247         *
   248         *  Each region entry should not overlap with any other entry.  The
   249         *  length of a region should be the same across all processors.
   250         *
   251         *  During static configuration, the 'isValid' field can be set to 'false'
   252         *  to signify a partially completed entry.  This should only be done
   253         *  if the base address of the entry is not known during static
   254         *  configuration.  The entry can be completed and the
   255         *  'isValid' field can be set to true at runtime.
   256         *
   257         *  @field(base)          The base address.
   258         *  @field(len)           The length.
   259         *  @field(ownerProcId)   MultiProc id of processor that manages region.
   260         *  @field(isValid)       Whether the region is valid or not.
   261         *  @field(cacheEnable)   Whether the region is cacheable.
   262         *  @field(cacheLineSize) The cache line size for the region.
   263         *  @field(createHeap)    Whether a heap is created for the region.
   264         *  @field(name)          The name associated with the region.
   265         */
   266        struct Entry {
   267            Ptr    base;
   268            SizeT  len;
   269            UInt16 ownerProcId;
   270            Bool   isValid;
   271            Bool   cacheEnable;
   272            SizeT  cacheLineSize;
   273            Bool   createHeap;
   274            String name;
   275        };
   276    
   277        /*! Specifies the invalid id */
   278        const UInt16 INVALIDREGIONID = 0xFFFF;
   279    
   280        /*! Specifies the default owner proc id */
   281        const UInt16 DEFAULTOWNERID = ~0;
   282    
   283        /*!
   284         *  Worst-case cache line size
   285         *
   286         *  This is the default system cache line size for all modules.
   287         *  When a module puts structures in shared memory, this value is
   288         *  used to make sure items are aligned on a cache line boundary.
   289         *  If no cacheLineSize is specified for a region, it will use this
   290         *  value.
   291         */
   292        config SizeT cacheLineSize = 128;
   293    
   294        /*!
   295         *  The number of shared region table entries.
   296         *
   297         *  This value is used for calculating the number of bits for the offset.
   298         *  Note: This value must be the same across all processors in the system.
   299         *        Increasing this parameter will increase the footprint and
   300         *        the time for translating a pointer to a SRPtr.
   301         */
   302        config UInt16 numEntries = 4;
   303    
   304        /*!
   305         *  Determines whether address translation is required.
   306         *
   307         *  This configuration parameter should be set to 'false' if and only if all
   308         *  shared memory regions have the same base address for all processors.
   309         *  If 'false', it results in a fast {@link #getPtr} and {@link #getSRPtr},
   310         *  because a SRPtr is equivalent to a Ptr and no translation is done.
   311         */
   312        config Bool translate = true;
   313    
   314        /*! @_nodoc
   315         *  Value that corresponds to NULL in SRPtr address space.
   316         */
   317        config SRPtr INVALIDSRPTR = 0xFFFFFFFF;
   318    
   319        /*! @_nodoc
   320         *  ======== attach ========
   321         *  Opens a heap, for non-owner processors, for each SharedRegion.
   322         *
   323         *  Function is called in Ipc_attach().
   324         */
   325        Int attach(UInt16 remoteProcId);
   326    
   327        /*! @_nodoc
   328         *  ======== clearReservedMemory ========
   329         *  Clears the reserve memory for each region in the table.
   330         */
   331        Void clearReservedMemory();
   332    
   333        /*! @_nodoc
   334         *  ======== detach ========
   335         *  Close the heap, for non-owner processors when detaching from the owner.
   336         *
   337         *  Function is called in Ipc_detach().
   338         */
   339        Int detach(UInt16 remoteProcId);
   340    
   341        /*!
   342         *  ======== genSectionInCmd ========
   343         *  Enable/Disable generation of output section in linker cmd file
   344         *
   345         *  This function can be called for each shared region to not generate
   346         *  an output section in the linker command file.  By default all shared
   347         *  region entries generate an output section in the linker command file.
   348         *
   349         *  @param(id)          Region id.
   350         *  @param(gen)         TRUE - generate, FALSE - don't generate
   351         */
   352        metaonly Void genSectionInCmd(UInt16 id, Bool gen);
   353    
   354        /*!
   355         *  ======== getCacheLineSizeMeta ========
   356         *  Meta version of Ipc_getCacheLineSize
   357         */
   358        metaonly SizeT getCacheLineSizeMeta(UInt16 id);
   359    
   360        /*! @_nodoc
   361         *  ======== getIdMeta ========
   362         *  Returns the region id for a given local address
   363         *
   364         *  @param(addr)    Address to retrieve the shared region pointer.
   365         *
   366         *  @b(returns)     region id
   367         */
   368        metaonly UInt16 getIdMeta(Ptr addr);
   369    
   370        /*! @_nodoc
   371         *  ======== getPtrMeta ========
   372         *  Meta version of {@link #getPtr}
   373         */
   374        metaonly Ptr getPtrMeta(SRPtr srptr);
   375    
   376        /*! @_nodoc
   377         *  ======== getPtrMeta$view ========
   378         *  ROV-time version of getPtrMeta
   379         *
   380         *  @param(srptr)   Shared region pointer.
   381         *
   382         *  @b(returns)     Pointer associated with shared region pointer.
   383         */
   384        metaonly Ptr getPtrMeta$view(SRPtr srptr);
   385    
   386        /*! @_nodoc
   387         *  ======== getSRPtrMeta ========
   388         *  Meta version of {@link #getSRPtr}
   389         */
   390        metaonly SRPtr getSRPtrMeta(Ptr addr);
   391    
   392        /*! @_nodoc
   393         *  ======== getSRPtrMeta$view ========
   394         *  ROV-time version of getSRPtrMeta
   395         *
   396         *  @param(addr)    Address to retrieve the shared region pointer.
   397         *
   398         *  @b(returns)     Shared region pointer.
   399         */
   400        metaonly SRPtr getSRPtrMeta$view(Ptr addr);
   401    
   402        /*! @_nodoc
   403         *  ======== isCacheEnabledMeta ========
   404         *  Meta version of {@link #isCacheEnabled}
   405         */
   406        metaonly Bool isCacheEnabledMeta(UInt16 id);
   407    
   408        /*! @_nodoc
   409         *  ======== reserveMemory ========
   410         *  Reserves the specified amount of memory from the specified region id.
   411         *
   412         *  Must be called before Ipc_start().  The amount of memory reserved
   413         *  must be the same on all cores.
   414         *  The return pointer is the starting address that was reserved.
   415         *
   416         *  @param(id)      Region id.
   417         *  @param(size)    Amount of memory to reserve.
   418         *
   419         *  @b(returns)     Starting address of memory reserved.
   420         */
   421        Ptr reserveMemory(UInt16 id, SizeT size);
   422    
   423        /*! @_nodoc
   424         *  ======== resetInternalFields ========
   425         *  Reset the internal fields of a region.
   426         *
   427         *  This function is called in Ipc_stop() to reset the reservedSize
   428         *  and heap handle.  It should not be called by the user.
   429         *
   430         *  @param(id)      Region id.
   431         */
   432        Void resetInternalFields(UInt16 id);
   433    
   434        /*!
   435         *  ======== setEntryMeta ========
   436         *  Sets the entry at the specified region id in the shared region table.
   437         *
   438         *  The required parameters are base and len. All the other fields will
   439         *  get their default if not specified.
   440         *
   441         *  @param(id)          Region id.
   442         *  @param(entry)       Entry fields about the region.
   443         */
   444        metaonly Void setEntryMeta(UInt16 id, Entry entry);
   445    
   446        /*! @_nodoc
   447         *  ======== start ========
   448         *  Creates a heap by owner of region for each SharedRegion.
   449         *
   450         *  Function is called by Ipc_start().  Requires that SharedRegion 0
   451         *  be valid before calling start().
   452         */
   453        Int start();
   454    
   455        /*! @_nodoc
   456         *  ======== stop ========
   457         *  Undo what was done by start.
   458         *
   459         *  This function is called by Ipc_stop().  It deletes any heap that
   460         *  was created in start for the owner of any SharedRegion.  For
   461         *  non-owners, it doesn't do anything.
   462         */
   463        Int stop();
   464    
   465    
   466    internal:
   467    
   468        const UInt32 CREATED = 0x08111963;
   469    
   470        /* Information stored on a per region basis */
   471        struct Region {
   472            Entry        entry;
   473            SizeT        reservedSize;
   474            IHeap.Handle heap;
   475        };
   476    
   477        /* temporary storage of shared regions */
   478        metaonly config Entry entry[];
   479    
   480        /* generate linker section for shared regions */
   481        metaonly config Bool genSectionInLinkCmd[];
   482    
   483        /* internal to keep track of the number of entries added */
   484        metaonly config UInt entryCount;
   485    
   486        /* number of bits for the offset for a SRPtr. This value is calculated */
   487        config UInt32 numOffsetBits;
   488    
   489        /* offset bitmask using for generating a SRPtr */
   490        config UInt32 offsetMask;
   491    
   492        /*
   493         *  ======== checkOverlap ========
   494         *  Determines if there is an overlap with an existing entry
   495         *
   496         *  @param(base)    Base address of the region
   497         *  @param(len)     Size of the region
   498         *
   499         *  @b(returns)     Status if successful or not.
   500         */
   501        Int checkOverlap(Ptr base, SizeT len);
   502    
   503        /*
   504         *  ======== Module State structure ========
   505         *  The regions array contains information for each shared region entry.
   506         *  The size of the table will be determined by the number of entries.
   507         */
   508        struct Module_State {
   509            Region      regions[];
   510        };
   511    }