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