16371d818e3d28ea8a2edf156a9ffdf9c170ce90
[linux-3.10.git] / drivers / staging / tidspbridge / include / dspbridge / node.h
1 /*
2  * node.h
3  *
4  * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5  *
6  * DSP/BIOS Bridge Node Manager.
7  *
8  * Copyright (C) 2005-2006 Texas Instruments, Inc.
9  *
10  * This package is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13  *
14  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  */
18
19 #ifndef NODE_
20 #define NODE_
21
22 #include <dspbridge/procpriv.h>
23
24 #include <dspbridge/nodedefs.h>
25 #include <dspbridge/disp.h>
26 #include <dspbridge/nldrdefs.h>
27 #include <dspbridge/drv.h>
28
29 /*
30  *  ======== node_allocate ========
31  *  Purpose:
32  *      Allocate GPP resources to manage a node on the DSP.
33  *  Parameters:
34  *      hprocessor:         Handle of processor that is allocating the node.
35  *      node_uuid:          Pointer to a dsp_uuid for the node.
36  *      pargs:              Optional arguments to be passed to the node.
37  *      attr_in:            Optional pointer to node attributes (priority,
38  *                          timeout...)
39  *      noderes:             Location to store node resource info.
40  *  Returns:
41  *      0:            Success.
42  *      -ENOMEM:        Insufficient memory on GPP.
43  *      -ENOKEY:          Node UUID has not been registered.
44  *      -ESPIPE:        iAlg functions not found for a DAIS node.
45  *      -EDOM:         attr_in != NULL and attr_in->prio out of
46  *                          range.
47  *      -EPERM:          A failure occurred, unable to allocate node.
48  *      -EBADR:    Proccessor is not in the running state.
49  *  Requires:
50  *      node_init(void) called.
51  *      hprocessor != NULL.
52  *      node_uuid != NULL.
53  *      noderes != NULL.
54  *  Ensures:
55  *      0:            IsValidNode(*ph_node).
56  *      error:              *noderes == NULL.
57  */
58 extern int node_allocate(struct proc_object *hprocessor,
59                                 const struct dsp_uuid *node_uuid,
60                                 const struct dsp_cbdata
61                                 *pargs, const struct dsp_nodeattrin
62                                 *attr_in,
63                                 struct node_res_object **noderes,
64                                 struct process_context *pr_ctxt);
65
66 /*
67  *  ======== node_alloc_msg_buf ========
68  *  Purpose:
69  *      Allocate and Prepare a buffer whose descriptor will be passed to a
70  *      Node within a (dsp_msg)message
71  *  Parameters:
72  *      hnode:          The node handle.
73  *      usize:          The size of the buffer to be allocated.
74  *      pattr:          Pointer to a dsp_bufferattr structure.
75  *      pbuffer:        Location to store the address of the allocated
76  *                      buffer on output.
77  *  Returns:
78  *      0:        Success.
79  *      -EFAULT:    Invalid node handle.
80  *      -ENOMEM:    Insufficent memory.
81  *      -EPERM:      General Failure.
82  *      -EINVAL:      Invalid Size.
83  *  Requires:
84  *      node_init(void) called.
85  *      pbuffer != NULL.
86  *  Ensures:
87  */
88 extern int node_alloc_msg_buf(struct node_object *hnode,
89                                      u32 usize, struct dsp_bufferattr
90                                      *pattr, u8 **pbuffer);
91
92 /*
93  *  ======== node_change_priority ========
94  *  Purpose:
95  *      Change the priority of an allocated node.
96  *  Parameters:
97  *      hnode:              Node handle returned from node_allocate.
98  *      prio:          New priority level to set node's priority to.
99  *  Returns:
100  *      0:            Success.
101  *      -EFAULT:        Invalid hnode.
102  *      -EDOM:         prio is out of range.
103  *      -EPERM: The specified node is not a task node.
104  *              Unable to change node's runtime priority level.
105  *      -EBADR:    Node is not in the NODE_ALLOCATED, NODE_PAUSED,
106  *                          or NODE_RUNNING state.
107  *      -ETIME:       A timeout occurred before the DSP responded.
108  *  Requires:
109  *      node_init(void) called.
110  *  Ensures:
111  *      0 && (Node's current priority == prio)
112  */
113 extern int node_change_priority(struct node_object *hnode, s32 prio);
114
115 /*
116  *  ======== node_connect ========
117  *  Purpose:
118  *      Connect two nodes on the DSP, or a node on the DSP to the GPP. In the
119  *      case that the connection is being made between a node on the DSP and
120  *      the GPP, one of the node handles (either node1 or node2) must be
121  *      the constant NODE_HGPPNODE.
122  *  Parameters:
123  *      node1:         Handle of first node to connect to second node. If
124  *                      this is a connection from the GPP to node2, node1
125  *                      must be the constant NODE_HGPPNODE. Otherwise, node1
126  *                      must be a node handle returned from a successful call
127  *                      to Node_Allocate().
128  *      node2:         Handle of second node. Must be either NODE_HGPPNODE
129  *                      if this is a connection from DSP node to GPP, or a
130  *                      node handle returned from a successful call to
131  *                      node_allocate().
132  *      stream1:        Output stream index on first node, to be connected
133  *                      to second node's input stream. Value must range from
134  *                      0 <= stream1 < number of output streams.
135  *      stream2:        Input stream index on second node. Value must range
136  *                      from 0 <= stream2 < number of input streams.
137  *      pattrs:         Stream attributes (NULL ==> use defaults).
138  *      conn_param:     A pointer to a dsp_cbdata structure that defines
139  *                      connection parameter for device nodes to pass to DSP
140  *                      side.
141  *                      If the value of this parameter is NULL, then this API
142  *                      behaves like DSPNode_Connect. This parameter will have
143  *                      length of the string and the null terminated string in
144  *                      dsp_cbdata struct. This can be extended in future tp
145  *                      pass binary data.
146  *  Returns:
147  *      0:                Success.
148  *      -EFAULT:            Invalid node1 or node2.
149  *      -ENOMEM:            Insufficient host memory.
150  *      -EINVAL:             A stream index parameter is invalid.
151  *      -EISCONN:  A connection already exists for one of the
152  *                              indices stream1 or stream2.
153  *      -EBADR:        Either node1 or node2 is not in the
154  *                              NODE_ALLOCATED state.
155  *      -ECONNREFUSED: No more connections available.
156  *      -EPERM:              Attempt to make an illegal connection (eg,
157  *                              Device node to device node, or device node to
158  *                              GPP), the two nodes are on different DSPs.
159  *  Requires:
160  *      node_init(void) called.
161  *  Ensures:
162  */
163 extern int node_connect(struct node_object *node1,
164                                u32 stream1,
165                                struct node_object *node2,
166                                u32 stream2,
167                                struct dsp_strmattr *pattrs,
168                                struct dsp_cbdata
169                                *conn_param);
170
171 /*
172  *  ======== node_create ========
173  *  Purpose:
174  *      Create a node on the DSP by remotely calling the node's create
175  *      function. If necessary, load code that contains the node's create
176  *      function.
177  *  Parameters:
178  *      hnode:              Node handle returned from node_allocate().
179  *  Returns:
180  *      0:            Success.
181  *      -EFAULT:        Invalid hnode.
182  *      -ESPIPE:        Create function not found in the COFF file.
183  *      -EBADR:    Node is not in the NODE_ALLOCATED state.
184  *      -ENOMEM:        Memory allocation failure on the DSP.
185  *      -ETIME:       A timeout occurred before the DSP responded.
186  *      -EPERM:          A failure occurred, unable to create node.
187  *  Requires:
188  *      node_init(void) called.
189  *  Ensures:
190  */
191 extern int node_create(struct node_object *hnode);
192
193 /*
194  *  ======== node_create_mgr ========
195  *  Purpose:
196  *      Create a NODE Manager object. This object handles the creation,
197  *      deletion, and execution of nodes on the DSP target. The NODE Manager
198  *      also maintains a pipe map of used and available node connections.
199  *      Each DEV object should have exactly one NODE Manager object.
200  *
201  *  Parameters:
202  *      node_man:       Location to store node manager handle on output.
203  *      hdev_obj:     Device for this processor.
204  *  Returns:
205  *      0:        Success;
206  *      -ENOMEM:    Insufficient memory for requested resources.
207  *      -EPERM:      General failure.
208  *  Requires:
209  *      node_init(void) called.
210  *      node_man != NULL.
211  *      hdev_obj != NULL.
212  *  Ensures:
213  *      0:        Valide *node_man.
214  *      error:          *node_man == NULL.
215  */
216 extern int node_create_mgr(struct node_mgr **node_man,
217                                   struct dev_object *hdev_obj);
218
219 /*
220  *  ======== node_delete ========
221  *  Purpose:
222  *      Delete resources allocated in node_allocate(). If the node was
223  *      created, delete the node on the DSP by remotely calling the node's
224  *      delete function. Loads the node's delete function if necessary.
225  *      GPP side resources are freed after node's delete function returns.
226  *  Parameters:
227  *      noderes:              Node resource info handle returned from
228  *                                 node_allocate().
229  *      pr_ctxt:                Poninter to process context data.
230  *  Returns:
231  *      0:            Success.
232  *      -EFAULT:        Invalid hnode.
233  *      -ETIME:       A timeout occurred before the DSP responded.
234  *      -EPERM:          A failure occurred in deleting the node.
235  *      -ESPIPE:        Delete function not found in the COFF file.
236  *  Requires:
237  *      node_init(void) called.
238  *  Ensures:
239  *      0:            hnode is invalid.
240  */
241 extern int node_delete(struct node_res_object *noderes,
242                               struct process_context *pr_ctxt);
243
244 /*
245  *  ======== node_delete_mgr ========
246  *  Purpose:
247  *      Delete the NODE Manager.
248  *  Parameters:
249  *      hnode_mgr:       Node manager object.
250  *  Returns:
251  *      0:        Success.
252  *  Requires:
253  *      node_init(void) called.
254  *      Valid hnode_mgr.
255  *  Ensures:
256  */
257 extern int node_delete_mgr(struct node_mgr *hnode_mgr);
258
259 /*
260  *  ======== node_enum_nodes ========
261  *  Purpose:
262  *      Enumerate the nodes currently allocated for the DSP.
263  *  Parameters:
264  *      hnode_mgr:       Node manager returned from node_create_mgr().
265  *      node_tab:       Array to copy node handles into.
266  *      node_tab_size:   Number of handles that can be written to node_tab.
267  *      pu_num_nodes:     Location where number of node handles written to
268  *                      node_tab will be written.
269  *      pu_allocated:    Location to write total number of allocated nodes.
270  *  Returns:
271  *      0:        Success.
272  *      -EINVAL:      node_tab is too small to hold all node handles.
273  *  Requires:
274  *      Valid hnode_mgr.
275  *      node_tab != NULL || node_tab_size == 0.
276  *      pu_num_nodes != NULL.
277  *      pu_allocated != NULL.
278  *  Ensures:
279  *      - (-EINVAL && *pu_num_nodes == 0)
280  *      - || (0 && *pu_num_nodes <= node_tab_size)  &&
281  *        (*pu_allocated == *pu_num_nodes)
282  */
283 extern int node_enum_nodes(struct node_mgr *hnode_mgr,
284                                   void **node_tab,
285                                   u32 node_tab_size,
286                                   u32 *pu_num_nodes,
287                                   u32 *pu_allocated);
288
289 /*
290  *  ======== node_exit ========
291  *  Purpose:
292  *      Discontinue usage of NODE module.
293  *  Parameters:
294  *  Returns:
295  *  Requires:
296  *      node_init(void) successfully called before.
297  *  Ensures:
298  *      Any resources acquired in node_init(void) will be freed when last NODE
299  *      client calls node_exit(void).
300  */
301 extern void node_exit(void);
302
303 /*
304  *  ======== node_free_msg_buf ========
305  *  Purpose:
306  *      Free a message buffer previously allocated with node_alloc_msg_buf.
307  *  Parameters:
308  *      hnode:          The node handle.
309  *      pbuffer:        (Address) Buffer allocated by node_alloc_msg_buf.
310  *      pattr:          Same buffer attributes passed to node_alloc_msg_buf.
311  *  Returns:
312  *      0:        Success.
313  *      -EFAULT:    Invalid node handle.
314  *      -EPERM:      Failure to free the buffer.
315  *  Requires:
316  *      node_init(void) called.
317  *      pbuffer != NULL.
318  *  Ensures:
319  */
320 extern int node_free_msg_buf(struct node_object *hnode,
321                                     u8 *pbuffer,
322                                     struct dsp_bufferattr
323                                     *pattr);
324
325 /*
326  *  ======== node_get_attr ========
327  *  Purpose:
328  *      Copy the current attributes of the specified node into a dsp_nodeattr
329  *      structure.
330  *  Parameters:
331  *      hnode:          Node object allocated from node_allocate().
332  *      pattr:          Pointer to dsp_nodeattr structure to copy node's
333  *                      attributes.
334  *      attr_size:      Size of pattr.
335  *  Returns:
336  *      0:        Success.
337  *      -EFAULT:    Invalid hnode.
338  *  Requires:
339  *      node_init(void) called.
340  *      pattr != NULL.
341  *  Ensures:
342  *      0:        *pattrs contains the node's current attributes.
343  */
344 extern int node_get_attr(struct node_object *hnode,
345                                 struct dsp_nodeattr *pattr, u32 attr_size);
346
347 /*
348  *  ======== node_get_message ========
349  *  Purpose:
350  *      Retrieve a message from a node on the DSP. The node must be either a
351  *      message node, task node, or XDAIS socket node.
352  *      If a message is not available, this function will block until a
353  *      message is available, or the node's timeout value is reached.
354  *  Parameters:
355  *      hnode:          Node handle returned from node_allocate().
356  *      message:       Pointer to dsp_msg structure to copy the
357  *                      message into.
358  *      utimeout:       Timeout in milliseconds to wait for message.
359  *  Returns:
360  *      0:        Success.
361  *      -EFAULT:    Invalid hnode.
362  *      -EPERM: Cannot retrieve messages from this type of node.
363  *              Error occurred while trying to retrieve a message.
364  *      -ETIME:   Timeout occurred and no message is available.
365  *  Requires:
366  *      node_init(void) called.
367  *      message != NULL.
368  *  Ensures:
369  */
370 extern int node_get_message(struct node_object *hnode,
371                                    struct dsp_msg *message, u32 utimeout);
372
373 /*
374  *  ======== node_get_nldr_obj ========
375  *  Purpose:
376  *      Retrieve the Nldr manager
377  *  Parameters:
378  *      hnode_mgr:       Node Manager
379  *      nldr_ovlyobj:   Pointer to a Nldr manager handle
380  *  Returns:
381  *      0:        Success.
382  *      -EFAULT:    Invalid hnode.
383  *  Ensures:
384  */
385 extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
386                                     struct nldr_object **nldr_ovlyobj);
387
388 /*
389  *  ======== node_init ========
390  *  Purpose:
391  *      Initialize the NODE module.
392  *  Parameters:
393  *  Returns:
394  *      TRUE if initialization succeeded, FALSE otherwise.
395  *  Ensures:
396  */
397 extern bool node_init(void);
398
399 /*
400  *  ======== node_on_exit ========
401  *  Purpose:
402  *      Gets called when RMS_EXIT is received for a node. PROC needs to pass
403  *      this function as a parameter to msg_create(). This function then gets
404  *      called by the Bridge driver when an exit message for a node is received.
405  *  Parameters:
406  *      hnode:      Handle of the node that the exit message is for.
407  *      node_status:    Return status of the node's execute phase.
408  *  Returns:
409  *  Ensures:
410  */
411 void node_on_exit(struct node_object *hnode, s32 node_status);
412
413 /*
414  *  ======== node_pause ========
415  *  Purpose:
416  *      Suspend execution of a node currently running on the DSP.
417  *  Parameters:
418  *      hnode:              Node object representing a node currently
419  *                          running on the DSP.
420  *  Returns:
421  *      0:            Success.
422  *      -EFAULT:        Invalid hnode.
423  *      -EPERM: Node is not a task or socket node.
424  *              Failed to pause node.
425  *      -ETIME:       A timeout occurred before the DSP responded.
426  *      DSP_EWRONGSTSATE:   Node is not in NODE_RUNNING state.
427  *  Requires:
428  *      node_init(void) called.
429  *  Ensures:
430  */
431 extern int node_pause(struct node_object *hnode);
432
433 /*
434  *  ======== node_put_message ========
435  *  Purpose:
436  *      Send a message to a message node, task node, or XDAIS socket node.
437  *      This function will block until the message stream can accommodate
438  *      the message, or a timeout occurs. The message will be copied, so Msg
439  *      can be re-used immediately after return.
440  *  Parameters:
441  *      hnode:              Node handle returned by node_allocate().
442  *      pmsg:               Location of message to be sent to the node.
443  *      utimeout:           Timeout in msecs to wait.
444  *  Returns:
445  *      0:            Success.
446  *      -EFAULT:        Invalid hnode.
447  *      -EPERM: Messages can't be sent to this type of node.
448  *              Unable to send message.
449  *      -ETIME:       Timeout occurred before message could be set.
450  *      -EBADR:    Node is in invalid state for sending messages.
451  *  Requires:
452  *      node_init(void) called.
453  *      pmsg != NULL.
454  *  Ensures:
455  */
456 extern int node_put_message(struct node_object *hnode,
457                                    const struct dsp_msg *pmsg, u32 utimeout);
458
459 /*
460  *  ======== node_register_notify ========
461  *  Purpose:
462  *      Register to be notified on specific events for this node.
463  *  Parameters:
464  *      hnode:          Node handle returned by node_allocate().
465  *      event_mask:     Mask of types of events to be notified about.
466  *      notify_type:    Type of notification to be sent.
467  *      hnotification:  Handle to be used for notification.
468  *  Returns:
469  *      0:        Success.
470  *      -EFAULT:    Invalid hnode.
471  *      -ENOMEM:    Insufficient memory on GPP.
472  *      -EINVAL:     event_mask is invalid.
473  *      -ENOSYS:   Notification type specified by notify_type is not
474  *                      supported.
475  *  Requires:
476  *      node_init(void) called.
477  *      hnotification != NULL.
478  *  Ensures:
479  */
480 extern int node_register_notify(struct node_object *hnode,
481                                        u32 event_mask, u32 notify_type,
482                                        struct dsp_notification
483                                        *hnotification);
484
485 /*
486  *  ======== node_run ========
487  *  Purpose:
488  *      Start execution of a node's execute phase, or resume execution of
489  *      a node that has been suspended (via node_pause()) on the DSP. Load
490  *      the node's execute function if necessary.
491  *  Parameters:
492  *      hnode:              Node object representing a node currently
493  *                          running on the DSP.
494  *  Returns:
495  *      0:            Success.
496  *      -EFAULT:        Invalid hnode.
497  *      -EPERM: hnode doesn't represent a message, task or dais socket node.
498  *              Unable to start or resume execution.
499  *      -ETIME:       A timeout occurred before the DSP responded.
500  *      DSP_EWRONGSTSATE:   Node is not in NODE_PAUSED or NODE_CREATED state.
501  *      -ESPIPE:        Execute function not found in the COFF file.
502  *  Requires:
503  *      node_init(void) called.
504  *  Ensures:
505  */
506 extern int node_run(struct node_object *hnode);
507
508 /*
509  *  ======== node_terminate ========
510  *  Purpose:
511  *      Signal a node running on the DSP that it should exit its execute
512  *      phase function.
513  *  Parameters:
514  *      hnode:              Node object representing a node currently
515  *                          running on the DSP.
516  *      pstatus:            Location to store execute-phase function return
517  *                          value.
518  *  Returns:
519  *      0:            Success.
520  *      -EFAULT:        Invalid hnode.
521  *      -ETIME:       A timeout occurred before the DSP responded.
522  *      -EPERM: Type of node specified cannot be terminated.
523  *              Unable to terminate the node.
524  *      -EBADR:    Operation not valid for the current node state.
525  *  Requires:
526  *      node_init(void) called.
527  *      pstatus != NULL.
528  *  Ensures:
529  */
530 extern int node_terminate(struct node_object *hnode,
531                                  int *pstatus);
532
533 /*
534  *  ======== node_get_uuid_props ========
535  *  Purpose:
536  *      Fetch Node properties given the UUID
537  *  Parameters:
538  *
539  */
540 extern int node_get_uuid_props(void *hprocessor,
541                                       const struct dsp_uuid *node_uuid,
542                                       struct dsp_ndbprops
543                                       *node_props);
544
545 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
546 /**
547  * node_find_addr() - Find the closest symbol to the given address.
548  *
549  * @node_mgr:           Node manager handle
550  * @sym_addr:           Given address to find the closest symbol
551  * @offset_range:               offset range to look fo the closest symbol
552  * @sym_addr_output:    Symbol Output address
553  * @sym_name:           String with the symbol name of the closest symbol
554  *
555  *      This function finds the closest symbol to the address where a MMU
556  *      Fault occurred on the DSP side.
557  */
558 int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
559                                 u32 offset_range, void *sym_addr_output,
560                                 char *sym_name);
561
562 enum node_state node_get_state(void *hnode);
563 #endif
564
565 #endif /* NODE_ */