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 */
57extern 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 */
86extern 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 */
110extern 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 */
159extern 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 */
186extern 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 */
210extern 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:                Poninter 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 */
234extern 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 */
249extern 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 */
275extern 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 */
297extern 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 */
320extern 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 */
345extern 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 */
360extern 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 */
375void 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 */
394extern 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 */
418extern 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 */
441extern 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 */
466extern 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 */
489extern 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 */
499extern 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/**
506 * node_find_addr() - Find the closest symbol to the given address.
507 *
508 * @node_mgr:		Node manager handle
509 * @sym_addr:		Given address to find the closest symbol
510 * @offset_range:		offset range to look fo the closest symbol
511 * @sym_addr_output:	Symbol Output address
512 * @sym_name:		String with the symbol name of the closest symbol
513 *
514 * 	This function finds the closest symbol to the address where a MMU
515 *	Fault occurred on the DSP side.
516 */
517int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
518				u32 offset_range, void *sym_addr_output,
519				char *sym_name);
520
521enum node_state node_get_state(void *hnode);
522#endif
523
524#endif /* NODE_ */
525