1    /*
     2     * Copyright (c) 2012, 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    /*
    34     *  ======== LoggerStopMode.xdc ========
    35     */
    36    import xdc.runtime.ITimestampClient;
    37    import xdc.runtime.IHeap;
    38    import xdc.runtime.Types;
    39    import xdc.runtime.Log;
    40    import xdc.runtime.ILogger;
    41    import xdc.runtime.Error;
    42    import xdc.runtime.Diags;
    43    import xdc.rov.ViewInfo;
    44    
    45    /*!
    46     *  ======== LoggerStopMode ========
    47     *  A logger which stores `Log` events in a non-blocking, streamable
    48     *  circular buffer.
    49     */
    50    
    51    @ModuleStartup      /* Initialize static instances */
    52    @InstanceFinalize   /* this mod has cleanup fxn when instances are deleted */
    53    @InstanceInitError  /* instance create can fail */
    54    module LoggerStopMode inherits ILoggerSnapshot
    55    {
    56        /*!
    57         *  @_nodoc
    58         *  ======== ModuleView ========
    59         */
    60        metaonly struct ModuleView {
    61            Bool       isTimestampEnabled;
    62            Bool       enableFlush;
    63            String     statusLogger;
    64            String     moduleIdToRouteToStatusLogger;
    65            //Diags.Mask level1Mask;
    66            //Diags.Mask level2Mask
    67            //Diags.Mask level3Mask
    68            //Diags.Mask level4Mask
    69        }
    70    
    71        /*!
    72         *  @_nodoc
    73         *  ======== InstanceView ========
    74         */
    75        metaonly struct InstanceView {
    76            String    label;
    77            Bool      enabled;
    78            SizeT     transferBufSize;
    79            SizeT     maxEventSize;
    80            Bits16    serial;
    81            Int       numCores;
    82            IUIATransfer.TransferType transferType;
    83            Bool      flush;
    84            Int       droppedEvents;
    85        }
    86    
    87        metaonly struct RecordView {
    88            Int     serial;
    89            Long    timestampRaw;
    90            String  modName;
    91            String  text;
    92            Int     eventId;
    93            String  eventName;
    94            IArg    arg0;
    95            IArg    arg1;
    96            IArg    arg2;
    97            IArg    arg3;
    98            IArg    arg4;
    99            IArg    arg5;
   100            IArg    arg6;
   101            IArg    arg7;
   102        }
   103    
   104        /*!
   105         *  @_nodoc
   106         *  ======== rovViewInfo ========
   107         */
   108        @Facet
   109        metaonly config ViewInfo.Instance rovViewInfo =
   110            ViewInfo.create({
   111                viewMap: [
   112                    ['Module',
   113                        {
   114                            type: ViewInfo.MODULE,
   115                            viewInitFxn: 'viewInitModule',
   116                            structName: 'ModuleView'
   117                        }
   118                    ],
   119                    ['Instances',
   120                        {
   121                            type: ViewInfo.INSTANCE,
   122                            viewInitFxn: 'viewInitInstances',
   123                            structName: 'InstanceView'
   124                        }
   125                    ],
   126                    ['Records',
   127                        {
   128                            type: xdc.rov.ViewInfo.INSTANCE_DATA,
   129                            viewInitFxn: 'viewInitRecords',
   130                            structName: 'RecordView'
   131                        }
   132                    ]
   133                ]
   134            });
   135    
   136        /*! Error raised if get or setFilterLevel receive a bad level value */
   137        config Error.Id E_badLevel =
   138            {msg: "E_badLevel: Bad filter level value: %d"};
   139    
   140        /*!
   141         *  ======== isTimestampEnabled ========
   142         *  Enable or disable logging the 64b local CPU timestamp
   143         *  at the start of each event
   144         */
   145        config Bool isTimestampEnabled = true;
   146    
   147        /*!
   148         *  ======== enableFlush ========
   149         *  Flush all logs at system exit
   150         */
   151        config Bool enableFlush = false;
   152    
   153       /*!
   154         *  ======== statusLogger ========
   155         *  Route all 'STATUS' (error and warning) events to this logger.
   156         *
   157         *  If a statusLogger is specified AND the filterByLevel is true,
   158         *  all LoggerStopMode instances will check to determine if any of the events
   159         *  they receive are errors or warnings (if their diags mask includes the
   160         *  STATUS category) or if the event is from the module specified by
   161         *  moduleIdToRouteToStatusLogger, and if so, will log these
   162         *  events to the statusLogger.
   163         *
   164         *  Error events are infrequent, but it's generally critical that they be
   165         *  seen. In a typical system, non-error events easily outnumber any error
   166         *  events, and the logger is likely to wrap, overwriting any error events.
   167         *  To protect these events from being overwritten and lost, they can be
   168         *  sent to their own separate logger to preserve them.
   169         *
   170         *  The default value is null, indicating that the STATUS events will just
   171         *  be logged by the logger they were sent to.
   172         */
   173        config xdc.runtime.IFilterLogger.Handle statusLogger = null;
   174    
   175       /*!
   176         *  ======== overflowLogger ========
   177         *  Route all events that cannot be stored in the main (transfer)
   178         *  event buffer to this logger
   179         *
   180         *  If an overflowLogger is specified and there is not enough room in the
   181         *  instance's buffer, the event will be passed to this logger instead.
   182         *
   183         *  The overflow Logger is intended to ensure that the last 'N' events
   184         *  leading up to a breakpoint are captured and are available for stop-mode
   185         *  debugging.  The overflow logger should be designed to automatically
   186         *  wrap, overwriting the oldest events and preserving the most recent
   187         *  events. An example is xdc.runtime.LoggerBuf.
   188         *
   189         *  The default value is null, indicating that overflow events that occur
   190         *  because the event transport is not fast enough to upload them will
   191         *  just be dropped.
   192         */
   193        config ILogger.Handle overflowLogger = null;
   194    
   195        /*!
   196         *  ======== level1Mask ========
   197         *  Mask of diags categories whose initial filtering level is Diags.LEVEL1
   198         *
   199         *  See '{@link #level4Mask}' for details.
   200         */
   201        config Diags.Mask level1Mask = 0;
   202    
   203        /*!
   204         *  ======== level2Mask ========
   205         *  Mask of diags categories whose initial filtering level is Diags.LEVEL2
   206         *
   207         *  See '{@link #level4Mask}' for details.
   208         */
   209        config Diags.Mask level2Mask = 0;
   210    
   211        /*!
   212         *  ======== level3Mask ========
   213         *  Mask of diags categories whose initial filtering level is Diags.LEVEL3
   214         *
   215         *  See '{@link #level4Mask}' for details.
   216         */
   217        config Diags.Mask level3Mask = 0;
   218    
   219        /*!
   220         *  ======== level4Mask ========
   221         *  Mask of diags categories whose initial filtering level is Diags.LEVEL4
   222         *
   223         *  If 'filterByLevel' is true, then all LoggerBuf instances will filter
   224         *  incoming events based on their event level.
   225         *
   226         *  The LoggerStopMode module allows for specifying a different filter level for
   227         *  every Diags bit. These filtering levels are module wide; LoggerBuf does
   228         *  not support specifying the levels on a per-instance basis.
   229         *
   230         *  The setFilterLevel API can be used to change the filtering levels at
   231         *  runtime.
   232         *
   233         *  The default filtering levels are assigned using the 'level1Mask' -
   234         *  'level4Mask' config parameters. These are used to specify, for each of
   235         *  the four event levels, the set of bits which should filter at that
   236         *  level by default.
   237         *
   238         *  The default filtering configuration sets the filter level to
   239         *  Diags.LEVEL4 for all logging-related diags bits so that all events are
   240         *  logged by default.
   241         */
   242        config Diags.Mask level4Mask = Diags.ALL_LOGGING;
   243    
   244        /*!
   245         *  ======== moduleToRouteToStatusLogger ========
   246         *  events from this module will be routed to the statusLogger (if configured)
   247         */
   248        metaonly config String moduleToRouteToStatusLogger;
   249    
   250        /*!
   251         *  ======== setModuleIdToRouteToStatusLogger ========
   252         *  Specifies which module to route events to the statusLogger for
   253         *
   254         *  @param(mid)    the module ID to route events for.  Set to -1 for 'none'
   255         */
   256        @DirectCall
   257        Void setModuleIdToRouteToStatusLogger(Types.ModuleId mid);
   258    
   259        /*!
   260         *  ======== flushAll ========
   261         *  Flush logs of all instances of `LoggerStopMode`
   262         *
   263         *  The user is responsible for making sure that no `LoggerStopMode`
   264         *  instances are created or deleted while in this API, by using an
   265         *  appropriate gate.
   266         */
   267        Void flushAll();
   268    
   269        /*!
   270         *  ======== flushAllInternal ========
   271         *  @_nodoc
   272         */
   273        @DirectCall
   274        Void flushAllInternal(Int stat);
   275    
   276        /*!
   277         * @_nodoc
   278         *  ======== initDecoder ========
   279         *  Initialize the Java LoggerStopModeDecoder for use in the LoggerStopMode
   280         *  'Records' ROV view.
   281         */
   282        function initDecoder();
   283    
   284    instance:
   285        /*!
   286         *  ======== create ========
   287         *  Create a `LoggerStopMode` logger
   288         *
   289         *  @see LoggerStopMode#Params
   290         */
   291        @DirectCall
   292        create();
   293    
   294        /*!
   295         *  ======== transferBufSize ========
   296         *  Number of minimum addressable units (e.g. bytes) in transfer buffer
   297         *
   298         *  The transfer buffer is used to store events that can be read by
   299         *  the transport.  Since the transport is typically bandwidth limited,
   300         *  it is possible to drop events if the buffer fills up before the
   301         *  event can be transmitted.  If this occurs and the
   302         *  `{@link #overflowLogger} is not null, the event will be written to
   303         *  the overflow buffer.
   304         */
   305        config SizeT transferBufSize = 512;
   306    
   307        /*!
   308         * ======== maxEventSize ========
   309         * The maximum event size (in Maus) that can be written with a single event.
   310         *
   311         * Determines the size of the area following the circular buffer
   312         * that is used to provide a linear copy space to speed up
   313         * copying data into the buffer in a circular manner.
   314         * Must be less than or equal to transferBufSize.
   315         */
   316        config SizeT maxEventSize = 128;
   317    
   318        /*!
   319         *  ======== exitFlush ========
   320         *  Flush log at system exit
   321         *
   322         *  Only used when module parameter `{@link #enableFlush}` is `true`.
   323         */
   324        config Bool exitFlush = true;
   325    
   326        /*!
   327         *  ======== bufSection ========
   328         *  Section name for the buffer managed by the static instance.
   329         *
   330         *  The default section is the 'dataMemory' in the platform.
   331         */
   332        metaonly config String bufSection = null;
   333    
   334        /*!
   335         *  ======== bufHeap ========
   336         *  The heap that contains the `Log` buffer for dynamic instances.
   337         *
   338         *  The default value `null` means the buffer will be allocated from
   339         *  the `{@link Memory#defaultHeapInstance}` heap.
   340         */
   341        config IHeap.Handle bufHeap = null;
   342    
   343        /*!
   344         *  ======== numCores ========
   345         *  Number of cores running the same image with an instance in shared memory
   346         *
   347         *  A common use case is to have the same binary image (e.g. .out file)
   348         *  run on multiple cores of multi-core device. This causes a problem if the
   349         *  logger's buffer is in shared memory (e.g. DDR). Since the image is the
   350         *  same for all the cores, each core will attempt to write to the same
   351         *  buffer in the shared memory. To avoid this, either the logger's buffers
   352         *  must be in non-shared memory or by setting the numCores parameter to
   353         *  the number of cores on the device.
   354         *
   355         *  Note: the `{@link #bufSection}` along with the Program.sectMap is how
   356         *  a logger instance's buffer is placed into specific memory.
   357         *
   358         *  Setting numCores to a value great than 1 signals LoggerStopMode to
   359         *  statically set aside additional memory ((x numCores) to allow each
   360         *  core to have `{@link #transferBufSize}` amount of memory.
   361         *
   362         *  Warning: setting this parameter to a value greater than one should only
   363         *  be done when there is a single image used on multiple cores of a
   364         *  multi-core device AND the logger instance's buffer is in shared memory.
   365         *  While functionally it will still work, memory will be wasted if both
   366         *  these conditions are not met.
   367         *
   368         *  The default is 1, which means do not reserve any additional memory
   369         *  for the logger.
   370         */
   371        config Int numCores = 1;
   372    
   373        /*!
   374         *  ======== flush ========
   375         *  Read, clear, and output the contents of the log
   376         *
   377         *  This method reads, clears, and "prints" each `Log` event (via
   378         *  `{@link System#printf}`) in the log.
   379         */
   380        @DirectCall
   381        Void flush();
   382    
   383        /*!
   384         *  ======== getNumDropped =========
   385         *  Returns the number of dropped events for this logger instance
   386         */
   387        @DirectCall
   388        Int getNumDropped();
   389    
   390        /*!
   391         *  ======== enable ========
   392         *  Enable a log
   393         *
   394         *  @a(returns)
   395         *  The function returns the state of the log (`TRUE` if enabled,
   396         *  `FALSE` if disabled) before the call. That allow clients to restore
   397         *  the previous state.
   398         */
   399        @DirectCall
   400        override Bool enable();
   401    
   402        /*!
   403         *  ======== disable ========
   404         *  Disable a log
   405         *
   406         *  Events written to a disabled log are silently discarded.
   407         *
   408         *  @a(returns)
   409         *  The function returns the state of the log (`TRUE` if enabled,
   410         *  `FALSE` if disabled) before the call. That allow clients to restore
   411         *  the previous state.
   412         */
   413        @DirectCall
   414        override Bool disable();
   415    
   416        /*!
   417         *  ======== write0 ========
   418         *  Process a log event with 0 arguments and the calling address.
   419         *
   420         *  Same as `write4` except with 0 arguments rather than 4.
   421         *  @see #write4()
   422         */
   423        @DirectCall
   424        override Void write0(Log.Event evt, Types.ModuleId mid);
   425    
   426        /*!
   427         *  ======== write1 ========
   428         *  Process a log event with 1 arguments and the calling address.
   429         *
   430         *  Same as `write4` except with 0 arguments rather than 4.
   431         *  @see #write4()
   432         */
   433        @DirectCall
   434        override Void write1(Log.Event evt, Types.ModuleId mid, IArg a1);
   435    
   436        /*!
   437         *  ======== write2 ========
   438         *  Process a log event with 2 arguments and the calling address.
   439         *
   440         *  Same as `write4` except with 2 arguments rather than 4.
   441         *
   442         *  @see #write4()
   443         */
   444        @DirectCall
   445        override Void write2(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2);
   446    
   447        /*!
   448         *  ======== write4 ========
   449         *  Process a log event with 4 arguments and the calling address.
   450         *
   451         *  @see ILogger#write4()
   452         */
   453        @DirectCall
   454        override Void write4(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
   455                             IArg a3, IArg a4);
   456    
   457        /*!
   458         *  ======== write8 ========
   459         *  Process a log event with 8 arguments and the calling address.
   460         *
   461         *  Same as `write4` except with 8 arguments rather than 4.
   462         *
   463         *  @see #write4()
   464         */
   465        @DirectCall
   466        override Void write8(Log.Event evt, Types.ModuleId mid, IArg a1, IArg a2,
   467                             IArg a3, IArg a4, IArg a5, IArg a6, IArg a7, IArg a8);
   468    
   469        /*!
   470         *  ======== setFilterLevel ========
   471         *  Sets the level of detail that instances will log.
   472         *
   473         *  Events with the specified level or higher will be logged, events
   474         *  below the specified level will be dropped.
   475         *
   476         *  Events are filtered first by diags category, then by level. If an
   477         *  event's diags category is disabled in the module's diags mask, then it
   478         *  will be filtered out regardless of level. The event will not even be
   479         *  passed to the logger.
   480         *
   481         *  This API allows for setting the filtering level for more than one
   482         *  diags category at a time. The mask parameter can be a single category
   483         *  or multiple categories combined, and the level will be set for all of
   484         *  those categories.
   485         *
   486         *  @param(mask) The diags categories to set the level for
   487         *  @param(filterLevel) The new filtering level for the specified
   488         *                      categories
   489         */
   490        @DirectCall
   491        override Void setFilterLevel(Diags.Mask mask, Diags.EventLevel filterLevel);
   492    
   493        /*!
   494         *  ======== getFilterLevel ========
   495         *  Returns the mask of diags categories currently set to the specified
   496         *  level.
   497         *
   498         *  See '{@link #setFilterLevel}' for an explanation of level filtering.
   499         */
   500        @DirectCall
   501        override Diags.Mask getFilterLevel(Diags.EventLevel level);
   502    
   503        /*!
   504         * ======== getFreeSize =========
   505         * Determines how much free space exist (in Maus)
   506         */
   507        @DirectCall
   508        SizeT getFreeSize();
   509    
   510        /*!
   511         * ======== getUnreadSize =========
   512         * Determines how much unread data exist (in Maus)
   513         */
   514        @DirectCall
   515        SizeT getUnreadSize();
   516    
   517    internal:
   518        /*!
   519         *  ======== readBlockOfMemory ========
   520         */
   521        @DirectCall
   522        Bool readBlockOfMemory(Handle obj, Ptr pMemBlock, SizeT sizeToRead);
   523    
   524        /*!
   525         *  ======== writeBlockOfMemory ========
   526         */
   527        @DirectCall
   528        Bool writeBlockOfMemory(Handle obj, Ptr newWrPtr, Ptr pMemBlock,
   529                                SizeT size);
   530    
   531        /*!
   532         *  ======== filterOutEvent ========
   533         */
   534        @DirectCall
   535        Bool filterOutEvent(Diags.Mask mask);
   536    
   537        struct Module_State {
   538            Diags.Mask level1;
   539            Diags.Mask level2;
   540            Diags.Mask level3;
   541            Types.ModuleId moduleIdToRouteToStatusLogger;
   542        };
   543    
   544        /*!
   545         *  @_nodoc
   546         * ======== postIncrementPtr =========
   547         * returns the buffer size in MAUs (min. addressable units)
   548         */
   549         @DirectCall
   550         Bits32 *postIncrementPtr(Object *obj, UArg *myRdPtr);
   551    
   552        struct Instance_State {
   553            QueueDescriptor.Header hdr;
   554            IHeap.Handle bufHeap;
   555            SizeT maxEventSizeInBits32;
   556            Bits16 serial;
   557            IUIATransfer.TransferType transferType;
   558            Bool enabled;
   559            Bool flush;
   560            Int  droppedEvents;
   561            Ptr  queueStartAdrs;  /* Replicates hdr.queueStartAdrs to reduce CPU overhead */
   562            SizeT  queueSizeInMAUs; /* Replicates hdr.queueSizeInMAUs to reduce CPU overhead */
   563            Ptr  endOfBufferAdrsPlus1; /* pre-calculate the end address to reduce CPU overhead.
   564                                          = (Bits32)obj->queueStartAdrs + obj->queueSizeInMAUs */
   565            Char bufferArray[];
   566            Int numCores;
   567        };
   568    }