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