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     *  ======== GateDualCore.xdc ========
    34     *
    35     */
    36    package ti.sysbios.family.arm.ducati;
    37    
    38    import xdc.rov.ViewInfo;
    39    
    40    import xdc.runtime.Assert;
    41    import xdc.runtime.Error;
    42    
    43    /*!
    44     *  ======== GateDualCore ========
    45     *  A Gate for use by the two Ducati M3 cores to manage shared resources.
    46     *
    47     *  GateDualCore uses disabling and enabling of interrupts as well as a shared
    48     *  variable between the two M3 cores as the resource locking
    49     *  mechanism. Such a gate guarantees exclusive access to a resource
    50     *  shared between the cores.
    51     *
    52     *  Each gate consumes one 32 bit word of shared memory.
    53     *  An array of these gates is shared between the two M3 cores and
    54     *  therefore the address of this array must be known to both (see
    55     *  {@link #gateArrayAddress}).
    56     *
    57     *  By default, the array has 4 entries (see {@link #numGates})
    58     *  and is placed immediately below Core 0's default interrupt
    59     *  vector table address. It is the responsibility of the user to
    60     *  configure both cores with the same array address and size.
    61     *
    62     *  @a(Restrictions)
    63     *  In a dual core M3 (Ducati) environment, core 0 is responsible
    64     *  for initializing the shared gate variable, therefore core 0
    65     *  must be brought up BEFORE core 1 invokes GateDualCore_enter().
    66     *  This can be achieved by simply running core 0 to its main()
    67     *  function prior to loading and running core 1.
    68     *
    69     *  GateDualCore does not support nesting of {@link #enter}/{@link #leave}
    70     *  calls.
    71     *
    72     *  Global interrupts are disabled upon return from GateDualCore_enter().
    73     *  The duration between the enter and leave should be as short as possible
    74     *  to minimize Hwi latency and stalls by the other M3 core.
    75     *
    76     *  Gate zero (0) is reserved for the {@link ti.sysbios.hal.unicache.Cache}
    77     *  module and is internally configured for its use.
    78     *  @a
    79     */
    80    
    81    @Template("./GateDualCore.xdt")  /* generates gateArray */
    82    @ModuleStartup      /* generate a call to startup function */
    83    @InstanceInitError  /* create requires EB */
    84    
    85    module GateDualCore inherits xdc.runtime.IGateProvider
    86    {
    87    
    88        /*! @_nodoc */
    89        metaonly struct BasicView {
    90            String      label;
    91            UInt        index;
    92            String      owner;
    93            String      gateValue;
    94            UInt        stalls;
    95            UInt        noStalls;
    96            UInt        totalStalls;
    97            UInt        maxStall;
    98        };
    99    
   100        @Facet
   101        metaonly config ViewInfo.Instance rovViewInfo =
   102            ViewInfo.create({
   103                viewMap: [
   104                    ['Basic',    {type: ViewInfo.INSTANCE, viewInitFxn: 'viewInitBasic',    structName: 'BasicView'}],
   105                ]
   106            });
   107    
   108        /*! Assert if nested "enter" called. */
   109        config Assert.Id A_nestedEnter = {
   110            msg: "A_nestedEnter: Can't nest 'enter' calls."
   111        };
   112    
   113        /*!
   114         *  Error raised if an invalid Gate index is provided
   115         */
   116        config Error.Id E_invalidIndex = {
   117            msg: "E_invalidIndex %d"
   118        };
   119    
   120        /*!
   121         *  Error raised if a Gate is already in use
   122         */
   123        config Error.Id E_gateInUse = {
   124            msg: "E_gateInUse %d"
   125        };
   126    
   127        /*!
   128         *  Base address of configurable Ducati Gate Array
   129         *
   130         *  Each gate consumes one 32 bit word of shared memory.
   131         *  The array is shared between the two M3 cores and therefore
   132         *  the address of this array must be the same for both.
   133         *
   134         *  By default, the array has 4 entries (see {@link #numGates})
   135         *  and is placed immediately below Core 1's default interrupt
   136         *  vector table address of 0x00000800 (see
   137         *  {@link ti.sysbios.family.arm.m3.Hwi#vectorTableAddress}).
   138         *
   139         *  Gate zero (0) is reserved for the
   140         *  {@link ti.sysbios.hal.unicache.Cache} module.
   141         */
   142        config Ptr gateArrayAddress = 0x000007f0;
   143    
   144        /*!
   145         *  Number of Gates that can be created. Default is 4.
   146         *
   147         *  Each gate consumes one 32 bit word of memory.
   148         *  (see {@link #gateArrayAddress}).
   149         */
   150        config UInt numGates = 4;
   151    
   152        /*!
   153         *  Gate initialize flag.
   154         *
   155         *  By default, core 0 initializes all of the
   156         *  gates in {@link #gateArray}.
   157         *  This behavior can be overridden by explicitly setting this
   158         *  flag within your config script.
   159         */
   160        config Bool initGates;
   161    
   162        /*!
   163         *  Gate statistics collection flag. Default is disabled.
   164         */
   165        config bool enableStats = false;
   166    
   167        /*!
   168         *  Shared array of gate variables.
   169         *
   170         *  This global variable is placed in its own data section
   171         *  and that section is placed at {@link #gateArrayAddress}.
   172         *
   173         *  The size of the array is determined by {@link #numGates}
   174         */
   175        extern UInt32 gateArray[numGates];
   176    
   177    instance:
   178    
   179        /*! index of the gate variable in the shared gateArray table */
   180        config UInt index = 0;
   181    
   182        /*!
   183         *  @_nodoc
   184         *  ======== enter ========
   185         *  Enter this gate
   186         */
   187        override IArg enter();
   188    
   189        /*!
   190         *  @_nodoc
   191         *  ======== leave ========
   192         *  Leave this gate
   193         */
   194        override Void leave(IArg key);
   195    
   196        /*!
   197         *  Sync execution with the other M3 core.
   198         */
   199        Void sync();
   200    
   201    internal:
   202    
   203        /*
   204         *  ======== postInit ========
   205         *  finish initializing gate instances
   206         */
   207        Void postInit(Object *gate);
   208    
   209        struct Instance_State {
   210            UInt            index;
   211            volatile UInt32 *gatePtr;
   212            volatile UInt8  *gateBytePtr;
   213            /* below are for stats collection */
   214            UInt            stalls;
   215            UInt            noStalls;
   216            UInt            totalStalls;
   217            UInt            maxStall;
   218        };
   219    
   220        struct Module_State {
   221            UInt8   usedGates[numGates];
   222        };
   223    }