4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
6 * DSP/BIOS Bridge Node Manager.
8 * Copyright (C) 2005-2006 Texas Instruments, Inc.
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.
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.
22 #include <dspbridge/procpriv.h>
24 #include <dspbridge/nodedefs.h>
25 #include <dspbridge/disp.h>
26 #include <dspbridge/nldrdefs.h>
27 #include <dspbridge/drv.h>
30 * ======== node_allocate ========
32 * Allocate GPP resources to manage a node on the DSP.
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,
39 * noderes: Location to store node resource info.
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
47 * -EPERM: A failure occurred, unable to allocate node.
48 * -EBADR: Proccessor is not in the running state.
54 * 0: IsValidNode(*ph_node).
55 * error: *noderes == NULL.
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
62 struct node_res_object **noderes,
63 struct process_context *pr_ctxt);
66 * ======== node_alloc_msg_buf ========
68 * Allocate and Prepare a buffer whose descriptor will be passed to a
69 * Node within a (dsp_msg)message
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
78 * -EFAULT: Invalid node handle.
79 * -ENOMEM: Insufficent memory.
80 * -EPERM: General Failure.
81 * -EINVAL: Invalid Size.
86 extern int node_alloc_msg_buf(struct node_object *hnode,
87 u32 usize, struct dsp_bufferattr
88 *pattr, u8 **pbuffer);
91 * ======== node_change_priority ========
93 * Change the priority of an allocated node.
95 * hnode: Node handle returned from node_allocate.
96 * prio: New priority level to set node's priority to.
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.
108 * 0 && (Node's current priority == prio)
110 extern int node_change_priority(struct node_object *hnode, s32 prio);
113 * ======== node_connect ========
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.
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
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
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
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.
159 extern int node_connect(struct node_object *node1,
161 struct node_object *node2,
163 struct dsp_strmattr *pattrs,
168 * ======== node_create ========
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
174 * hnode: Node handle returned from node_allocate().
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.
186 extern int node_create(struct node_object *hnode);
189 * ======== node_create_mgr ========
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.
197 * node_man: Location to store node manager handle on output.
198 * hdev_obj: Device for this processor.
201 * -ENOMEM: Insufficient memory for requested resources.
202 * -EPERM: General failure.
207 * 0: Valide *node_man.
208 * error: *node_man == NULL.
210 extern int node_create_mgr(struct node_mgr **node_man,
211 struct dev_object *hdev_obj);
214 * ======== node_delete ========
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.
221 * noderes: Node resource info handle returned from
223 * pr_ctxt: Pointer to process context data.
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.
232 * 0: hnode is invalid.
234 extern int node_delete(struct node_res_object *noderes,
235 struct process_context *pr_ctxt);
238 * ======== node_delete_mgr ========
240 * Delete the NODE Manager.
242 * hnode_mgr: Node manager object.
249 extern int node_delete_mgr(struct node_mgr *hnode_mgr);
252 * ======== node_enum_nodes ========
254 * Enumerate the nodes currently allocated for the DSP.
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.
264 * -EINVAL: node_tab is too small to hold all node handles.
267 * node_tab != NULL || node_tab_size == 0.
268 * pu_num_nodes != NULL.
269 * pu_allocated != NULL.
271 * - (-EINVAL && *pu_num_nodes == 0)
272 * - || (0 && *pu_num_nodes <= node_tab_size) &&
273 * (*pu_allocated == *pu_num_nodes)
275 extern int node_enum_nodes(struct node_mgr *hnode_mgr,
282 * ======== node_free_msg_buf ========
284 * Free a message buffer previously allocated with node_alloc_msg_buf.
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.
291 * -EFAULT: Invalid node handle.
292 * -EPERM: Failure to free the buffer.
297 extern int node_free_msg_buf(struct node_object *hnode,
299 struct dsp_bufferattr
303 * ======== node_get_attr ========
305 * Copy the current attributes of the specified node into a dsp_nodeattr
308 * hnode: Node object allocated from node_allocate().
309 * pattr: Pointer to dsp_nodeattr structure to copy node's
311 * attr_size: Size of pattr.
314 * -EFAULT: Invalid hnode.
318 * 0: *pattrs contains the node's current attributes.
320 extern int node_get_attr(struct node_object *hnode,
321 struct dsp_nodeattr *pattr, u32 attr_size);
324 * ======== node_get_message ========
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.
331 * hnode: Node handle returned from node_allocate().
332 * message: Pointer to dsp_msg structure to copy the
334 * utimeout: Timeout in milliseconds to wait for message.
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.
345 extern int node_get_message(struct node_object *hnode,
346 struct dsp_msg *message, u32 utimeout);
349 * ======== node_get_nldr_obj ========
351 * Retrieve the Nldr manager
353 * hnode_mgr: Node Manager
354 * nldr_ovlyobj: Pointer to a Nldr manager handle
357 * -EFAULT: Invalid hnode.
360 extern int node_get_nldr_obj(struct node_mgr *hnode_mgr,
361 struct nldr_object **nldr_ovlyobj);
364 * ======== node_on_exit ========
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.
370 * hnode: Handle of the node that the exit message is for.
371 * node_status: Return status of the node's execute phase.
375 void node_on_exit(struct node_object *hnode, s32 node_status);
378 * ======== node_pause ========
380 * Suspend execution of a node currently running on the DSP.
382 * hnode: Node object representing a node currently
383 * running on the DSP.
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.
394 extern int node_pause(struct node_object *hnode);
397 * ======== node_put_message ========
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.
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.
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.
418 extern int node_put_message(struct node_object *hnode,
419 const struct dsp_msg *pmsg, u32 utimeout);
422 * ======== node_register_notify ========
424 * Register to be notified on specific events for this node.
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.
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
438 * hnotification != NULL.
441 extern int node_register_notify(struct node_object *hnode,
442 u32 event_mask, u32 notify_type,
443 struct dsp_notification
447 * ======== node_run ========
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.
453 * hnode: Node object representing a node currently
454 * running on the DSP.
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.
466 extern int node_run(struct node_object *hnode);
469 * ======== node_terminate ========
471 * Signal a node running on the DSP that it should exit its execute
474 * hnode: Node object representing a node currently
475 * running on the DSP.
476 * pstatus: Location to store execute-phase function return
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.
489 extern int node_terminate(struct node_object *hnode,
493 * ======== node_get_uuid_props ========
495 * Fetch Node properties given the UUID
499 extern int node_get_uuid_props(void *hprocessor,
500 const struct dsp_uuid *node_uuid,
504 #ifdef CONFIG_TIDSPBRIDGE_BACKTRACE
506 * node_find_addr() - Find the closest symbol to the given address.
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
514 * This function finds the closest symbol to the address where a MMU
515 * Fault occurred on the DSP side.
517 int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr,
518 u32 offset_range, void *sym_addr_output,
521 enum node_state node_get_state(void *hnode);