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 import ti.sdo.utils.MultiProc;
37 import ti.sdo.ipc.interfaces.INotifyDriver;
38 import ti.sdo.ipc.notifyDrivers.IInterrupt;
39 import ti.sdo.ipc.Notify;
40
41 import xdc.rov.ViewInfo;
42
43 import xdc.runtime.Assert;
44
45 /*!
46 * ======== NotifyDriverCirc ========
47 * A shared memory driver using circular buffer for the Notify Module.
48 *
49 * This is a {@link ti.sdo.ipc.Notify} driver that utilizes shared memory
50 * and inter-processor hardware interrupts for notification between cores.
51 * This driver supports caching.
52 *
53 * This driver is designed to work with a variety of devices, each with
54 * distinct interrupt mechanisms. Therefore, this module needs to be plugged
55 * with an appropriate module that implements the {@link IInterrupt} interface
56 * for a given device.
57 *
58 * The Notify_[enable/disable]Event APIs are not supported by this driver.
59 *
60 * The driver utilizes shared memory in the manner indicated by the following
61 * diagram.
62 *
63 * @p(code)
64 *
65 * NOTE: Processors '0' and '1' correspond to the processors with lower and
66 * higher MultiProc ids, respectively
67 *
68 * sharedAddr -> --------------------------- bytes
69 * | eventEntry0 (0) | 8
70 * | eventEntry1 (0) | 8
71 * | ... |
72 * | eventEntry15 (0) | 8
73 * | [align to cache size] |
74 * |-------------------------|
75 * | eventEntry16 (0) | 8
76 * | eventEntry17 (0) | 8
77 * | ... |
78 * | eventEntry31 (0) | 8
79 * | [align to cache size] |
80 * |-------------------------|
81 * | putWriteIndex (0) | 4
82 * | [align to cache size] |
83 * |-------------------------|
84 * | putReadIndex (0) | 4
85 * | [align to cache size] |
86 * |-------------------------|
87 * | eventEntry0 (1) | 8
88 * | eventEntry1 (1) | 8
89 * | ... |
90 * | eventEntry15 (1) | 8
91 * | [align to cache size] |
92 * |-------------------------|
93 * | eventEntry16 (1) | 8
94 * | eventEntry17 (1) | 8
95 * | ... |
96 * | eventEntry31 (1) | 8
97 * | [align to cache size] |
98 * |-------------------------|
99 * | getWriteIndex (1) | 4
100 * | [align to cache size] |
101 * |-------------------------|
102 * | getReadIndex (1) | 4
103 * | [align to cache size] |
104 * |-------------------------|
105 *
106 *
107 * Legend:
108 * (0), (1) : Memory that belongs to the proc with lower and higher
109 * MultiProc.id, respectively
110 * |----| : Cache line boundary
111 *
112 * @p
113 */
114
115 @InstanceFinalize
116
117 module NotifyDriverCirc inherits ti.sdo.ipc.interfaces.INotifyDriver
118 {
119 /*! @_nodoc */
120 metaonly struct BasicView {
121 String remoteProcName;
122 Bool cacheEnabled;
123 UInt bufSize;
124 UInt spinCount;
125 UInt maxSpinWait;
126 }
127
128 /*! @_nodoc */
129 metaonly struct EventDataView {
130 UInt index;
131 String buffer;
132 Ptr addr;
133 UInt eventId;
134 Ptr payload;
135 }
136
137 /*!
138 * ======== rovViewInfo ========
139 */
140 @Facet
141 metaonly config ViewInfo.Instance rovViewInfo =
142 ViewInfo.create({
143 viewMap: [
144 ['Basic',
145 {
146 type: ViewInfo.INSTANCE,
147 viewInitFxn: 'viewInitBasic',
148 structName: 'BasicView'
149 }
150 ],
151 ['Events',
152 {
153 type: ViewInfo.INSTANCE_DATA,
154 viewInitFxn: 'viewInitData',
155 structName: 'EventDataView'
156 }
157 ],
158 ]
159 });
160
161 /*!
162 * Assert raised when trying to use Notify_[enable/disable]Event with
163 * NotifyDriverCirc
164 */
165 config Assert.Id A_notSupported =
166 {msg: "A_notSupported: [enable/disable]Event not supported by NotifyDriverCirc"};
167
168
169 /*! @_nodoc
170 * IInterrupt proxy that handles interrupts between multiple CPU cores
171 */
172 proxy InterruptProxy inherits IInterrupt;
173
174 /*!
175 * ======== enableStats ========
176 * Enable statistics for sending an event
177 *
178 * If this parameter is to 'TRUE' and 'waitClear' is also set to
179 * TRUE when calling (@link #sendEvent(), then the module keeps
180 * track of the number of times the processor spins waiting for
181 * an empty slot and the max amount of time it waits.
182 */
183 config Bool enableStats = false;
184
185 /*!
186 * ======== numMsgs ========
187 * The number of messages or slots in the circular buffer
188 *
189 * This is use to determine the size of the put and get buffers.
190 * Each eventEntry is two 32bits wide, therefore the total size
191 * of each circular buffer is [numMsgs * sizeof(eventEntry)].
192 * The total size of each buffer must be a multiple of the
193 * the cache line size. For example, if the cacheLineSize = 128
194 * then numMsgs could be 16, 32, etc...
195 */
196 config UInt numMsgs = 32;
197
198 /*!
199 * ======== sharedMemReq ========
200 * Amount of shared memory required for creation of each instance
201 *
202 * @param(params) Pointer to parameters that will be used in the
203 * create
204 *
205 * @a(returns) Number of MAUs in shared memory needed to create
206 * the instance.
207 */
208 SizeT sharedMemReq(const Params *params);
209
210 instance:
211
212 /*!
213 * ======== sharedAddr ========
214 * Address in shared memory where this instance will be placed
215 *
216 * Use {@link #sharedMemReq} to determine the amount of shared memory
217 * required.
218 */
219 config Ptr sharedAddr = null;
220
221 /*!
222 * ======== cacheEnabled ========
223 * Whether cache operations will be performed
224 *
225 * If it is known that no cache operations are needed for this instance
226 * set this flag to FALSE. If {@link #sharedAddr} lies within a shared
227 * region and the cache enabled setting for the region is FALSE,
228 * then the value specified here will be overriden to FALSE.
229 */
230 config Bool cacheEnabled = true;
231
232 /*!
233 * ======== cacheLineSize ========
234 * The cache line size of the shared memory
235 *
236 * This value should be configured
237 */
238 config SizeT cacheLineSize = 128;
239
240 /*!
241 * ======== remoteProcId ========
242 * The MultiProc ID corresponding to the remote processor
243 *
244 * This parameter must be set for every device. The
245 * MultiProc_getId call can be used to obtain
246 * a MultiProc id given the remote processor's name.
247 */
248 config UInt16 remoteProcId = MultiProc.INVALIDID;
249
250 /*!
251 * ======== intVectorId ========
252 * Interrupt vector ID to be used by the driver.
253 *
254 * This parameter is only used by C64x+ targets
255 */
256 config UInt intVectorId = ~1u;
257
258 /*!
259 * ======== localIntId ========
260 * Local interrupt ID for interrupt line
261 *
262 * For devices that support multiple inter-processor interrupt lines, this
263 * configuration parameter allows selecting a specific line to use for
264 * receiving an interrupt. The value specified here corresponds to the
265 * incoming interrupt line on the local processor.
266 *
267 * If this configuration is not set, a default interrupt id is
268 * typically chosen.
269 */
270 config UInt localIntId = -1u;
271
272 /*!
273 * ======== remoteIntId ========
274 * Remote interrupt ID for interrupt line
275 *
276 * For devices that support multiple inter-processor interrupt lines, this
277 * configuration parameter allows selecting a specific line to use for
278 * receiving an interrupt. The value specified here corresponds to the
279 * incoming interrupt line on the remote processor.
280 *
281 * If this configuration is not set, a default interrupt id is
282 * typically chosen.
283 */
284 config UInt remoteIntId = -1u;
285
286 internal:
287
288 /*! The max index set to (numMsgs - 1) */
289 config UInt maxIndex;
290
291 /*!
292 * The modulo index value. Set to (numMsgs / 4).
293 * Used in the isr for doing cache_wb of readIndex.
294 */
295 config UInt modIndex;
296
297 /*!
298 * Plugs the interrupt and executes the callback functions according
299 * to event priority
300 */
301 Void isr(UArg arg);
302
303 /*!
304 * Structure for each event. This struct is placed in shared memory.
305 */
306 struct EventEntry {
307 volatile Bits32 eventid;
308 volatile Bits32 payload;
309 }
310
311 /*! Instance state structure */
312 struct Instance_State {
313 EventEntry *putBuffer;
314 Bits32 *putReadIndex;
315 Bits32 *putWriteIndex;
316 EventEntry *getBuffer;
317 Bits32 *getReadIndex;
318 Bits32 *getWriteIndex;
319 Bits32 evtRegMask;
320 SizeT opCacheSize;
321 UInt32 spinCount;
322 UInt32 spinWaitTime;
323 Notify.Handle notifyHandle;
324 IInterrupt.IntInfo intInfo;
325 UInt16 remoteProcId;
326 Bool cacheEnabled;
327 }
328 }