Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
node.h
Go to the documentation of this file.
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  * hprocessor != NULL.
51  * node_uuid != NULL.
52  * noderes != NULL.
53  * Ensures:
54  * 0: IsValidNode(*ph_node).
55  * error: *noderes == NULL.
56  */
57 extern int node_allocate(struct proc_object *hprocessor,
58  const struct dsp_uuid *node_uuid,
59  const struct dsp_cbdata
60  *pargs, const struct dsp_nodeattrin
61  *attr_in,
62  struct node_res_object **noderes,
63  struct process_context *pr_ctxt);
64 
65 /*
66  * ======== node_alloc_msg_buf ========
67  * Purpose:
68  * Allocate and Prepare a buffer whose descriptor will be passed to a
69  * Node within a (dsp_msg)message
70  * Parameters:
71  * hnode: The node handle.
72  * usize: The size of the buffer to be allocated.
73  * pattr: Pointer to a dsp_bufferattr structure.
74  * pbuffer: Location to store the address of the allocated
75  * buffer on output.
76  * Returns:
77  * 0: Success.
78  * -EFAULT: Invalid node handle.
79  * -ENOMEM: Insufficent memory.
80  * -EPERM: General Failure.
81  * -EINVAL: Invalid Size.
82  * Requires:
83  * pbuffer != NULL.
84  * Ensures:
85  */
86 extern int node_alloc_msg_buf(struct node_object *hnode,
87  u32 usize, struct dsp_bufferattr
88  *pattr, u8 **pbuffer);
89 
90 /*
91  * ======== node_change_priority ========
92  * Purpose:
93  * Change the priority of an allocated node.
94  * Parameters:
95  * hnode: Node handle returned from node_allocate.
96  * prio: New priority level to set node's priority to.
97  * Returns:
98  * 0: Success.
99  * -EFAULT: Invalid hnode.
100  * -EDOM: prio is out of range.
101  * -EPERM: The specified node is not a task node.
102  * Unable to change node's runtime priority level.
103  * -EBADR: Node is not in the NODE_ALLOCATED, NODE_PAUSED,
104  * or NODE_RUNNING state.
105  * -ETIME: A timeout occurred before the DSP responded.
106  * Requires:
107  * Ensures:
108  * 0 && (Node's current priority == prio)
109  */
110 extern int node_change_priority(struct node_object *hnode, s32 prio);
111 
112 /*
113  * ======== node_connect ========
114  * Purpose:
115  * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the
116  * case that the connection is being made between a node on the DSP and
117  * the GPP, one of the node handles (either node1 or node2) must be
118  * the constant NODE_HGPPNODE.
119  * Parameters:
120  * node1: Handle of first node to connect to second node. If
121  * this is a connection from the GPP to node2, node1
122  * must be the constant NODE_HGPPNODE. Otherwise, node1
123  * must be a node handle returned from a successful call
124  * to Node_Allocate().
125  * node2: Handle of second node. Must be either NODE_HGPPNODE
126  * if this is a connection from DSP node to GPP, or a
127  * node handle returned from a successful call to
128  * node_allocate().
129  * stream1: Output stream index on first node, to be connected
130  * to second node's input stream. Value must range from
131  * 0 <= stream1 < number of output streams.
132  * stream2: Input stream index on second node. Value must range
133  * from 0 <= stream2 < number of input streams.
134  * pattrs: Stream attributes (NULL ==> use defaults).
135  * conn_param: A pointer to a dsp_cbdata structure that defines
136  * connection parameter for device nodes to pass to DSP
137  * side.
138  * If the value of this parameter is NULL, then this API
139  * behaves like DSPNode_Connect. This parameter will have
140  * length of the string and the null terminated string in
141  * dsp_cbdata struct. This can be extended in future tp
142  * pass binary data.
143  * Returns:
144  * 0: Success.
145  * -EFAULT: Invalid node1 or node2.
146  * -ENOMEM: Insufficient host memory.
147  * -EINVAL: A stream index parameter is invalid.
148  * -EISCONN: A connection already exists for one of the
149  * indices stream1 or stream2.
150  * -EBADR: Either node1 or node2 is not in the
151  * NODE_ALLOCATED state.
152  * -ECONNREFUSED: No more connections available.
153  * -EPERM: Attempt to make an illegal connection (eg,
154  * Device node to device node, or device node to
155  * GPP), the two nodes are on different DSPs.
156  * Requires:
157  * Ensures:
158  */
159 extern int node_connect(struct node_object *node1,
160  u32 stream1,
161  struct node_object *node2,
162  u32 stream2,
163  struct dsp_strmattr *pattrs,
164  struct dsp_cbdata
165  *conn_param);
166 
167 /*
168  * ======== node_create ========
169  * Purpose:
170  * Create a node on the DSP by remotely calling the node's create
171  * function. If necessary, load code that contains the node's create
172  * function.
173  * Parameters:
174  * hnode: Node handle returned from node_allocate().
175  * Returns:
176  * 0: Success.
177  * -EFAULT: Invalid hnode.
178  * -ESPIPE: Create function not found in the COFF file.
179  * -EBADR: Node is not in the NODE_ALLOCATED state.
180  * -ENOMEM: Memory allocation failure on the DSP.
181  * -ETIME: A timeout occurred before the DSP responded.
182  * -EPERM: A failure occurred, unable to create node.
183  * Requires:
184  * Ensures:
185  */
186 extern int node_create(struct node_object *hnode);
187 
188 /*
189  * ======== node_create_mgr ========
190  * Purpose:
191  * Create a NODE Manager object. This object handles the creation,
192  * deletion, and execution of nodes on the DSP target. The NODE Manager
193  * also maintains a pipe map of used and available node connections.
194  * Each DEV object should have exactly one NODE Manager object.
195  *
196  * Parameters:
197  * node_man: Location to store node manager handle on output.
198  * hdev_obj: Device for this processor.
199  * Returns:
200  * 0: Success;
201  * -ENOMEM: Insufficient memory for requested resources.
202  * -EPERM: General failure.
203  * Requires:
204  * node_man != NULL.
205  * hdev_obj != NULL.
206  * Ensures:
207  * 0: Valide *node_man.
208  * error: *node_man == NULL.
209  */
210 extern int node_create_mgr(struct node_mgr **node_man,
211  struct dev_object *hdev_obj);
212 
213 /*
214  * ======== node_delete ========
215  * Purpose:
216  * Delete resources allocated in node_allocate(). If the node was
217  * created, delete the node on the DSP by remotely calling the node's
218  * delete function. Loads the node's delete function if necessary.
219  * GPP side resources are freed after node's delete function returns.
220  * Parameters:
221  * noderes: Node resource info handle returned from
222  * node_allocate().
223  * pr_ctxt: Pointer to process context data.
224  * Returns:
225  * 0: Success.
226  * -EFAULT: Invalid hnode.
227  * -ETIME: A timeout occurred before the DSP responded.
228  * -EPERM: A failure occurred in deleting the node.
229  * -ESPIPE: Delete function not found in the COFF file.
230  * Requires:
231  * Ensures:
232  * 0: hnode is invalid.
233  */
234 extern int node_delete(struct node_res_object *noderes,
235  struct process_context *pr_ctxt);
236 
237 /*
238  * ======== node_delete_mgr ========
239  * Purpose:
240  * Delete the NODE Manager.
241  * Parameters:
242  * hnode_mgr: Node manager object.
243  * Returns:
244  * 0: Success.
245  * Requires:
246  * Valid hnode_mgr.
247  * Ensures:
248  */
249 extern int node_delete_mgr(struct node_mgr *hnode_mgr);
250 
251 /*
252  * ======== node_enum_nodes ========
253  * Purpose:
254  * Enumerate the nodes currently allocated for the DSP.
255  * Parameters:
256  * hnode_mgr: Node manager returned from node_create_mgr().
257  * node_tab: Array to copy node handles into.
258  * node_tab_size: Number of handles that can be written to node_tab.
259  * pu_num_nodes: Location where number of node handles written to
260  * node_tab will be written.
261  * pu_allocated: Location to write total number of allocated nodes.
262  * Returns:
263  * 0: Success.
264  * -EINVAL: node_tab is too small to hold all node handles.
265  * Requires:
266  * Valid hnode_mgr.
267  * node_tab != NULL || node_tab_size == 0.
268  * pu_num_nodes != NULL.
269  * pu_allocated != NULL.
270  * Ensures:
271  * - (-EINVAL && *pu_num_nodes == 0)
272  * - || (0 && *pu_num_nodes <= node_tab_size) &&
273  * (*pu_allocated == *pu_num_nodes)
274  */
275 extern int node_enum_nodes(struct node_mgr *hnode_mgr,
276  void **node_tab,
277  u32 node_tab_size,
278  u32 *pu_num_nodes,
279  u32 *pu_allocated);
280 
281 /*
282  * ======== node_free_msg_buf ========
283  * Purpose:
284  * Free a message buffer previously allocated with node_alloc_msg_buf.
285  * Parameters:
286  * hnode: The node handle.
287  * pbuffer: (Address) Buffer allocated by node_alloc_msg_buf.
288  * pattr: Same buffer attributes passed to node_alloc_msg_buf.
289  * Returns:
290  * 0: Success.
291  * -EFAULT: Invalid node handle.
292  * -EPERM: Failure to free the buffer.
293  * Requires:
294  * pbuffer != NULL.
295  * Ensures:
296  */
297 extern int node_free_msg_buf(struct node_object *hnode,
298  u8 *pbuffer,
299  struct dsp_bufferattr
300  *pattr);
301 
302 /*
303  * ======== node_get_attr ========
304  * Purpose:
305  * Copy the current attributes of the specified node into a dsp_nodeattr
306  * structure.
307  * Parameters:
308  * hnode: Node object allocated from node_allocate().
309  * pattr: Pointer to dsp_nodeattr structure to copy node's
310  * attributes.
311  * attr_size: Size of pattr.
312  * Returns:
313  * 0: Success.
314  * -EFAULT: Invalid hnode.
315  * Requires:
316  * pattr != NULL.
317  * Ensures:
318  * 0: *pattrs contains the node's current attributes.
319  */
320 extern int node_get_attr(struct node_object *hnode,
321  struct dsp_nodeattr *pattr, u32 attr_size);
322 
323 /*
324  * ======== node_get_message ========
325  * Purpose:
326  * Retrieve a message from a node on the DSP. The node must be either a
327  * message node, task node, or XDAIS socket node.
328  * If a message is not available, this function will block until a
329  * message is available, or the node's timeout value is reached.
330  * Parameters:
331  * hnode: Node handle returned from node_allocate().
332  * message: Pointer to dsp_msg structure to copy the
333  * message into.
334  * utimeout: Timeout in milliseconds to wait for message.
335  * Returns:
336  * 0: Success.
337  * -EFAULT: Invalid hnode.
338  * -EPERM: Cannot retrieve messages from this type of node.
339  * Error occurred while trying to retrieve a message.
340  * -ETIME: Timeout occurred and no message is available.
341  * Requires:
342  * message != NULL.
343  * Ensures:
344  */
345 extern int node_get_message(struct node_object *hnode,
346  struct dsp_msg *message, u32 utimeout);
347 
348 /*
349  * ======== node_get_nldr_obj ========
350  * Purpose:
351  * Retrieve the Nldr manager
352  * Parameters:
353  * hnode_mgr: Node Manager
354  * nldr_ovlyobj: Pointer to a Nldr manager handle
355  * Returns:
356  * 0: Success.
357  * -EFAULT: Invalid hnode.
358  * Ensures:
359  */
360 extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
361  struct nldr_object **nldr_ovlyobj);
362 
363 /*
364  * ======== node_on_exit ========
365  * Purpose:
366  * Gets called when RMS_EXIT is received for a node. PROC needs to pass
367  * this function as a parameter to msg_create(). This function then gets
368  * called by the Bridge driver when an exit message for a node is received.
369  * Parameters:
370  * hnode: Handle of the node that the exit message is for.
371  * node_status: Return status of the node's execute phase.
372  * Returns:
373  * Ensures:
374  */
375 void node_on_exit(struct node_object *hnode, s32 node_status);
376 
377 /*
378  * ======== node_pause ========
379  * Purpose:
380  * Suspend execution of a node currently running on the DSP.
381  * Parameters:
382  * hnode: Node object representing a node currently
383  * running on the DSP.
384  * Returns:
385  * 0: Success.
386  * -EFAULT: Invalid hnode.
387  * -EPERM: Node is not a task or socket node.
388  * Failed to pause node.
389  * -ETIME: A timeout occurred before the DSP responded.
390  * DSP_EWRONGSTSATE: Node is not in NODE_RUNNING state.
391  * Requires:
392  * Ensures:
393  */
394 extern int node_pause(struct node_object *hnode);
395 
396 /*
397  * ======== node_put_message ========
398  * Purpose:
399  * Send a message to a message node, task node, or XDAIS socket node.
400  * This function will block until the message stream can accommodate
401  * the message, or a timeout occurs. The message will be copied, so Msg
402  * can be re-used immediately after return.
403  * Parameters:
404  * hnode: Node handle returned by node_allocate().
405  * pmsg: Location of message to be sent to the node.
406  * utimeout: Timeout in msecs to wait.
407  * Returns:
408  * 0: Success.
409  * -EFAULT: Invalid hnode.
410  * -EPERM: Messages can't be sent to this type of node.
411  * Unable to send message.
412  * -ETIME: Timeout occurred before message could be set.
413  * -EBADR: Node is in invalid state for sending messages.
414  * Requires:
415  * pmsg != NULL.
416  * Ensures:
417  */
418 extern int node_put_message(struct node_object *hnode,
419  const struct dsp_msg *pmsg, u32 utimeout);
420 
421 /*
422  * ======== node_register_notify ========
423  * Purpose:
424  * Register to be notified on specific events for this node.
425  * Parameters:
426  * hnode: Node handle returned by node_allocate().
427  * event_mask: Mask of types of events to be notified about.
428  * notify_type: Type of notification to be sent.
429  * hnotification: Handle to be used for notification.
430  * Returns:
431  * 0: Success.
432  * -EFAULT: Invalid hnode.
433  * -ENOMEM: Insufficient memory on GPP.
434  * -EINVAL: event_mask is invalid.
435  * -ENOSYS: Notification type specified by notify_type is not
436  * supported.
437  * Requires:
438  * hnotification != NULL.
439  * Ensures:
440  */
441 extern int node_register_notify(struct node_object *hnode,
442  u32 event_mask, u32 notify_type,
443  struct dsp_notification
444  *hnotification);
445 
446 /*
447  * ======== node_run ========
448  * Purpose:
449  * Start execution of a node's execute phase, or resume execution of
450  * a node that has been suspended (via node_pause()) on the DSP. Load
451  * the node's execute function if necessary.
452  * Parameters:
453  * hnode: Node object representing a node currently
454  * running on the DSP.
455  * Returns:
456  * 0: Success.
457  * -EFAULT: Invalid hnode.
458  * -EPERM: hnode doesn't represent a message, task or dais socket node.
459  * Unable to start or resume execution.
460  * -ETIME: A timeout occurred before the DSP responded.
461  * DSP_EWRONGSTSATE: Node is not in NODE_PAUSED or NODE_CREATED state.
462  * -ESPIPE: Execute function not found in the COFF file.
463  * Requires:
464  * Ensures:
465  */
466 extern int node_run(struct node_object *hnode);
467 
468 /*
469  * ======== node_terminate ========
470  * Purpose:
471  * Signal a node running on the DSP that it should exit its execute
472  * phase function.
473  * Parameters:
474  * hnode: Node object representing a node currently
475  * running on the DSP.
476  * pstatus: Location to store execute-phase function return
477  * value.
478  * Returns:
479  * 0: Success.
480  * -EFAULT: Invalid hnode.
481  * -ETIME: A timeout occurred before the DSP responded.
482  * -EPERM: Type of node specified cannot be terminated.
483  * Unable to terminate the node.
484  * -EBADR: Operation not valid for the current node state.
485  * Requires:
486  * pstatus != NULL.
487  * Ensures:
488  */
489 extern int node_terminate(struct node_object *hnode,
490  int *pstatus);
491 
492 /*
493  * ======== node_get_uuid_props ========
494  * Purpose:
495  * Fetch Node properties given the UUID
496  * Parameters:
497  *
498  */
499 extern int node_get_uuid_props(void *hprocessor,
500  const struct dsp_uuid *node_uuid,
501  struct dsp_ndbprops
502  *node_props);
503 
504 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
505 
517 int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
518  u32 offset_range, void *sym_addr_output,
519  char *sym_name);
520 
521 enum node_state node_get_state(void *hnode);
522 #endif
523 
524 #endif /* NODE_ */