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_ */ 566