1    /*
     2     * Copyright (c) 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    
    34    
    35    /*
    36     *  ======== LoggerStreamer2.xdc ========
    37     */
    38    import xdc.runtime.ILogger;
    39    import ti.uia.runtime.ILoggerSnapshot;
    40    import xdc.rov.ViewInfo;
    41    import xdc.runtime.Log;
    42    import xdc.runtime.Diags;
    43    import xdc.runtime.Types;
    44    import xdc.runtime.Log;
    45    import xdc.runtime.Error;
    46    
    47    /*!
    48     *  ======== LoggerStreamer2 ========
    49     *  This general purpose logger is useful in situations where the application
    50     *  wants to manage the buffers used to store and transmit events. This
    51     *  includes managing the sending of the buffers to an instrumentation host
    52     *  (e.g. System Analyzer in CCS).  The logger is named "LoggerStreamer2"
    53     *  because it is designed to enable the application to send a stream of
    54     *  packets containing UIA event data to the instrumentation host, and it is
    55     *  an enhancement of LoggerStreamer, allowing multiple instances.
    56     *
    57     *  The difference between LoggerStreamer2 and LoggerStreamer, is that each
    58     *  LoggerStreamer2 instance has its own buffers for events logged to that
    59     *  instance. By including the header file, ti/uia/runtime/LogUC.h, you
    60     *  can specify the LoggerStreamer2 instance that you want the event logged
    61     *  to.
    62     *
    63     *  The application is responsible for providing the buffers that
    64     *  LoggerStreamer2 loggers use. There are two ways to accomplish this.
    65     *  @p(blist)
    66     *      - Provide a prime callback function via the `{@link #primeFxn}`
    67     *        configuration parameter.
    68     *      - Call the `{@link #prime}` API once.
    69     *  @p
    70     *
    71     *  The logger stores the events in a UIAPacket event packet structure that
    72     *  allows them to be sent directly to System Analyzer (e.g. via UDP), enabling
    73     *  efficient streaming of the data from the target to the host.  The first
    74     *  four 32-bit words contain a `{@link UIAPacket#Hdr}` structure. This struct
    75     *  is used by the host (e.g. System Analyzer in CCS) to help decode the
    76     *  data (e.g. endianess, length of data, etc.). The `{@link UIAPacket#Hdr}`
    77     *  structure is initialized via the `{@link #initBuffer}` API. All buffers
    78     *  given to LoggerStreamer2 loggers (via priming or exchange) must be
    79     *  initialized via `{@link #initBuffer}`.
    80     *
    81     *  The size of the buffer includes the UIAPacket_Hdr.
    82     *  LoggerStreamer2 treats the buffer as a UInt32 array, so the application
    83     *  must guarantee the buffers are aligned on word addresses.  Alignment on
    84     *  cache line boundaries is recommended for best performance.
    85     *
    86     *  When the buffer is filled, LoggerStreamer2 will hand it off to the
    87     *  application using an application-provided exchange function (`{@link #exchangeFxn}`).
    88     *  The exchange function must be of type `{@link #ExchangeFxnType}`.  The
    89     *  exchange function takes the Log instance as a parameter.
    90     *
    91     *  The exchange function is called within the context of a Log call, so the
    92     *  exchange function should be designed to be fast. Since the exchange
    93     *  function is called within the context of the Log call, LoggerStreamer2
    94     *  guarantees no Log records are dropped (i.e. LoggerStreamer2 is lossless).
    95     *
    96     *  LoggerStreamer2 was designed to have as minimal impact as possible on an
    97     *  application  when calling a Log function. There are several configuration
    98     *  parameters that allow an application to get the optimal performance in
    99     *  exchange for certain restrictions.
   100     *
   101     *  Interrupts are disabled during the duration of the log call including
   102     *  when the exchange function is called. LoggerStreamer2 will ignore any
   103     *  log events generated during the exchangeFxn (e.g. posting a semaphore).
   104     *
   105     *  NOTE:  You can use LoggingSetup, but you will need to set the loggers
   106     *  first.  LoggingSetup cannot create LoggerStreamer2 instances, since it
   107     *  does not know what config parameters to use.  See example of LoggingSetup
   108     *  use below.
   109     *
   110     *  @a(Examples)
   111     *  The following XDC configuration statements
   112     *  create a logger module, and assign it as the default logger for all
   113     *  modules.
   114     *
   115     *  @p(code)
   116     *  var Defaults = xdc.useModule('xdc.runtime.Defaults');
   117     *  var Diags = xdc.useModule('xdc.runtime.Diags');
   118     *  var LoggerStreamer2 = xdc.useModule('ti.uia.sysbios.LoggerStreamer2');
   119     *
   120     *  LoggerStreamer2.isTimestampEnabled = true;
   121     *
   122     *  var loggerParams = new LoggerStreamer2.Params();
   123     *  loggerParams.primeFxn = '&prime';
   124     *  loggerParams.exchangeFxn = '&exchange';
   125     *  loggerParams.context = 0;
   126     *
   127     *  Program.global.logger0 = LoggerStreamer2.create(loggerParams);
   128     *  Defaults.common$.logger = Program.global.logger0;
   129     *
   130     *  loggerParams.context = 1;
   131     *  Program.global.logger1 = LoggerStreamer2.create(loggerParams);
   132     *
   133     *  @p
   134     *
   135     *  @a(Examples)
   136     *  The following C code demonstrates basic prime and exchange functions,
   137     *  and logging to different LoggerStreamer2 instances.
   138     *  A real implementation would send the buffer to an instrumentation
   139     *  host (e.g. System Analyzer in CCS) via a transport such as UDP.
   140     *
   141     *  @p(code)
   142     *  #include <xdc/std.h>
   143     *  #include <xdc/runtime/Diags.h>
   144     *  #include <xdc/runtime/Log.h>
   145     *
   146     *  #include <ti/uia/runtime/LogUC.h>
   147     *
   148     *  UInt32 buffer_0[2][BUFSIZE_0];
   149     *  UInt32 buffer_1[2][BUFSIZE_1];
   150     *
   151     *  Int main(Int argc, String argv[])
   152     *  {
   153     *      Log_iwriteUC0(logger0, LoggerStreamer2_L_test);
   154     *      Log_iwriteUC1(logger1, LoggerStreamer2_L_test, 0x1000);
   155     *  }
   156     *
   157     *  Ptr prime(LoggerStreamer2_Object *log)
   158     *  {
   159     *      UInt32 id = (UInt32)LoggerStreamer2_getContext(log);
   160     *
   161     *      if (id == 0) {
   162     *          LoggerStreamer2_initBuffer(buffer_0[0], 0);
   163     *          LoggerStreamer2_initBuffer(buffer_0[1], 0);
   164     *          return ((Ptr)buffer_0[0]);
   165     *      }
   166     *      if (id == 1) {
   167     *          LoggerStreamer2_initBuffer(buffer_1[0], 0);
   168     *          LoggerStreamer2_initBuffer(buffer_1[1], 0);
   169     *          return ((Ptr)(buffer_1[0]));
   170     *      }
   171     *
   172     *      return (NULL); // Error
   173     *  }
   174     *
   175     *  Ptr exchange(LoggerStreamer2_Object *log, Ptr *full)
   176     *  {
   177     *      UInt32 id = (UInt32)LoggerStreamer2_getContext(log);
   178     *
   179     *      if (id == 0) {
   180     *          count_0++;
   181     *          // Ping-pong between the two buffers
   182     *          return ((Ptr*)buffer_0[count_0 & 1]);
   183     *      }
   184     *      if (id == 1) {
   185     *          count_1++;
   186     *          // Ping-pong between the two buffers
   187     *          return ((Ptr*)buffer_1[count_1 & 1]);
   188     *      }
   189     *      return (NULL);  // Error
   190     *  }
   191     *  @p
   192     *
   193     *  @a(Examples)
   194     *  The following XDC configuration statements show how to use LoggingSetup
   195     *  with LoggerStreamer2.
   196     *
   197     *  @p(code)
   198     *
   199     *  var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
   200     *  LoggingSetup.eventUploadMode = LoggingSetup.UploadMode_STREAMER2;
   201     *  LoggingSetup.mainLogger = Program.global.logger0;
   202     *  LoggingSetup.sysbiosLogger = Program.global.logger0;
   203     *
   204     *  @p
   205     */
   206    
   207    @ModuleStartup
   208    @Template("./LoggerStreamer2.xdt")
   209    @CustomHeader
   210    module LoggerStreamer2 inherits ILoggerSnapshot {
   211    
   212        /*!
   213         *  ======== TransportType ========
   214         *  Used to specify the type of transport to use
   215         *
   216         *  This enum is used by the instrumentation host to determine what
   217         *  the transport is. It is not used by the target code.
   218         */
   219        enum TransportType {
   220            TransportType_UART = 0,
   221            TransportType_USB = 1,
   222            TransportType_ETHERNET = 2,
   223            TransportType_CUSTOM = 3
   224        };
   225    
   226        /*!
   227         *  @_nodoc
   228         *  ======== ModuleView ========
   229         */
   230        metaonly struct ModuleView {
   231            Bool       isEnabled;
   232            Bool       isTimestampEnabled;
   233            String     transportType;
   234            String     customTransport;
   235        }
   236    
   237        /*!
   238         *  @_nodoc
   239         *  ======== InstanceView ========
   240         */
   241        metaonly struct InstanceView {
   242            String    label;
   243            Bool      enabled;
   244            Int       bufferSize;
   245            String    primeFunc;
   246            String    exchangeFunc;
   247            SizeT     maxEventSize;
   248            UArg      context;
   249        }
   250    
   251        metaonly struct RecordView {
   252            Int     sequence;
   253            Long    timestampRaw;
   254            String  modName;
   255            String  text;
   256            Int     eventId;
   257            String  eventName;
   258            IArg    arg0;
   259            IArg    arg1;
   260            IArg    arg2;
   261            IArg    arg3;
   262            IArg    arg4;
   263            IArg    arg5;
   264            IArg    arg6;
   265            IArg    arg7;
   266        }
   267    
   268        /*!
   269         *  @_nodoc
   270         *  ======== rovViewInfo ========
   271         */
   272        @Facet
   273        metaonly config ViewInfo.Instance rovViewInfo =
   274            ViewInfo.create({
   275                viewMap: [
   276                    ['Module',
   277                        {
   278                            type: ViewInfo.MODULE,
   279                            viewInitFxn: 'viewInitModule',
   280                            structName: 'ModuleView'
   281                        }
   282                    ],
   283                    ['Instances',
   284                        {
   285                            type: ViewInfo.INSTANCE,
   286                            viewInitFxn: 'viewInitInstances',
   287                            structName: 'InstanceView'
   288                        }
   289                    ],
   290                    ['Records',
   291                        {
   292                            type: xdc.rov.ViewInfo.MODULE_DATA,
   293                            viewInitFxn: 'viewInitRecords',
   294                            structName: 'RecordView'
   295                        }
   296                    ]
   297                ]
   298            });
   299    
   300        /*!
   301         *  ======== RtaData ========
   302         *  Data added to the RTA MetaData file to support System Analyzer
   303         */
   304        @XmlDtd metaonly struct RtaData {
   305            Int instanceId;
   306        }
   307    
   308        /*!
   309         *  ======== ExchangeFxnType ========
   310         *  Typedef for the exchange function pointer.
   311         *  The LoggerStreamer2 object and a pointer to the full
   312         *  buffer are passed as arguments.  If using the same exchange function
   313         *  for multiple LoggerStreamer2 instances, getContext() can be
   314         *  called within the exchange function to determine which buffer to
   315         *  exchange.
   316         */
   317        typedef Ptr (*ExchangeFxnType)(Object *, Ptr);
   318    
   319        /*!
   320         *  ======== PrimeFxnType ========
   321         *  Typedef for the exchange function pointer.
   322         */
   323        typedef Ptr (*PrimeFxnType)(Object *);
   324    
   325        /*!
   326         *  ======== transportType ========
   327         *  Transport used to send the records to an instrumentation host
   328         *
   329         *  This parameter is used to specify the transport that the
   330         *  `{@link #exchangeFxn}` function will use to send the buffer to
   331         *  an instrumentation host (e.g. System Analyzer in CCS).
   332         *
   333         *  This parameter is placed into the generated UIA XML file. The
   334         *  instrumentation host can use the XML file to help it auto-detect as
   335         *  much as possible and act accordingly.
   336         *
   337         *  If the desired transport is not in the `{@link #TransportType}` enum,
   338         *  select `{@link #TransportType_CUSTOM}` and set the
   339         *  `{@link #customTransportType}` string with the desired string.
   340         */
   341        metaonly config TransportType transportType = TransportType_ETHERNET;
   342    
   343        /*!
   344         *  ======== customTransportType ========
   345         *  Custom transport used to send the records to an instrumentation host
   346         *
   347         *  If the desired transport is not in the `{@link #TransportType}` enum,
   348         *  and `{@link #transportType}` is set to `{@link #TransportType_CUSTOM}`,
   349         *  this parameter must be filled in with the correct transport name.
   350         *
   351         *  If `{@link #transportType}` is NOT set to
   352         *  `{@link #TransportType_CUSTOM}`, this parameter is ignored.
   353         */
   354        config String customTransportType = null;
   355    
   356        /*!
   357         *  ======== isTimestampEnabled ========
   358         *  Enable or disable logging the 64b local CPU timestamp
   359         *  at the start of each event
   360         *
   361         *  Having a timestamp allows an instrumentation host (e.g.
   362         *  System Analyzer) to display events with the correct system time.
   363         */
   364        config Bool isTimestampEnabled = false;
   365    
   366        /*!
   367         * @_nodoc
   368         *  ======== isBadPacketDetectionEnabled ========
   369         *  Enable or disable checking that the event contents in the packet are
   370         *  properly formatted with no data errors
   371         *
   372         *  If enabled, a breakpoint can be placed in the code to detect when
   373         *  a bad packet is found.
   374         */
   375        config Bool isBadPacketDetectionEnabled = false;
   376    
   377        /*!
   378         *  ======== supportLoggerDisable ========
   379         *  Allow LoggerStreamer2 instances to be enabled/disabled during runtime.
   380         */
   381        config Bool supportLoggerDisable = false;
   382    
   383        /*!
   384         *  ======== testForNullWrPtr ========
   385         *  Protect against log calls during the exchange function.
   386         */
   387        config Bool testForNullWrPtr = true;
   388    
   389        /*!
   390         *  ======== statusLogger ========
   391         *  This configuration option is not supported by this logger and should
   392         *  be left null.
   393         */
   394        config xdc.runtime.IFilterLogger.Handle statusLogger = null;
   395    
   396        /*!
   397         *  ======== level1Mask ========
   398         *  Mask of diags categories whose initial filtering level is Diags.LEVEL1
   399         *
   400         *  See '{@link #level4Mask}' for details.
   401         */
   402        config Diags.Mask level1Mask = 0;
   403    
   404        /*!
   405         *  ======== level2Mask ========
   406         *  Mask of diags categories whose initial filtering level is Diags.LEVEL2
   407         *
   408         *  See '{@link #level4Mask}' for details.
   409         */
   410        config Diags.Mask level2Mask = 0;
   411    
   412        /*!
   413         *  ======== level3Mask ========
   414         *  Mask of diags categories whose initial filtering level is Diags.LEVEL3
   415         *
   416         *  See '{@link #level4Mask}' for details.
   417         */
   418        config Diags.Mask level3Mask = 0;
   419    
   420        /*!
   421         *  ======== level4Mask ========
   422         *  Mask of diags categories whose initial filtering level is Diags.LEVEL4
   423         *
   424         *  If 'filterByLevel' is true, then all LoggerBuf instances will filter
   425         *  incoming events based on their event level.
   426         *
   427         *  The LoggerCircBuf module allows for specifying a different filter level
   428         *  for every Diags bit. These filtering levels are module wide; LoggerBuf
   429         *  does not support specifying the levels on a per-instance basis.
   430         *
   431         *  The setFilterLevel API can be used to change the filtering levels at
   432         *  runtime.
   433         *
   434         *  The default filtering levels are assigned using the 'level1Mask' -
   435         *  'level4Mask' config parameters. These are used to specify, for each of
   436         *  the four event levels, the set of bits which should filter at that
   437         *  level by default.
   438         *
   439         *  The default filtering configuration sets the filter level to
   440         *  Diags.LEVEL4 for all logging-related diags bits so that all events are
   441         *  logged by default.
   442         */
   443        config Diags.Mask level4Mask = Diags.ALL_LOGGING;
   444    
   445        /*!
   446         *  ======== moduleToRouteToStatusLogger ========
   447         *  This configuration option is not supported by this logger and should
   448         *  be left unconfigured.
   449         */
   450        metaonly config String moduleToRouteToStatusLogger;
   451    
   452        /*!
   453         *  ======== setModuleIdToRouteToStatusLogger ========
   454         *  This function is provided for compatibility with the ILoggerSnapshot
   455         *  interface only and simply returns when called.
   456         */
   457        @DirectCall
   458        Void setModuleIdToRouteToStatusLogger(Types.ModuleId mid);
   459    
   460        /*!
   461         * @_nodoc
   462         *  ======== L_test ========
   463         *  Event used to benchmark write0.
   464         */
   465        config xdc.runtime.Log.Event L_test = {
   466            mask: xdc.runtime.Diags.USER1,
   467            msg: "Test"
   468        };
   469    
   470        /*!
   471         * @_nodoc
   472         *  ======== E_badLevel ========
   473         *  Error raised if get or setFilterLevel receive a bad level value
   474         */
   475        config Error.Id E_badLevel = {
   476             msg: "E_badLevel: Bad filter level value: %d"
   477        };
   478    
   479        /*!
   480         *  ======== A_invalidBuffer ========
   481         *  Assert raised when the buffer parameter is NULL
   482         */
   483        config xdc.runtime.Assert.Id A_invalidBuffer =
   484            {msg: "LoggerStreamer2_create's buffer returned by primeFxn is NULL"};
   485    
   486    instance:
   487    
   488        /*!
   489         *  ======== create ========
   490         *  Create a `LoggerStreamer2` logger
   491         */
   492        create();
   493    
   494        /*!
   495         *  ======== initBuffer ========
   496         *  Initializes the UIA packet header.
   497         *
   498         *  This API is used to initialize a buffer before it is given to
   499         *  LoggerStreamer2 (via priming or exchange). The function initializes
   500         *  the UIAPacket portion of the buffer.
   501         *
   502         *  @param(buffer)    Pointer to the buffer that LoggerStreamer2 will
   503         *                    fill with Log events. The first four 32-bit words
   504         *                    will contain the UIAPacket_Hdr structure.
   505         *
   506         *  @param(src)       Used to initialize the UIA source address. For
   507         *                    a single core device, this will generally be 0.
   508         *                    For multi-core devices, it generally corresponds
   509         *                    to the DNUM (on C6xxxx deviecs) or the Ipc
   510         *                    MultiProc id. It must be unique for all cores and
   511         *                    match the configuration in the System Analyzer
   512         *                    endpoint configuration.
   513         */
   514        Void initBuffer(Ptr buffer, UInt16 src);
   515    
   516        /*!
   517         *  ======== flush ========
   518         *  Force LoggerStreamer2 to call the exchange function
   519         *
   520         *  This API makes LoggerStreamer2 call the application provided
   521         *  `{@link #exchangeFxn}` function if there are Log events present
   522         *  in the buffer.
   523         *
   524         *  The call to the `{@link #exchangeFxn}` function is called in the
   525         *  context of the flush call.
   526         */
   527         Void flush();
   528    
   529         /*!
   530          *  ======== prime =========
   531          *  If PrimeFxn is not set the user must call prime with the first buffer.
   532          */
   533         Bool prime(Ptr buffer);
   534    
   535        /*!
   536         * @_nodoc
   537         *  ======== validatePacket ========
   538         *  if isBadPacketDetectionEnabled is configured as true, this function is
   539         *  called prior to the exchange function being called.
   540         *
   541         *  Returns null if the packet is ok, else returns the address of a string
   542         *  that describes the error.
   543         */
   544        @DirectCall
   545        Char* validatePacket(UInt32 *writePtr, UInt32 numBytesInPacket);
   546    
   547        /*!
   548         *  ======== context ========
   549         *  Context that can be used in exchangeFxn and primeFxn.  This can be
   550         *  set to null if using a different exchangeFxn and primeFxn for each
   551         *  LoggerStreamer2 instance.  The context can be changed at run-time
   552         *  via setContext().
   553         */
   554        config UArg context = null;
   555    
   556        /*!
   557         *  ======== primeFxn ========
   558         *  Function pointer to the prime function.
   559         */
   560        config PrimeFxnType primeFxn = null;
   561    
   562        /*!
   563         *  ======== exchangeFxn ========
   564         *  Function pointer to the exchange function.
   565         *
   566         *  The exchange function must return a pointer to a buffer that is word
   567         *  aligned, initialized with a UIA header and the correct size.  This is
   568         *  called in the context of a log so generally the exchange function
   569         *  should be quick to execute.
   570         */
   571        config ExchangeFxnType exchangeFxn = null;
   572    
   573        /*!
   574         *  ======== instanceId ========
   575         *  Unique id of the LoggerStreamer2 instance.
   576         */
   577        config Int16 instanceId = 1;
   578    
   579         /*!
   580         *  ======== maxEventSize ========
   581         *  The maximum event size (in Maus) that can be written with a single
   582         *  event. Must be less than or equal to bufSize - 64.
   583         *
   584         *  The writeMemoryRange API checks to see if the event size required to
   585         *  write the block of memory is larger than maxEventSize.  If so, it will
   586         *  split the memory range up into a number of smaller blocks and log the
   587         *  blocks using separate events with a common snapshot ID in order to
   588         *  allow the events to be collated and the original memory block to be
   589         *  reconstructed on the host.
   590         */
   591        config SizeT maxEventSize = 512;
   592    
   593        /*!
   594         *  ======== bufSize ========
   595         *  LoggerStreamer2 instance's buffer size in MAUs (Minimum Addressable
   596         *  Units e.g. Bytes)
   597         *
   598         *  NOTE: the buffer size must contain an integer number of 32b words
   599         *  (e.g. if a MAU = 1 byte, then the buffer size must be a multiple of 4).
   600         *  The buffer size must also be at least maxEventSize + 64.
   601         */
   602        config SizeT bufSize = 1400;
   603    
   604        /*!
   605         *  ======== write0 ========
   606         *  Process a log event with 0 arguments and the calling address.
   607         *
   608         *  Same as `write4` except with 0 arguments rather than 4.
   609         *  @see #write4()
   610         */
   611        @DirectCall
   612        override Void write0(xdc.runtime.Log.Event evt,
   613                    xdc.runtime.Types.ModuleId mid);
   614    
   615        /*!
   616         *  ======== write1 ========
   617         *  Process a log event with 1 arguments and the calling address.
   618         *
   619         *  Same as `write4` except with 1 arguments rather than 4.
   620         *  @see #write4()
   621         */
   622        @DirectCall
   623        override Void write1(xdc.runtime.Log.Event evt,
   624                    xdc.runtime.Types.ModuleId mid,
   625                    IArg a1);
   626    
   627        /*!
   628         *  ======== write2 ========
   629         *  Process a log event with 2 arguments and the calling address.
   630         *
   631         *  Same as `write4` except with 2 arguments rather than 4.
   632         *  @see #write4()
   633         */
   634        @DirectCall
   635        override Void write2(xdc.runtime.Log.Event evt,
   636                    xdc.runtime.Types.ModuleId mid,
   637                    IArg a1, IArg a2);
   638    
   639        /*!
   640         *  ======== write4 ========
   641         *  Process a log event with 4 arguments and the calling address.
   642         *
   643         *  @see ILogger#write4()
   644         */@DirectCall
   645        override Void write4(xdc.runtime.Log.Event evt,
   646                    xdc.runtime.Types.ModuleId mid,
   647                    IArg a1, IArg a2, IArg a3, IArg a4);
   648    
   649        /*!
   650         *  ======== write8 ========
   651         *  Process a log event with 8 arguments and the calling address.
   652         *
   653         *  Same as `write4` except with 8 arguments rather than 4.
   654         *
   655         *  @see #write4()
   656         */
   657        @DirectCall
   658        override Void write8(xdc.runtime.Log.Event evt,
   659                    xdc.runtime.Types.ModuleId mid,
   660                    IArg a1, IArg a2, IArg a3, IArg a4,
   661                    IArg a5, IArg a6, IArg a7, IArg a8);
   662    
   663        /*!
   664         *  ======== setFilterLevel ========
   665         *  Sets the level of detail that instances will log.
   666         *
   667         *  Events with the specified level or higher will be logged, events
   668         *  below the specified level will be dropped.
   669         *
   670         *  Events are filtered first by diags category, then by level. If an
   671         *  event's diags category is disabled in the module's diags mask, then it
   672         *  will be filtered out regardless of level. The event will not even be
   673         *  passed to the logger.
   674         *
   675         *  This API allows for setting the filtering level for more than one
   676         *  diags category at a time. The mask parameter can be a single category
   677         *  or multiple categories combined, and the level will be set for all of
   678         *  those categories.
   679         *
   680         *  @param(mask) The diags categories to set the level for
   681         *  @param(filterLevel) The new filtering level for the specified
   682         *                      categories
   683         */
   684        @DirectCall
   685        override Void setFilterLevel(Diags.Mask mask, Diags.EventLevel filterLevel);
   686    
   687        /*!
   688         *  ======== getFilterLevel ========
   689         *  Returns the mask of diags categories currently set to the specified
   690         *  level.
   691         *
   692         *  See '{@link #setFilterLevel}' for an explanation of level filtering.
   693         */
   694        @DirectCall
   695        override Diags.Mask getFilterLevel(Diags.EventLevel level);
   696    
   697        /*!
   698         *  ======== getBufSize ========
   699         *  Returns the Log's configured buffer size.
   700         *
   701         *  @b(returns)     Log's configured buffer size.
   702         */
   703        @DirectCall
   704        SizeT getBufSize();
   705    
   706        /*!
   707         *  ======== getContext ========
   708         *  Returns the Log's context
   709         *
   710         *  @b(returns)     context
   711         */
   712        @DirectCall
   713        UArg getContext();
   714    
   715        /*!
   716         *  ======== setContext ========
   717         *  Set the Log's context.
   718         *
   719         *  @param(context)     New value of Log's context
   720         */
   721        @DirectCall
   722        Void setContext(UArg context);
   723    
   724    internal:
   725        metaonly config Int maxId = 0;
   726    
   727        /* Write size in bytes for generating event length */
   728        const Int WRITE0_SIZE_IN_BYTES = 8;
   729        const Int WRITE1_SIZE_IN_BYTES = 12;
   730        const Int WRITE2_SIZE_IN_BYTES = 16;
   731        const Int WRITE4_SIZE_IN_BYTES = 24;
   732        const Int WRITE8_SIZE_IN_BYTES = 40;
   733        /* Bytes added for timestamps; used for generating event length in bytes */
   734        const Int TIMESTAMP = 8;
   735        const Int NO_TIMESTAMP = 0;
   736    
   737        /*!
   738         *  ======== filterOutEvent ========
   739         */
   740        @DirectCall
   741        Bool filterOutEvent(Diags.Mask mask);
   742    
   743        /*
   744         *  Interesting...I moved the enabled field to the end and performance
   745         *  in the exchange case was slower by 4 cycles...
   746         */
   747        struct Module_State {
   748            Bool        enabled;       /* Enabled state */
   749            Diags.Mask level1;
   750            Diags.Mask level2;
   751            Diags.Mask level3;
   752            Types.ModuleId moduleIdToRouteToStatusLogger;
   753        };
   754    
   755        struct Instance_State {
   756            Bool        enabled;       /* Enabled state */
   757            Int16       instanceId;
   758            PrimeFxnType    primeFxn;
   759            ExchangeFxnType exchangeFxn;
   760            UArg        context;
   761            Bool        primeStatus;   /* Has the Log been primed? */
   762            UInt32      bufSize;       /* Size of the buffer */
   763            UInt32      *buffer;       /* Ptr to buffer */
   764            UInt32      *write;        /* Ptr to write location */
   765            UInt32      *end;
   766            SizeT       maxEventSizeInBits32; /* Max event size in 32 bit words */
   767            SizeT       maxEventSize;  /* Max event size in target MAUs */
   768    
   769            /*
   770             *  incremented by writeMemoryRange when event is too big to log or
   771             *  no buffers available
   772             */
   773            Int  droppedEvents;
   774            UInt16      seqNumber;
   775        };
   776    }