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