1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
32 33 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")
82 @ModuleStartup
83 @InstanceInitError
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 205 206
207 Void postInit(Object *gate);
208
209 struct Instance_State {
210 UInt index;
211 volatile UInt32 *gatePtr;
212 volatile UInt8 *gateBytePtr;
213
214 UInt stalls;
215 UInt noStalls;
216 UInt totalStalls;
217 UInt maxStall;
218 };
219
220 struct Module_State {
221 UInt8 usedGates[numGates];
222 };
223 }