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/dispdefs.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 occured, 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 */ 58extern 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 */ 88extern 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 */ 113extern int node_change_priority(struct node_object *hnode, s32 prio); 114 115/* 116 * ======== node_close_orphans ======== 117 * Purpose: 118 * Delete all nodes whose owning processor is being destroyed. 119 * Parameters: 120 * hnode_mgr: Node manager object. 121 * proc: Handle to processor object being destroyed. 122 * Returns: 123 * 0: Success. 124 * -EPERM: Unable to delete all nodes belonging to proc. 125 * Requires: 126 * Valid hnode_mgr. 127 * proc != NULL. 128 * Ensures: 129 */ 130extern int node_close_orphans(struct node_mgr *hnode_mgr, 131 struct proc_object *proc); 132 133/* 134 * ======== node_connect ======== 135 * Purpose: 136 * Connect two nodes on the DSP, or a node on the DSP to the GPP. In the 137 * case that the connnection is being made between a node on the DSP and 138 * the GPP, one of the node handles (either node1 or node2) must be 139 * the constant NODE_HGPPNODE. 140 * Parameters: 141 * node1: Handle of first node to connect to second node. If 142 * this is a connection from the GPP to node2, node1 143 * must be the constant NODE_HGPPNODE. Otherwise, node1 144 * must be a node handle returned from a successful call 145 * to Node_Allocate(). 146 * node2: Handle of second node. Must be either NODE_HGPPNODE 147 * if this is a connection from DSP node to GPP, or a 148 * node handle returned from a successful call to 149 * node_allocate(). 150 * stream1: Output stream index on first node, to be connected 151 * to second node's input stream. Value must range from 152 * 0 <= stream1 < number of output streams. 153 * stream2: Input stream index on second node. Value must range 154 * from 0 <= stream2 < number of input streams. 155 * pattrs: Stream attributes (NULL ==> use defaults). 156 * conn_param: A pointer to a dsp_cbdata structure that defines 157 * connection parameter for device nodes to pass to DSP 158 * side. 159 * If the value of this parameter is NULL, then this API 160 * behaves like DSPNode_Connect. This parameter will have 161 * length of the string and the null terminated string in 162 * dsp_cbdata struct. This can be extended in future tp 163 * pass binary data. 164 * Returns: 165 * 0: Success. 166 * -EFAULT: Invalid node1 or node2. 167 * -ENOMEM: Insufficient host memory. 168 * -EINVAL: A stream index parameter is invalid. 169 * -EISCONN: A connection already exists for one of the 170 * indices stream1 or stream2. 171 * -EBADR: Either node1 or node2 is not in the 172 * NODE_ALLOCATED state. 173 * -ECONNREFUSED: No more connections available. 174 * -EPERM: Attempt to make an illegal connection (eg, 175 * Device node to device node, or device node to 176 * GPP), the two nodes are on different DSPs. 177 * Requires: 178 * node_init(void) called. 179 * Ensures: 180 */ 181extern int node_connect(struct node_object *node1, 182 u32 stream1, 183 struct node_object *node2, 184 u32 stream2, 185 struct dsp_strmattr *pattrs, 186 struct dsp_cbdata 187 *conn_param); 188 189/* 190 * ======== node_create ======== 191 * Purpose: 192 * Create a node on the DSP by remotely calling the node's create 193 * function. If necessary, load code that contains the node's create 194 * function. 195 * Parameters: 196 * hnode: Node handle returned from node_allocate(). 197 * Returns: 198 * 0: Success. 199 * -EFAULT: Invalid hnode. 200 * -ESPIPE: Create function not found in the COFF file. 201 * -EBADR: Node is not in the NODE_ALLOCATED state. 202 * -ENOMEM: Memory allocation failure on the DSP. 203 * -ETIME: A timeout occurred before the DSP responded. 204 * -EPERM: A failure occurred, unable to create node. 205 * Requires: 206 * node_init(void) called. 207 * Ensures: 208 */ 209extern int node_create(struct node_object *hnode); 210 211/* 212 * ======== node_create_mgr ======== 213 * Purpose: 214 * Create a NODE Manager object. This object handles the creation, 215 * deletion, and execution of nodes on the DSP target. The NODE Manager 216 * also maintains a pipe map of used and available node connections. 217 * Each DEV object should have exactly one NODE Manager object. 218 * 219 * Parameters: 220 * node_man: Location to store node manager handle on output. 221 * hdev_obj: Device for this processor. 222 * Returns: 223 * 0: Success; 224 * -ENOMEM: Insufficient memory for requested resources. 225 * -EPERM: General failure. 226 * Requires: 227 * node_init(void) called. 228 * node_man != NULL. 229 * hdev_obj != NULL. 230 * Ensures: 231 * 0: Valide *node_man. 232 * error: *node_man == NULL. 233 */ 234extern int node_create_mgr(struct node_mgr **node_man, 235 struct dev_object *hdev_obj); 236 237/* 238 * ======== node_delete ======== 239 * Purpose: 240 * Delete resources allocated in node_allocate(). If the node was 241 * created, delete the node on the DSP by remotely calling the node's 242 * delete function. Loads the node's delete function if necessary. 243 * GPP side resources are freed after node's delete function returns. 244 * Parameters: 245 * noderes: Node resource info handle returned from 246 * node_allocate(). 247 * pr_ctxt: Poninter to process context data. 248 * Returns: 249 * 0: Success. 250 * -EFAULT: Invalid hnode. 251 * -ETIME: A timeout occurred before the DSP responded. 252 * -EPERM: A failure occurred in deleting the node. 253 * -ESPIPE: Delete function not found in the COFF file. 254 * Requires: 255 * node_init(void) called. 256 * Ensures: 257 * 0: hnode is invalid. 258 */ 259extern int node_delete(struct node_res_object *noderes, 260 struct process_context *pr_ctxt); 261 262/* 263 * ======== node_delete_mgr ======== 264 * Purpose: 265 * Delete the NODE Manager. 266 * Parameters: 267 * hnode_mgr: Node manager object. 268 * Returns: 269 * 0: Success. 270 * Requires: 271 * node_init(void) called. 272 * Valid hnode_mgr. 273 * Ensures: 274 */ 275extern int node_delete_mgr(struct node_mgr *hnode_mgr); 276 277/* 278 * ======== node_enum_nodes ======== 279 * Purpose: 280 * Enumerate the nodes currently allocated for the DSP. 281 * Parameters: 282 * hnode_mgr: Node manager returned from node_create_mgr(). 283 * node_tab: Array to copy node handles into. 284 * node_tab_size: Number of handles that can be written to node_tab. 285 * pu_num_nodes: Location where number of node handles written to 286 * node_tab will be written. 287 * pu_allocated: Location to write total number of allocated nodes. 288 * Returns: 289 * 0: Success. 290 * -EINVAL: node_tab is too small to hold all node handles. 291 * Requires: 292 * Valid hnode_mgr. 293 * node_tab != NULL || node_tab_size == 0. 294 * pu_num_nodes != NULL. 295 * pu_allocated != NULL. 296 * Ensures: 297 * - (-EINVAL && *pu_num_nodes == 0) 298 * - || (0 && *pu_num_nodes <= node_tab_size) && 299 * (*pu_allocated == *pu_num_nodes) 300 */ 301extern int node_enum_nodes(struct node_mgr *hnode_mgr, 302 void **node_tab, 303 u32 node_tab_size, 304 u32 *pu_num_nodes, 305 u32 *pu_allocated); 306 307/* 308 * ======== node_exit ======== 309 * Purpose: 310 * Discontinue usage of NODE module. 311 * Parameters: 312 * Returns: 313 * Requires: 314 * node_init(void) successfully called before. 315 * Ensures: 316 * Any resources acquired in node_init(void) will be freed when last NODE 317 * client calls node_exit(void). 318 */ 319extern void node_exit(void); 320 321/* 322 * ======== node_free_msg_buf ======== 323 * Purpose: 324 * Free a message buffer previously allocated with node_alloc_msg_buf. 325 * Parameters: 326 * hnode: The node handle. 327 * pbuffer: (Address) Buffer allocated by node_alloc_msg_buf. 328 * pattr: Same buffer attributes passed to node_alloc_msg_buf. 329 * Returns: 330 * 0: Success. 331 * -EFAULT: Invalid node handle. 332 * -EPERM: Failure to free the buffer. 333 * Requires: 334 * node_init(void) called. 335 * pbuffer != NULL. 336 * Ensures: 337 */ 338extern int node_free_msg_buf(struct node_object *hnode, 339 u8 *pbuffer, 340 struct dsp_bufferattr 341 *pattr); 342 343/* 344 * ======== node_get_attr ======== 345 * Purpose: 346 * Copy the current attributes of the specified node into a dsp_nodeattr 347 * structure. 348 * Parameters: 349 * hnode: Node object allocated from node_allocate(). 350 * pattr: Pointer to dsp_nodeattr structure to copy node's 351 * attributes. 352 * attr_size: Size of pattr. 353 * Returns: 354 * 0: Success. 355 * -EFAULT: Invalid hnode. 356 * Requires: 357 * node_init(void) called. 358 * pattr != NULL. 359 * Ensures: 360 * 0: *pattrs contains the node's current attributes. 361 */ 362extern int node_get_attr(struct node_object *hnode, 363 struct dsp_nodeattr *pattr, u32 attr_size); 364 365/* 366 * ======== node_get_message ======== 367 * Purpose: 368 * Retrieve a message from a node on the DSP. The node must be either a 369 * message node, task node, or XDAIS socket node. 370 * If a message is not available, this function will block until a 371 * message is available, or the node's timeout value is reached. 372 * Parameters: 373 * hnode: Node handle returned from node_allocate(). 374 * message: Pointer to dsp_msg structure to copy the 375 * message into. 376 * utimeout: Timeout in milliseconds to wait for message. 377 * Returns: 378 * 0: Success. 379 * -EFAULT: Invalid hnode. 380 * -EPERM: Cannot retrieve messages from this type of node. 381 * Error occurred while trying to retrieve a message. 382 * -ETIME: Timeout occurred and no message is available. 383 * Requires: 384 * node_init(void) called. 385 * message != NULL. 386 * Ensures: 387 */ 388extern int node_get_message(struct node_object *hnode, 389 struct dsp_msg *message, u32 utimeout); 390 391/* 392 * ======== node_get_nldr_obj ======== 393 * Purpose: 394 * Retrieve the Nldr manager 395 * Parameters: 396 * hnode_mgr: Node Manager 397 * nldr_ovlyobj: Pointer to a Nldr manager handle 398 * Returns: 399 * 0: Success. 400 * -EFAULT: Invalid hnode. 401 * Ensures: 402 */ 403extern int node_get_nldr_obj(struct node_mgr *hnode_mgr, 404 struct nldr_object **nldr_ovlyobj); 405 406/* 407 * ======== node_init ======== 408 * Purpose: 409 * Initialize the NODE module. 410 * Parameters: 411 * Returns: 412 * TRUE if initialization succeeded, FALSE otherwise. 413 * Ensures: 414 */ 415extern bool node_init(void); 416 417/* 418 * ======== node_on_exit ======== 419 * Purpose: 420 * Gets called when RMS_EXIT is received for a node. PROC needs to pass 421 * this function as a parameter to msg_create(). This function then gets 422 * called by the Bridge driver when an exit message for a node is received. 423 * Parameters: 424 * hnode: Handle of the node that the exit message is for. 425 * node_status: Return status of the node's execute phase. 426 * Returns: 427 * Ensures: 428 */ 429void node_on_exit(struct node_object *hnode, s32 node_status); 430 431/* 432 * ======== node_pause ======== 433 * Purpose: 434 * Suspend execution of a node currently running on the DSP. 435 * Parameters: 436 * hnode: Node object representing a node currently 437 * running on the DSP. 438 * Returns: 439 * 0: Success. 440 * -EFAULT: Invalid hnode. 441 * -EPERM: Node is not a task or socket node. 442 * Failed to pause node. 443 * -ETIME: A timeout occurred before the DSP responded. 444 * DSP_EWRONGSTSATE: Node is not in NODE_RUNNING state. 445 * Requires: 446 * node_init(void) called. 447 * Ensures: 448 */ 449extern int node_pause(struct node_object *hnode); 450 451/* 452 * ======== node_put_message ======== 453 * Purpose: 454 * Send a message to a message node, task node, or XDAIS socket node. 455 * This function will block until the message stream can accommodate 456 * the message, or a timeout occurs. The message will be copied, so Msg 457 * can be re-used immediately after return. 458 * Parameters: 459 * hnode: Node handle returned by node_allocate(). 460 * pmsg: Location of message to be sent to the node. 461 * utimeout: Timeout in msecs to wait. 462 * Returns: 463 * 0: Success. 464 * -EFAULT: Invalid hnode. 465 * -EPERM: Messages can't be sent to this type of node. 466 * Unable to send message. 467 * -ETIME: Timeout occurred before message could be set. 468 * -EBADR: Node is in invalid state for sending messages. 469 * Requires: 470 * node_init(void) called. 471 * pmsg != NULL. 472 * Ensures: 473 */ 474extern int node_put_message(struct node_object *hnode, 475 const struct dsp_msg *pmsg, u32 utimeout); 476 477/* 478 * ======== node_register_notify ======== 479 * Purpose: 480 * Register to be notified on specific events for this node. 481 * Parameters: 482 * hnode: Node handle returned by node_allocate(). 483 * event_mask: Mask of types of events to be notified about. 484 * notify_type: Type of notification to be sent. 485 * hnotification: Handle to be used for notification. 486 * Returns: 487 * 0: Success. 488 * -EFAULT: Invalid hnode. 489 * -ENOMEM: Insufficient memory on GPP. 490 * -EINVAL: event_mask is invalid. 491 * -ENOSYS: Notification type specified by notify_type is not 492 * supported. 493 * Requires: 494 * node_init(void) called. 495 * hnotification != NULL. 496 * Ensures: 497 */ 498extern int node_register_notify(struct node_object *hnode, 499 u32 event_mask, u32 notify_type, 500 struct dsp_notification 501 *hnotification); 502 503/* 504 * ======== node_run ======== 505 * Purpose: 506 * Start execution of a node's execute phase, or resume execution of 507 * a node that has been suspended (via node_pause()) on the DSP. Load 508 * the node's execute function if necessary. 509 * Parameters: 510 * hnode: Node object representing a node currently 511 * running on the DSP. 512 * Returns: 513 * 0: Success. 514 * -EFAULT: Invalid hnode. 515 * -EPERM: hnode doesn't represent a message, task or dais socket node. 516 * Unable to start or resume execution. 517 * -ETIME: A timeout occurred before the DSP responded. 518 * DSP_EWRONGSTSATE: Node is not in NODE_PAUSED or NODE_CREATED state. 519 * -ESPIPE: Execute function not found in the COFF file. 520 * Requires: 521 * node_init(void) called. 522 * Ensures: 523 */ 524extern int node_run(struct node_object *hnode); 525 526/* 527 * ======== node_terminate ======== 528 * Purpose: 529 * Signal a node running on the DSP that it should exit its execute 530 * phase function. 531 * Parameters: 532 * hnode: Node object representing a node currently 533 * running on the DSP. 534 * pstatus: Location to store execute-phase function return 535 * value. 536 * Returns: 537 * 0: Success. 538 * -EFAULT: Invalid hnode. 539 * -ETIME: A timeout occurred before the DSP responded. 540 * -EPERM: Type of node specified cannot be terminated. 541 * Unable to terminate the node. 542 * -EBADR: Operation not valid for the current node state. 543 * Requires: 544 * node_init(void) called. 545 * pstatus != NULL. 546 * Ensures: 547 */ 548extern int node_terminate(struct node_object *hnode, 549 int *pstatus); 550 551/* 552 * ======== node_get_uuid_props ======== 553 * Purpose: 554 * Fetch Node properties given the UUID 555 * Parameters: 556 * 557 */ 558extern int node_get_uuid_props(void *hprocessor, 559 const struct dsp_uuid *node_uuid, 560 struct dsp_ndbprops 561 *node_props); 562 563#ifdef CONFIG_TIDSPBRIDGE_BACKTRACE 564/** 565 * node_find_addr() - Find the closest symbol to the given address. 566 * 567 * @node_mgr: Node manager handle 568 * @sym_addr: Given address to find the closest symbol 569 * @offset_range: offset range to look fo the closest symbol 570 * @sym_addr_output: Symbol Output address 571 * @sym_name: String with the symbol name of the closest symbol 572 * 573 * This function finds the closest symbol to the address where a MMU 574 * Fault occurred on the DSP side. 575 */ 576int node_find_addr(struct node_mgr *node_mgr, u32 sym_addr, 577 u32 offset_range, void *sym_addr_output, 578 char *sym_name); 579 580enum node_state node_get_state(void *hnode); 581#endif 582 583#endif /* NODE_ */ 584