Rename: git mv src packages to complete application of ipc-j patches to ipcdev.
[ipc/ipcdev.git] / packages / ti / ipc / Notify.h
1 /*
2  * Copyright (c) 2012-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  *  @file       Notify.h
34  *
35  *  @brief      Notification manager for IPC
36  *
37  *  The Notify module manages the multiplexing/demultiplexing of software
38  *  interrupts over hardware interrupts.  In order to receive notifications,
39  *  a processor registers one or more callback functions to an eventId
40  *  using Notify_registerEvent().  The Notify_registerEvent()
41  *  call (like most other Notify APIs) uses a MultiProc id and
42  *  line id to target a specific interrupt line to/from a specific processor
43  *  on a device.  The Notify_eventAvailable() API may be used to query whether
44  *  an event id is availble for use before registration.
45  *
46  *  Once an event has been registered, a remote processor may send an event
47  *  using the Notify_sendEvent() call.  If the event and the interrupt line
48  *  are both enabled, all callback functions registered to the event will
49  *  be called sequentially.
50  *
51  *  A specific event may be disabled or enabled using the Notify_disableEvent()
52  *  and Notify_enableEvent() calls.  An entire interrupt line may be disabled
53  *  or restored using the Notify_disable() or Notify_restore() calls.
54  *  Notify_disable() does not alter the state of individual events.
55  *  Instead, it just disables the ability of the Notify module to receive
56  *  events on the interrupt line.
57  *
58  *  Notify APIs should never be called within an Hwi context.  All API calls
59  *  should be made within main(), a Task or a Swi with the exception of
60  *  Notify_sendEvent() which may also be called within a Hwi.
61  *
62  *  "Loopback" functionality allows Notifications to be registered
63  *  and sent locally.  This is accomplished by supplying our own MultiProc id
64  *  to Notify APIs. Line id #0 is always used for local notifications.  It is
65  *  important to be aware of some subtle (but important) differences between
66  *  remote and local notifications:
67  *
68  *      - Loopback callback functions will execute in the same thread in which
69  *        Notify_sendEvent() is called.  This is in contrast to callback
70  *        functions that are called due to another processor's sent
71  *        notification- these 'remote' callback functions will execute in an
72  *        ISR context.
73  *
74  *      - Loopback callback functions will execute with interrupts disabled
75  *
76  *      - Disabling the local interrupt line will cause all notifications that
77  *        are sent to the local processor to be lost.  By contrast, a
78  *        notification sent to an enabled event on a remote processor that has
79  *        called Notify_disable() results in a pending notifications until the
80  *        disabled processor has called Notify_restore().
81  *
82  *      - Local notifications do not support events of different priorities.
83  *        By contrast, Notify driver implementations may correlate event ids
84  *        with varying priorities.
85  *
86  *  In order to use any Notify APIs on DSP/BIOS, IPC/SysLink must first be
87  *  started.  This will internally call Notify_attach() which sets up
88  *  all necessary Notify drivers, shared memory and interprocessor interrupts.
89  *  It is possible for a user application to call Notify_attach() directly
90  *  (before Ipc_attach() or Ipc_start()) if notifications must be set up prior
91  *  to runtime SharedRegion initialization. Refer to the documentation for
92  *  Notify_attach() for more information.
93  *
94  *  The Notify header should be included in an application as follows:
95  *  @code
96  *  #include <ti/ipc/Notify.h>
97  *  @endcode
98  *
99  *  @version  0.00.01
100  *
101  *  ============================================================================
102  */
104 #ifndef ti_ipc_Notify__include
105 #define ti_ipc_Notify__include
107 #if defined (__cplusplus)
108 extern "C" {
109 #endif
111 /* =============================================================================
112  *  All success and failure codes for the module
113  * =============================================================================
114  */
116 /*!
117  *  @brief  The resource is still in use
118  */
119 #define Notify_S_BUSY                    2
121 /*!
122  *  @brief  Module already set up
123  */
124 #define Notify_S_ALREADYSETUP            1
126 /*!
127  *  @brief  Operation is successful.
128  */
129 #define Notify_S_SUCCESS                 0
131 /*!
132  *  @brief  Generic failure.
133  */
134 #define Notify_E_FAIL                   -1
136 /*!
137  *  @brief  Argument passed to function is invalid.
138  */
139 #define Notify_E_INVALIDARG             -2
141 /*!
142  *  @brief  Operation resulted in memory failure.
143  */
144 #define Notify_E_MEMORY                 -3
146 /*!
147  *  @brief  The specified entity already exists.
148  */
149 #define Notify_E_ALREADYEXISTS          -4
151 /*!
152  *  @brief  Unable to find the specified entity.
153  */
154 #define Notify_E_NOTFOUND               -5
156 /*!
157  *  @brief  Operation timed out.
158  */
159 #define Notify_E_TIMEOUT                -6
161 /*!
162  *  @brief  Module is not initialized.
163  */
164 #define Notify_E_INVALIDSTATE           -7
166 /*!
167  *  @brief  A failure occurred in an OS-specific call
168  */
169 #define Notify_E_OSFAILURE              -8
171 /*!
172  *  @brief  The module has been already setup
173  */
174 #define Notify_E_ALREADYSETUP           -9
176 /*!
177  *  @brief  Specified resource is not available
178  */
179 #define Notify_E_RESOURCE               -10
181 /*!
182  *  @brief  Operation was interrupted. Please restart the operation
183  */
184 #define Notify_E_RESTART                -11
186 /*!
187  *  @brief  The resource is still in use
188  */
189 #define Notify_E_BUSY                   -12
191 /*!
192  *  @brief  Driver corresponding to the specified eventId is not registered
193  */
194 #define Notify_E_DRIVERNOTREGISTERED    -13
196 /*!
197  *  @brief  Event not registered
198  */
199 #define Notify_E_EVTNOTREGISTERED       -14
201 /*!
202  *  @brief  Event is disabled
203  */
204 #define Notify_E_EVTDISABLED            -15
206 /*!
207  *  @brief  Remote notification is not initialized
208  */
209 #define Notify_E_NOTINITIALIZED         -16
211 /*!
212  *  @brief  Trying to illegally use a reserved event
213  */
214 #define Notify_E_EVTRESERVED            -17
216 /* =============================================================================
217  *  Macros
218  * =============================================================================
219  */
221 /*!
222  *  @brief  Maximum number of events supported by the Notify module
223  */
224 #define Notify_MAXEVENTS                (UInt16)32
226 /*!
227  *  @brief  Maximum number of IPC interrupt lines for any pair of processors
228  */
229 #define Notify_MAX_INTLINES             4u
231 /*!
232  *  @brief  This key must be provided as the upper 16 bits of the eventId when
233  *          registering for an event, if any reserved event numbers are to be
234  *          used.
235  */
236 #define Notify_SYSTEMKEY                ((UInt16)0xC1D2)
238 /* =============================================================================
239  *  Structures & Enums
240  * =============================================================================
241  */
243 /*!
244  *  @var     Notify_FnNotifyCbck
245  *  @brief   Signature of any callback function that can be registered with the
246  *           Notify component.
247  *
248  *  @param[in]  procId      Remote processor id
249  *  @param[in]  lineId      Line id
250  *  @param[in]  eventId     Event id (minus system key if reserved event)
251  *  @param[in]  arg         Argument specified in the registerEvent
252  *  @param[in]  payload     Payload specified in the sendEvent
253  */
254 typedef Void (*Notify_FnNotifyCbck)(UInt16 , UInt16, UInt32, UArg, UInt32);
256 /* =============================================================================
257  *  Notify Module-wide Functions
258  * =============================================================================
259  */
261 /*!
262  *  @brief      Creates notify drivers and registers them with Notify
263  *
264  *  This function must be called before other Notify API calls are
265  *  invoked.  Performing a attach invokes a device-specific Notify
266  *  initialization routine that creates required drivers and
267  *  registers those drivers with the Notify module.  If the drivers
268  *  require shared memory, a shared address must be supplied.
269  *
270  *  Notify_attach() is typically called internally as part of the IPC
271  *  initialization sequence.  Any memory required for Notify drivers
272  *  is reserved by SharedRegion and passed to Notify_attach().  However, if it
273  *  is necessary to pass a specific base address to Notify_attach() (i.e. if
274  *  the shared region is not valid yet), then Notify_attach() should be called
275  *  before Ipc_start() with this address.  When Ipc_start() is eventually
276  *  called, Notify_attach() will be internally bypassed since it was directly
277  *  called by the user.
278  *
279  *  @param[in]  remoteProcId    Remote processor id
280  *  @param[in]  sharedAddr      Shared address to use if any driver requires
281  *                              shared memory
282  *  @return     Notify status:
283  *              - #Notify_E_FAIL: failed to attach to remote processor
284  *              - #Notify_S_SUCCESS: successfully attach to remote processor
285  */
286 Int Notify_attach(UInt16 remoteProcId, Ptr sharedAddr);
288 /*!
289  *  @brief      Disable ability to receive interrupts on an interrupt line
290  *
291  *  This function disables a NotifyDriver from processing received
292  *  events. The key that is returned from this call must be used
293  *  in the Notify_restore() function.
294  *
295  *  Notify supports nested disable/restore calls. The value of the returned
296  *  key is the nesting depth.
297  *
298  *  If Notify_disable() is called upon an interrupt line that is already
299  *  disabled, then the corresponding Notify_restore() will not re-enable
300  *  notifications.  Only the restore call that corresponds to the
301  *  Notify_disable() that actually disabled notifications will re-enable
302  *  notifications on the interrupt line.
303  *
304  *  @param[in]  procId      Remote processor id
305  *  @param[in]  lineId      Line id
306  *
307  *  @return     Key that must be used in Notify_restore()
308  *
309  *  @sa         Notify_restore()
310  */
311 UInt Notify_disable(UInt16 procId, UInt16 lineId);
313 /*!
314  *  @brief      Disable an event
315  *
316  *  This function allows the disabling of a single event number
317  *  from the specified source processor.  Sending to a disabled event
318  *  will return #Notify_E_EVTDISABLED on the sender if waitClear is false.
319  *  Notify_disableEvent() and Notify_enableEvent() may not be supported by all
320  *  Notify drivers.  Consult the documentation for the Notify driver to determine
321  *  whether it supports this API call.
322  *
323  *  An event is, by default, enabled upon driver initialization.
324  *  Calling Notify_disableEvent() upon an event that is already disabled
325  *  results in no change in state.
326  *
327  *  Note that callbacks may be registered to an event or removed
328  *  from the event even while the event has been disabled.
329  *
330  *  @param[in]  procId      Remote processor id
331  *  @param[in]  lineId      Line id
332  *  @param[in]  eventId     Event id
333  *
334  *  @sa         Notify_enableEvent()
335  */
336 Void Notify_disableEvent(UInt16 procId, UInt16 lineId, UInt32 eventId);
338 /*!
339  *  @brief      Enable an event
340  *
341  *  This function re-enables an event that has been previously disabled
342  *  using disableEvent().  Calling Notify_enableEvent() upon an event that is
343  *  already enabled results in no change in state.  An event is,
344  *  by default, enabled upon driver initialization.
345  *
346  *  Notify_disableEvent() and Notify_enableEvent() may not be supported by all
347  *  Notify drivers.  Consult the documentation for the Notify driver to determine
348  *  whether it supports this API call.
349  *
350  *  @param[in]  procId      Remote processor id
351  *  @param[in]  lineId      Line id
352  *  @param[in]  eventId     Event id
353  *
354  *  @sa         Notify_disableEvent()
355  */
356 Void Notify_enableEvent(UInt16 procId, UInt16 lineId, UInt32 eventId);
358 /*!
359  *  @brief      Whether an unused event is available on an interrupt line
360  *
361  *  This function can be used to determine whether an unused eventId for a
362  *  specific interrupt line is available for use in Notify_registerEvent()
363  *  or Notify_registerEventSingle().  This function will return TRUE if and only
364  *  if the following conditions are simultaneously TRUE:
365  *  -  The corresponding interrupt line is available.  Notifications over an
366  *     interrupt line to a remote processor are typically made available by
367  *     calling Notify_attach() or Ipc_attach().
368  *  -  The event is not a reserved event
369  *  -  The event is a reserved event and #Notify_SYSTEMKEY has been passed
370  *     as the upper 16 bits of the 32-bit eventId argument
371  *  -  No callback functions have been registered to the event
372  *  If any of the above conditions is false, this function will return FALSE.
373  *  Note that an event may still be registered using Notify_registerEvent()
374  *  while the last condition is false if the existing callback function(s)
375  *  were registered using Notify_registerEvent() (not
376  *  Notify_registerEventSingle()).
377  *
378  *  @param[in]  procId      Remote processor id
379  *  @param[in]  lineId      Line id
380  *  @param[in]  eventId     Event id
381  *
382  *  @return     TRUE if an unused event is available, FALSE otherwise
383  */
384 Bool Notify_eventAvailable(UInt16 procId, UInt16 lineId, UInt32 eventId);
386 /*!
387  *  @brief      Whether notification via interrupt line has been registered.
388  *
389  *  This function will return TRUE if and only if a notify driver has been
390  *  registered for the interrupt line identified by the supplied procId and
391  *  lineId.  The interrupt line corresponding to loopback functionality is
392  *  always registered.  A value of FALSE indicates that either
393  *  Notify_attach() has not yet been called or that notification to the
394  *  remote processor is unsupported.
395  *
396  *  @param[in]  procId      Remote processor id
397  *  @param[in]  lineId      Line id
398  *
399  *  @return     TRUE if registered, FALSE otherwise
400  */
401 Bool Notify_intLineRegistered(UInt16 procId, UInt16 lineId);
403 /*!
404  *  @brief      Returns number of interrupt lines to remote processor
405  *
406  *  This function returns the number of available interrupt lines to a remote
407  *  processor.
408  *
409  *  @param[in]  procId      Remote processor id
410  *
411  *  @return     Number of interrupt lines
412  */
413 UInt16 Notify_numIntLines(UInt16 procId);
415 /*! @cond */
416 /*!
417  *  @brief  Returns the amount of shared memory used by one Notify instance.
418  *
419  *  This will typically be used internally by other IPC modules during system
420  *  initialization.  The return value depends upon the base address because
421  *  of cache alignment settings.
422  *
423  *  @param[in]  sharedAddr      Base address that will be passed to
424  *                              Notify_attach()
425  *
426  *  @return     Shared memory required (in MAUs)
427  */
428 SizeT Notify_sharedMemReq(UInt16 procId, Ptr sharedAddr);
430 /*! @endcond */
432 /*!
433  *  @brief      Register a callback for an event (supports multiple callbacks)
434  *
435  *  This function registers a callback to a specific event number,
436  *  processor id and interrupt line. When the event is received by the
437  *  specified processor, the callback is called.
438  *
439  *  The callback function prototype is of type #Notify_FnNotifyCbck.
440  *  This function must be non-blocking.
441  *
442  *  It is important to note that multiple callbacks may be registered with
443  *  a single event.  This is accomplished by simply calling
444  *  Notify_registerEvent() for each combination of callback functions and
445  *  callback arguments as needed.
446  *
447  *  It is important to note that interrupts are disabled during the entire
448  *  duration of this function's execution.
449  *
450  *  @param[in]  procId          Remote processor id
451  *  @param[in]  lineId          Line id (0 for most systems)
452  *  @param[in]  eventId         Event id
453  *  @param[in]  fnNotifyCbck    Pointer to callback function
454  *  @param[in]  cbckArg         Callback function argument
455  *
456  *  @return     Notify status:
457  *              - #Notify_S_SUCCESS: Event successfully registered
458  *              - #Notify_E_MEMORY: Failed to register due to memory error
459  *
460  *  @sa         Notify_unregisterEvent()
461  */
462 Int Notify_registerEvent(UInt16 procId,
463                          UInt16 lineId,
464                          UInt32 eventId,
465                          Notify_FnNotifyCbck fnNotifyCbck,
466                          UArg cbckArg);
468 /*!
469  *  @brief      Register a single callback for an event
470  *
471  *  This function registers a callback to a specific event number,
472  *  processor id and interrupt line. When the event is received by the
473  *  specified processor, the callback is called.
474  *
475  *  The callback function prototype is of type #Notify_FnNotifyCbck.
476  *  The callback function must be non-blocking.
477  *
478  *  Only one callback may be registered with this API.
479  *
480  *  Use Notify_registerEvent() to register multiple callbacks for a single event.
481  *
482  *  @param[in]  procId          Remote processor id
483  *  @param[in]  lineId          Line id (0 for most systems)
484  *  @param[in]  eventId         Event id
485  *  @param[in]  fnNotifyCbck    Pointer to callback function
486  *  @param[in]  cbckArg         Callback function argument
487  *
488  *  @return     Notify status:
489  *              - #Notify_E_ALREADYEXISTS: Event already registered
490  *              - #Notify_S_SUCCESS: Event successfully registered
491  *
492  *  @sa         Notify_unregisterEventSingle()
493  */
494 Int Notify_registerEventSingle(UInt16 procId,
495                                UInt16 lineId,
496                                UInt32 eventId,
497                                Notify_FnNotifyCbck fnNotifyCbck,
498                                UArg cbckArg);
500 /*!
501  *  @brief      Restore ability to receive interrupts on an interrupt line
502  *
503  *  This function re-enables receiving notifications on a specific interrupt
504  *  line.
505  *
506  *  Notify supports nested disable/restore calls. The last restore call
507  *  will re-enable Notifications.
508  *
509  *  @param[in]  procId      Remote processor id
510  *  @param[in]  lineId      Line id
511  *  @param[in]  key         Key returned by Notify_disable()
512  *
513  *  @sa         Notify_disable()
514  */
515 Void Notify_restore(UInt16 procId, UInt16 lineId, UInt key);
517 /*!
518  *  @brief      Send an event on an interrupt line
519  *
520  *  This function sends an event to a processor via an interrupt line
521  *  identified by a processor id and line id. A payload may be optionally
522  *  sent to the the remote processor if supported by the device.
523  *
524  *  On the destination processor, the callback functions registered
525  *  with Notify with the associated eventId and source
526  *  processor id are called.
527  *
528  *  For example, when using 'NotifyDriverShm', a 'waitClear' value of 'TRUE'
529  *  indicates that, if an event was previously sent to the same eventId,
530  *  sendEvent should spin until the previous event has been acknowledged by the
531  *  remote processor. If 'waitClear' is FALSE, a pending event with the same
532  *  eventId will be overwritten by the event currently being sent. When in
533  *  doubt, a value of TRUE should be used because notifications may be
534  *  potentially dropped when FALSE is used.  When using NotifyDriverShm, a
535  *  payload should never be sent with 'waitClear = FALSE.'
536  *
537  *  On the other hand, other notify drivers that use a FIFO to transmit events
538  *  will spin if @c waitClear is TRUE until the FIFO has enough room to accept
539  *  the event being sent.  If @c waitClear is FALSE, Notify_sendEvent() will
540  *  return #Notify_E_FAIL if the FIFO does not have room for the event.
541  *
542  *  Refer to the documentation for the Notify drivers for more information
543  *  about the effect of the @c waitClear flag in Notify_sendEvent().
544  *
545  *  Notify_sendEvent can be called from a Hwi context unlike other Notify APIs.
546  *
547  *  @param[in]  procId      Remote processor id
548  *  @param[in]  lineId      Line id
549  *  @param[in]  eventId     Event id
550  *  @param[in]  payload     Payload to be sent along with the event.
551  *  @param[in]  waitClear   Indicates whether to spin waiting for the remote
552  *                          core to process previous events
553  *
554  *  @return     Notify status:
555  *              - #Notify_E_EVTNOTREGISTERED: event has no registered callback
556  *                functions
557  *              - #Notify_E_NOTINITIALIZED: remote driver has not yet been
558  *                initialized
559  *              - #Notify_E_EVTDISABLED: remote event is disabled
560  *              - #Notify_E_TIMEOUT: timeout occured (when waitClear is TRUE)
561  *              - #Notify_S_SUCCESS: event successfully sent
562  */
563 Int Notify_sendEvent(UInt16 procId, UInt16 lineId, UInt32 eventId,
564         UInt32 payload, Bool waitClear);
566 /*!
567  *  @brief      Remove an event listener from an event
568  *
569  *  This function unregisters a single callback that was registered to an event
570  *  using Notify_registerEvent(). The @c procId, @c lineId, @c eventId,
571  *  @c fnNotifyCbck and @c cbckArg must exactly match with the registered one.
572  *
573  *  This API is used to unregister events that were registered with
574  *  Notify_registerEvent().  If this is the last event, then
575  *  Notify_unregisterEventSingle() is called to completely remove the event.
576  *
577  *  @param[in]  procId          Remote processor id
578  *  @param[in]  lineId          Line id
579  *  @param[in]  eventId         Event id
580  *  @param[in]  fnNotifyCbck    Pointer to callback function
581  *  @param[in]  cbckArg         Callback function argument
582  *
583  *  @return     Notify status:
584  *              - #Notify_E_NOTFOUND: event listener not found
585  *              - #Notify_S_SUCCESS: event listener unregistered
586  *
587  *  @sa         Notify_registerEvent()
588  */
589 Int Notify_unregisterEvent(UInt16 procId, UInt16 lineId, UInt32 eventId,
590         Notify_FnNotifyCbck fnNotifyCbck, UArg cbckArg);
592 /*!
593  *  @brief      Remove an event listener from an event
594  *
595  *  This function removes a previously registered callback registered with
596  *  Notify_registerEventSingle(). The @c procId, @c lineId, and @c eventId
597  *  must exactly match the registered one.
598  *
599  *  @param[in]  procId      Remote processor id
600  *  @param[in]  lineId      Line id
601  *  @param[in]  eventId     Event id that is being unregistered
602  *
603  *  @return     Notify status:
604  *              - #Notify_S_SUCCESS: event unregistered
605  *              - #Notify_E_FAIL: fail to unregister event
606  *
607  *  @sa         Notify_registerEventSingle()
608  */
609 Int Notify_unregisterEventSingle(UInt16 procId, UInt16 lineId, UInt32 eventId);
611 #if defined (__cplusplus)
613 #endif /* defined (__cplusplus) */
614 #endif /* ti_ipc_Notify__include */