1 /* 2 * dspbridge/src/api/linux/DSPNode.c 3 * 4 * DSP-BIOS Bridge driver support functions for TI OMAP processors. 5 * 6 * Copyright (C) 2007 Texas Instruments, Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU Lesser General Public License as published 10 * by the Free Software Foundation version 2.1 of the License. 11 * 12 * This program is distributed .as is. WITHOUT ANY WARRANTY of any kind, 13 * whether express or implied; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 */ 17 18 19 /* 20 * ======== DSPNode.c ======== 21 * Description: 22 * This is the source for the DSP/BIOS Bridge API node module. The 23 * parameters are validated at the API level, but the bulk of the 24 * work is done at the driver level through the RM NODE module. 25 * 26 * Public Functions: 27 * DSPNode_Allocate 28 * DSPNode_AllocMsgBuf 29 * DSPNode_ChangePriority 30 * DSPNode_Connect 31 * DSPNode_ConnectEx 32 * DSPNode_Create 33 * DSPNode_Delete 34 * DSPNode_FreeMsgBuf 35 * DSPNode_GetAttr 36 * DSPNode_GetMessage 37 * DSPNode_Pause 38 * DSPNode_PutMessage 39 * DSPNode_RegisterNotify 40 * DSPNode_Run 41 * DSPNode_Terminate 42 * 43 *! Revision History 44 *! ================ 45 *! 14-Mar-2002 map Set *pBuffer to null before returning error status in 46 *! DSPNode_AllocMsgBuf. 47 *! 01-Oct-2001 rr CMM error codes are converted to DSP_STATUS in 48 *! DSPNode_Allocate. 49 *! 11-Sep-2001 ag Zero-copy message support. 50 *! 08-Jun-2001 jeh Fixed priority range check in DSPNode_ChangePriority. 51 *! 23-Apr-2001 jeh Added pStatus parameter to DSPNode_Terminate. 52 *! 06-Feb-2001 kc: Added check for alignment value in DSPNode_AllocMsgBuf 53 *! 08-Dec-2000 ag Added alignment to DSPNode_AllocMsgBuf(). 54 *! 05-Dec-2000 ag Added SM support to DSPNode_[Alloc][Free]MsgBuf(). 55 *! 09-Nov-2000 rr: Code cleaned up. Use of IsValidEvent/Mask Macros. 56 *! 27-Oct-2000 jeh Updated to version 0.9 of API spec. 57 *! 07-Sep-2000 jeh Changed type HANDLE in DSPNode_RegisterNotify to 58 *! DSP_HNOTIFICATION. Added DSP_STRMATTR param to 59 *! DSPNode_Connect. 60 *! 04-Aug-2000 rr: Name changed to DSPNode.c 61 *! 27-Jul-2000 rr: Types updated to ver 0.8 API. 62 *! 18-Jul-2000 rr: Node calls into the Class driver. 63 *! Only parameters are validated here. 64 *! 17-May-2000 rr: DSPNode_Connect checks for GHPPNODE. 65 *! 15-May-2000 gp: Made input args to DSPNode_Allocate() CONST. 66 *! Return DSP_ENOTIMPL from DSPNode_ChangePriority(). 67 *! 02-May-2000 rr: Reg functions use SERVICES. 68 *! 12-Apr-2000 ww: Created based on DirectDSP API specification, Version 0.6. 69 * 70 */ 71 72 /* ----------------------------------- Host OS */ 73 #include <host_os.h> 74 #include <stdlib.h> 75 #include <malloc.h> 76 77 /* ----------------------------------- DSP/BIOS Bridge */ 78 #include <dbdefs.h> 79 #include <errbase.h> 80 81 /* ----------------------------------- Trace & Debug */ 82 #include <dbg.h> 83 #include <dbg_zones.h> 84 85 /* ----------------------------------- Resource Manager */ 86 #include <memry.h> 87 88 /* ----------------------------------- Others */ 89 #include <dsptrap.h> 90 91 /* ----------------------------------- This */ 92 #include "_dbdebug.h" 93 #include "_dbpriv.h" 94 95 #include <DSPNode.h> 96 97 #ifdef DEBUG_BRIDGE_PERF 98 #include <perfutils.h> 99 #endif 100 101 /* ----------------------------------- Globals */ 102 extern int hMediaFile; /* class driver handle */ 103 104 /* Declared here, not to users */ 105 DSP_STATUS GetNodeType(DSP_HNODE hNode, DSP_NODETYPE *pNodeType); 106 107 /* 108 * ======== DSPNode_Allocate ======== 109 * Purpose: 110 * Allocate data structures for controlling and communicating 111 * with a node on a specific DSP processor.. 112 */ 113 DBAPI DSPNode_Allocate(DSP_HPROCESSOR hProcessor, 114 IN CONST struct DSP_UUID *pNodeID, 115 IN CONST OPTIONAL struct DSP_CBDATA *pArgs, 116 IN OPTIONAL struct DSP_NODEATTRIN *pAttrIn, 117 OUT DSP_HNODE *phNode) 118 { 119 DSP_STATUS status = DSP_SOK; 120 Trapped_Args tempStruct; 121 struct CMM_OBJECT *hCmm; /* shared memory mngr handle */ 122 struct CMM_INFO pInfo; /* Used for virtual space allocation */ 123 PVOID pVirtBase; 124 struct DSP_BUFFERATTR bufAttr; 125 DSP_NODETYPE nodeType; 126 struct DSP_NDBPROPS nodeProps; 127 UINT heapSize = 0; 128 PVOID pGPPVirtAddr = NULL; 129 UINT uProfileID; 130 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Allocate:\r\n"))); 131 if (!hProcessor) { 132 status = DSP_EHANDLE; 133 DEBUGMSG(DSPAPI_ZONE_ERROR, 134 (TEXT("NODE: DSPNode_Allocate: " 135 "hProcessor is Invalid \r\n"))); 136 goto func_cont; 137 } 138 if (!(pNodeID) || !(phNode)) { 139 status = DSP_EPOINTER; 140 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Allocate: " 141 "Invalid pointer in the Input\r\n"))); 142 goto func_cont; 143 } 144 /* First get the NODE properties, allocate, reserve 145 memory for Node heap */ 146 if (pAttrIn) { 147 status = DSPNode_GetUUIDProps(hProcessor, pNodeID, &nodeProps); 148 pAttrIn->pGPPVirtAddr = NULL; 149 if (DSP_SUCCEEDED(status)) { 150 uProfileID = pAttrIn->uProfileID; 151 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 152 ("DSPNodeAllocate: User requested" 153 "node heap profile \n")); 154 if (uProfileID < nodeProps.uCountProfiles) 155 heapSize = 156 nodeProps.aProfiles[uProfileID].ulHeapSize; 157 if (heapSize) { 158 /* allocate heap memory */ 159 /* Make heap size multiple of page size * */ 160 heapSize = PG_ALIGN_HIGH(heapSize, PG_SIZE_4K); 161 /* align memory on cache line boundary * */ 162 pGPPVirtAddr = memalign(GEM_CACHE_LINE_SIZE, 163 heapSize); 164 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 165 ("DSPNodeAllocate: Node heap memory" 166 "addr, size \n")); 167 if ((pGPPVirtAddr == NULL)) 168 status = DSP_EMEMORY; 169 pAttrIn->uHeapSize = heapSize; 170 pAttrIn->pGPPVirtAddr = pGPPVirtAddr; 171 } 172 } else { 173 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT( 174 "NODE:DSPNode_Allocate: Failed to get Node " 175 "UUID properties \r\n"))); 176 } 177 } 178 if (DSP_SUCCEEDED(status)) { 179 /* Set up the structure Call DSP Trap */ 180 tempStruct.ARGS_NODE_ALLOCATE.hProcessor = hProcessor; 181 tempStruct.ARGS_NODE_ALLOCATE.pNodeID = 182 (struct DSP_UUID *)pNodeID; 183 tempStruct.ARGS_NODE_ALLOCATE.pArgs = 184 (struct DSP_CBDATA *)pArgs; 185 tempStruct.ARGS_NODE_ALLOCATE.pAttrIn = 186 (struct DSP_NODEATTRIN *)pAttrIn; 187 tempStruct.ARGS_NODE_ALLOCATE.phNode = phNode; 188 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_ALLOCATE_OFFSET); 189 } 190 func_cont: 191 /* If 1st SM segment is configured then allocate and map it to 192 this process.*/ 193 if (!DSP_SUCCEEDED(status)) { 194 if (pGPPVirtAddr) 195 free(pGPPVirtAddr); 196 return status; 197 } 198 tempStruct.ARGS_CMM_GETHANDLE.hProcessor = hProcessor; 199 tempStruct.ARGS_CMM_GETHANDLE.phCmmMgr = &hCmm; 200 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETHANDLE_OFFSET); 201 if (DSP_SUCCEEDED(status)) { 202 /* Get SM segment info from CMM */ 203 tempStruct.ARGS_CMM_GETINFO.hCmmMgr = hCmm; 204 tempStruct.ARGS_CMM_GETINFO.pCmmInfo = &pInfo; 205 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETINFO_OFFSET); 206 if (DSP_FAILED(status)) { 207 status = DSP_EFAIL; 208 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT( 209 "NODE: DSPNode_Allocate: " 210 "Failed to get SM segment\r\n"))); 211 } else 212 status = DSP_SOK; 213 214 } else { 215 status = DSP_EFAIL; 216 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT( 217 "NODE: DSPNode_Allocate:Failed to CMM handle\r\n"))); 218 } 219 if (!DSP_SUCCEEDED(status)) { 220 free(pGPPVirtAddr); 221 return status; 222 } 223 224 GetNodeType(*phNode, &nodeType); 225 if ((nodeType != NODE_DEVICE) && (pInfo.ulNumGPPSMSegs > 0)) { 226 /* Messaging uses 1st segment */ 227 if ((pInfo.segInfo[0].dwSegBasePa != 0) && 228 (pInfo.segInfo[0].ulTotalSegSize) > 0) { 229 pVirtBase = mmap(NULL, pInfo.segInfo[0].ulTotalSegSize, 230 PROT_READ | PROT_WRITE, MAP_SHARED | 231 MAP_LOCKED, hMediaFile, 232 pInfo.segInfo[0].dwSegBasePa); 233 if (!pVirtBase) { 234 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: " 235 "DSPNode_Allocate:Virt alloc failed\r\n"))); 236 status = DSP_EMEMORY; 237 /* Clean up */ 238 tempStruct.ARGS_NODE_DELETE.hNode = *phNode; 239 DSPTRAP_Trap(&tempStruct, 240 CMD_NODE_DELETE_OFFSET); 241 return status; 242 } 243 /* set node translator's virt addr range for seg */ 244 bufAttr.uAlignment = 0; 245 bufAttr.uSegment = 1 | MEMRY_SETVIRTUALSEGID; 246 bufAttr.cbStruct = 0; 247 status = DSPNode_AllocMsgBuf(*phNode, 248 pInfo.segInfo[0].ulTotalSegSize, 249 &bufAttr, (BYTE **)&pVirtBase); 250 if (DSP_FAILED(status)) { 251 /* If failed to set segment, unmap */ 252 munmap(pVirtBase, 253 pInfo.segInfo[0].ulTotalSegSize); 254 /* Clean up */ 255 tempStruct.ARGS_NODE_DELETE.hNode = *phNode; 256 DSPTRAP_Trap(&tempStruct, 257 CMD_NODE_DELETE_OFFSET); 258 } 259 } 260 } 261 return status; 262 } 263 264 /* 265 * ======== DSPNode_AllocMsgBuf ======== 266 */ 267 DBAPI DSPNode_AllocMsgBuf(DSP_HNODE hNode, UINT uSize, 268 IN OPTIONAL struct DSP_BUFFERATTR *pAttr, OUT BYTE **pBuffer) 269 { 270 DSP_STATUS status = DSP_SOK; 271 Trapped_Args tempStruct; 272 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 273 (TEXT("NODE: DSPNode_AllocMsgBuf:\r\n"))); 274 275 if (uSize == 0) { 276 status = DSP_ESIZE; 277 if (pBuffer) 278 *pBuffer = NULL; 279 280 } else if (hNode) { 281 if (pBuffer) { 282 /* Set up the structure */ 283 tempStruct.ARGS_NODE_ALLOCMSGBUF.hNode = hNode; 284 tempStruct.ARGS_NODE_ALLOCMSGBUF.uSize = uSize; 285 tempStruct.ARGS_NODE_ALLOCMSGBUF.pAttr = pAttr; 286 /* Va Base */ 287 tempStruct.ARGS_NODE_ALLOCMSGBUF.pBuffer = pBuffer; 288 /* Call DSP Trap */ 289 status = DSPTRAP_Trap(&tempStruct, 290 CMD_NODE_ALLOCMSGBUF_OFFSET); 291 if (DSP_SUCCEEDED(status)) { 292 if (*pBuffer == NULL) { 293 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 294 (TEXT("NODE: DSPNode_AllocMsgBuf: " 295 "No SM\r\n"))); 296 status = DSP_EMEMORY; /* No SM */ 297 } 298 } else 299 *pBuffer = NULL; 300 301 } else { 302 /* Invalid pointer */ 303 status = DSP_EPOINTER; 304 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: " 305 "DSPNode_AllocBuf: Invalid pointer in the Input\r\n"))); 306 } 307 } else { 308 /* Invalid handle */ 309 status = DSP_EHANDLE; 310 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_AllocMsgBuf: " 311 "hNode is Invalid \r\n"))); 312 if (pBuffer) 313 *pBuffer = NULL; 314 315 } 316 317 return status; 318 } 319 320 /* 321 * ======== DSPNode_ChangePriority ======== 322 * Purpose: 323 * Change a task node's runtime priority within the DSP RTOS. 324 */ 325 DBAPI DSPNode_ChangePriority(DSP_HNODE hNode, INT iPriority) 326 { 327 DSP_STATUS status = DSP_SOK; 328 Trapped_Args tempStruct; 329 330 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 331 (TEXT("NODE: DSPNode_ChangePriority:\r\n"))); 332 333 if (hNode) { 334 /* Set up the structure */ 335 if (iPriority >= DSP_NODE_MIN_PRIORITY && 336 iPriority <= DSP_NODE_MAX_PRIORITY) { 337 /* Call DSP Trap */ 338 tempStruct.ARGS_NODE_CHANGEPRIORITY.hNode = hNode; 339 tempStruct.ARGS_NODE_CHANGEPRIORITY.iPriority = 340 iPriority; 341 status = DSPTRAP_Trap(&tempStruct, 342 CMD_NODE_CHANGEPRIORITY_OFFSET); 343 } else 344 status = DSP_ERANGE; 345 346 } else { 347 /* Invalid pointer */ 348 status = DSP_EHANDLE; 349 DEBUGMSG(DSPAPI_ZONE_ERROR, 350 (TEXT("NODE: DSPNode_ChangePriority: " 351 "hNode is Invalid \r\n"))); 352 } 353 354 return status; 355 } 356 357 /* 358 * ======== DSPNode_Connect ======== 359 * Purpose: 360 * Make a stream connection, either between two nodes on a DSP, 361 * or between a node on a DSP and the GPP. 362 */ 363 DBAPI DSPNode_Connect(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode, 364 UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs) 365 { 366 return DSPNode_ConnectEx(hNode, uStream, hOtherNode, uOtherStream, 367 pAttrs, NULL); 368 } 369 370 /* 371 * ======== DSPNode_ConnectEx ======== 372 * Purpose: 373 * Make a stream connection, either between two nodes on a DSP, 374 * or between a node on a DSP and the GPP. 375 */ 376 DBAPI DSPNode_ConnectEx(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode, 377 UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs, 378 IN OPTIONAL struct DSP_CBDATA *pConnParam) 379 { 380 DSP_STATUS status = DSP_SOK; 381 Trapped_Args tempStruct; 382 383 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_ConnectEx:\r\n"))); 384 385 if ((hNode) && (hOtherNode)) { 386 /* Set up the structure */ 387 /* Call DSP Trap */ 388 tempStruct.ARGS_NODE_CONNECT.hNode = hNode; 389 tempStruct.ARGS_NODE_CONNECT.uStream = uStream; 390 tempStruct.ARGS_NODE_CONNECT.hOtherNode = hOtherNode; 391 tempStruct.ARGS_NODE_CONNECT.uOtherStream = uOtherStream; 392 tempStruct.ARGS_NODE_CONNECT.pAttrs = pAttrs; 393 tempStruct.ARGS_NODE_CONNECT.pConnParam = pConnParam; 394 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CONNECT_OFFSET); 395 } else { 396 /* Invalid pointer */ 397 status = DSP_EHANDLE; 398 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Connect: " 399 "hNode or hOtherNode is Invalid Handle\r\n"))); 400 } 401 402 return status; 403 } 404 405 /* 406 * ======== DSPNode_Create ======== 407 * Purpose: 408 * Create a node in a pre-run (i.e., inactive) state on its 409 * DSP processor. 410 */ 411 DBAPI DSPNode_Create(DSP_HNODE hNode) 412 { 413 DSP_STATUS status = DSP_SOK; 414 Trapped_Args tempStruct; 415 #ifdef DEBUG_BRIDGE_PERF 416 struct timeval tv_beg; 417 struct timeval tv_end; 418 struct timezone tz; 419 int timeRetVal = 0; 420 421 timeRetVal = getTimeStamp(&tv_beg); 422 #endif 423 424 425 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Create:\r\n"))); 426 427 if (hNode) { 428 /* Set up the structure */ 429 /* Call DSP Trap */ 430 tempStruct.ARGS_NODE_CREATE.hNode = hNode; 431 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CREATE_OFFSET); 432 } else { 433 /* Invalid pointer */ 434 status = DSP_EHANDLE; 435 DEBUGMSG(DSPAPI_ZONE_ERROR, 436 (TEXT("NODE: DSPNode_Create: hNode is Invalid Handle\r\n"))); 437 } 438 439 #ifdef DEBUG_BRIDGE_PERF 440 timeRetVal = getTimeStamp(&tv_end); 441 PrintStatistics(&tv_beg, &tv_end, "DSPNode_Create", 0); 442 443 #endif 444 445 return status; 446 } 447 448 /* 449 * ======== DSPNode_Delete ======== 450 * Purpose: 451 * Delete all DSP-side and GPP-side resources for the node. 452 */ 453 DBAPI DSPNode_Delete(DSP_HNODE hNode) 454 { 455 DSP_STATUS status = DSP_SOK; 456 Trapped_Args tempStruct; 457 BYTE *pVirtBase = NULL; 458 struct DSP_BUFFERATTR bufAttr; 459 struct CMM_OBJECT *hCmm; /* shared memory mngr handle */ 460 struct CMM_INFO pInfo; /* Used for virtual space allocation */ 461 DSP_NODETYPE nodeType; 462 struct DSP_NODEATTR nodeAttr; 463 #ifdef DEBUG_BRIDGE_PERF 464 struct timeval tv_beg; 465 struct timeval tv_end; 466 struct timezone tz; 467 int timeRetVal = 0; 468 469 timeRetVal = getTimeStamp(&tv_beg); 470 #endif 471 472 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Delete:\r\n"))); 473 if (!hNode) { 474 /* Invalid pointer */ 475 status = DSP_EHANDLE; 476 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: " 477 "hNode is Invalid Handle\r\n"))); 478 return status; 479 } 480 /* Get segment size. 481 >0 is SM segment. Get default SM Mgr*/ 482 tempStruct.ARGS_CMM_GETHANDLE.hProcessor = NULL; 483 tempStruct.ARGS_CMM_GETHANDLE.phCmmMgr = &hCmm; 484 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETHANDLE_OFFSET); 485 if (DSP_SUCCEEDED(status)) { 486 /* Get SM segment info from CMM */ 487 tempStruct.ARGS_CMM_GETINFO.hCmmMgr = hCmm; 488 tempStruct.ARGS_CMM_GETINFO.pCmmInfo = &pInfo; 489 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETINFO_OFFSET); 490 if (DSP_FAILED(status)) { 491 status = DSP_EFAIL; 492 DEBUGMSG(DSPAPI_ZONE_ERROR, 493 (TEXT("NODE: DSPNode_Delete:" 494 " Failed to get SM segment\r\n"))); 495 } else 496 status = DSP_SOK; 497 498 } else { 499 status = DSP_EFAIL; 500 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: " 501 "Failed to CMM handle\r\n"))); 502 } 503 if (!DSP_SUCCEEDED(status)) { 504 status = DSP_EBADSEGID; /* no SM segments*/ 505 return status; 506 } 507 status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr)); 508 GetNodeType(hNode, &nodeType); 509 if (nodeType != NODE_DEVICE) { 510 /*segInfo index starts at 0.These checks may not be required*/ 511 if ((pInfo.segInfo[0].dwSegBasePa != 0) && 512 (pInfo.segInfo[0].ulTotalSegSize) > 0) { 513 /* get node translator's virtual address range 514 so we can free it */ 515 bufAttr.uAlignment = 0; 516 bufAttr.uSegment = 1 | MEMRY_GETVIRTUALSEGID; 517 DSPNode_AllocMsgBuf(hNode, 1, &bufAttr, &pVirtBase); 518 /* Free virtual space */ 519 if (!pVirtBase) 520 goto loop_end; 521 522 if (munmap(pVirtBase, 523 pInfo.segInfo[0].ulTotalSegSize)) { 524 status = DSP_EFAIL; 525 } 526 } 527 } 528 loop_end: 529 if (DSP_SUCCEEDED(status)) { 530 /* Set up the structure Call DSP Trap */ 531 tempStruct.ARGS_NODE_DELETE.hNode = hNode; 532 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_DELETE_OFFSET); 533 /* Free any node heap memory */ 534 if (nodeAttr.inNodeAttrIn.pGPPVirtAddr) { 535 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("DSPNodeDelete:" 536 "Freeing Node heap addr \n"))); 537 free(nodeAttr.inNodeAttrIn.pGPPVirtAddr); 538 } 539 } 540 #ifdef DEBUG_BRIDGE_PERF 541 timeRetVal = getTimeStamp(&tv_end); 542 PrintStatistics(&tv_beg, &tv_end, "DSPNode_Delete", 0); 543 #endif 544 545 return status; 546 } 547 548 /* 549 * ======== DSPNode_FreeMsgBuf ======== 550 */ 551 DBAPI DSPNode_FreeMsgBuf(DSP_HNODE hNode, IN BYTE *pBuffer, 552 IN OPTIONAL struct DSP_BUFFERATTR *pAttr) 553 { 554 DSP_STATUS status = DSP_SOK; 555 Trapped_Args tempStruct; 556 557 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_FreeMsgBuf:\r\n"))); 558 559 if (hNode) { 560 if (pBuffer) { 561 /* Set up the structure */ 562 /* Call DSP Trap */ 563 tempStruct.ARGS_NODE_FREEMSGBUF.hNode = hNode; 564 tempStruct.ARGS_NODE_FREEMSGBUF.pBuffer = pBuffer; 565 tempStruct.ARGS_NODE_FREEMSGBUF.pAttr = pAttr; 566 status = DSPTRAP_Trap(&tempStruct, 567 CMD_NODE_FREEMSGBUF_OFFSET); 568 if (DSP_FAILED(status)) { 569 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: " 570 "DSPNode_FreeMsgBuf:" 571 "Failed to Free SM buf\r\n"))); 572 } 573 } else { 574 /* Invalid parameter */ 575 status = DSP_EPOINTER; 576 DEBUGMSG(DSPAPI_ZONE_ERROR, 577 (TEXT("NODE: DSPNode_FreeMsgBuf: " 578 "Invalid pointer in the Input\r\n"))); 579 } 580 } else { 581 /* Invalid pointer */ 582 status = DSP_EHANDLE; 583 DEBUGMSG(DSPAPI_ZONE_ERROR, 584 (TEXT("NODE: DSPNode_FreeMsgBuf: " 585 "hNode is Invalid \r\n"))); 586 } 587 588 return status; 589 } 590 591 /* 592 * ======== DSPNode_GetAttr ======== 593 * Purpose: 594 * Copy the current attributes of the specified node. 595 */ 596 DBAPI DSPNode_GetAttr(DSP_HNODE hNode, OUT struct DSP_NODEATTR *pAttr, 597 UINT uAttrSize) 598 { 599 DSP_STATUS status = DSP_SOK; 600 Trapped_Args tempStruct; 601 602 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetAttr:\r\n"))); 603 604 if (hNode) { 605 if (pAttr) { 606 if (uAttrSize >= sizeof(struct DSP_NODEATTR)) { 607 /* Set up the structure */ 608 /* Call DSP Trap */ 609 tempStruct.ARGS_NODE_GETATTR.hNode = hNode; 610 tempStruct.ARGS_NODE_GETATTR.pAttr = pAttr; 611 tempStruct.ARGS_NODE_GETATTR.uAttrSize = 612 uAttrSize; 613 status = DSPTRAP_Trap(&tempStruct, 614 CMD_NODE_GETATTR_OFFSET); 615 } else { 616 status = DSP_ESIZE; 617 DEBUGMSG(DSPAPI_ZONE_ERROR, 618 (TEXT("NODE: DSPNode_GetAttr: " 619 "Size is too small \r\n"))); 620 } 621 } else { 622 /* Invalid parameter */ 623 status = DSP_EPOINTER; 624 DEBUGMSG(DSPAPI_ZONE_ERROR, 625 (TEXT("NODE: DSPNode_GetAttr: " 626 "Invalid pointer in the Input\r\n"))); 627 } 628 } else { 629 /* Invalid pointer */ 630 status = DSP_EHANDLE; 631 DEBUGMSG(DSPAPI_ZONE_ERROR, 632 (TEXT("NODE: DSPNode_GetAttr: " 633 "hNode is Invalid \r\n"))); 634 } 635 636 return status; 637 } 638 639 /* 640 * ======== DSPNode_GetMessage ======== 641 * Purpose: 642 * Retrieve an event message from a task node. 643 */ 644 DBAPI DSPNode_GetMessage(DSP_HNODE hNode, OUT struct DSP_MSG *pMessage, 645 UINT uTimeout) 646 { 647 DSP_STATUS status = DSP_SOK; 648 Trapped_Args tempStruct; 649 #ifdef DEBUG_BRIDGE_PERF 650 struct timeval tv_beg; 651 struct timeval tv_end; 652 struct timezone tz; 653 int timeRetVal = 0; 654 655 timeRetVal = getTimeStamp(&tv_beg); 656 657 #endif 658 659 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetMessage:\r\n"))); 660 661 if (hNode) { 662 if (pMessage) { 663 /* Set up the structure */ 664 /* Call DSP Trap */ 665 tempStruct.ARGS_NODE_GETMESSAGE.hNode = hNode; 666 tempStruct.ARGS_NODE_GETMESSAGE.pMessage = pMessage; 667 tempStruct.ARGS_NODE_GETMESSAGE.uTimeout = uTimeout; 668 status = DSPTRAP_Trap(&tempStruct, 669 CMD_NODE_GETMESSAGE_OFFSET); 670 } else { 671 status = DSP_EPOINTER; 672 DEBUGMSG(DSPAPI_ZONE_ERROR, 673 (TEXT("NODE: DSPNode_GetMessage:" 674 "pMessage is Invalid \r\n"))); 675 } 676 } else { 677 status = DSP_EHANDLE; 678 DEBUGMSG(DSPAPI_ZONE_ERROR, 679 (TEXT("NODE: DSPNode_GetMessage: " 680 "hNode is Invalid \r\n"))); 681 } 682 #ifdef DEBUG_BRIDGE_PERF 683 timeRetVal = getTimeStamp(&tv_end); 684 PrintStatistics(&tv_beg, &tv_end, "DSPNode_GetMessage", 0); 685 #endif 686 687 688 return status; 689 } 690 691 /* 692 * ======== GetNodeType ======== 693 * Purpose: 694 * Return the node type 695 */ 696 DSP_STATUS GetNodeType(DSP_HNODE hNode, DSP_NODETYPE *pNodeType) 697 { 698 /*DSP_STATUS status;*/ 699 DSP_STATUS status = DSP_SOK; 700 struct DSP_NODEATTR nodeAttr; 701 702 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("GetNodeType:\r\n"))); 703 704 if (hNode) { 705 status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr)); 706 if (DSP_SUCCEEDED(status)) { 707 *pNodeType = 708 nodeAttr.iNodeInfo.nbNodeDatabaseProps.uNodeType; 709 } 710 } else { 711 status = DSP_EHANDLE; 712 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("GetNodeType: " 713 "hNode is Invalid \r\n"))); 714 } 715 716 return status; 717 } 718 719 /* 720 * ======== DSPNode_Pause ======== 721 * Purpose: 722 * Temporarily suspend execution of a node that is currently running 723 * on a DSP. 724 */ 725 DBAPI DSPNode_Pause(DSP_HNODE hNode) 726 { 727 DSP_STATUS status = DSP_SOK; 728 Trapped_Args tempStruct; 729 730 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Pause:\r\n"))); 731 732 if (hNode) { 733 /* Set up the structure */ 734 /* Call DSP Trap */ 735 tempStruct.ARGS_NODE_PAUSE.hNode = hNode; 736 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_PAUSE_OFFSET); 737 } else { 738 /* Invalid pointer */ 739 status = DSP_EHANDLE; 740 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Pause: " 741 "hNode is Invalid Handle\r\n"))); 742 } 743 744 return status; 745 } 746 747 /* 748 * ======== DSPNode_PutMessage ======== 749 * Purpose: 750 * Send an event message to a task node. 751 */ 752 DBAPI DSPNode_PutMessage(DSP_HNODE hNode, IN CONST struct DSP_MSG *pMessage, 753 UINT uTimeout) 754 { 755 DSP_STATUS status = DSP_SOK; 756 Trapped_Args tempStruct; 757 #ifdef DEBUG_BRIDGE_PERF 758 struct timeval tv_beg; 759 struct timeval tv_end; 760 struct timeval tz; 761 int timeRetVal = 0; 762 763 timeRetVal = getTimeStamp(&tv_beg); 764 #endif 765 766 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_PutMessage:\r\n"))); 767 768 if (hNode) { 769 if (pMessage) { 770 /* Set up the structure */ 771 /* Call DSP Trap */ 772 tempStruct.ARGS_NODE_PUTMESSAGE.hNode = hNode; 773 tempStruct.ARGS_NODE_PUTMESSAGE.pMessage = 774 (struct DSP_MSG *)pMessage; 775 tempStruct.ARGS_NODE_PUTMESSAGE.uTimeout = uTimeout; 776 status = DSPTRAP_Trap(&tempStruct, 777 CMD_NODE_PUTMESSAGE_OFFSET); 778 } else { 779 status = DSP_EPOINTER; 780 DEBUGMSG(DSPAPI_ZONE_ERROR, 781 (TEXT("NODE: DSPNode_PutMessage: " 782 "pMessage is Invalid \r\n"))); 783 } 784 } else { 785 /* Invalid pointer */ 786 status = DSP_EHANDLE; 787 DEBUGMSG(DSPAPI_ZONE_ERROR, 788 (TEXT("NODE: DSPNode_PutMessage: " 789 "hNode is Invalid \r\n"))); 790 } 791 #ifdef DEBUG_BRIDGE_PERF 792 timeRetVal = getTimeStamp(&tv_end); 793 PrintStatistics(&tv_beg, &tv_end, "DSPNode_PutMessage", 0); 794 #endif 795 796 797 return status; 798 } 799 800 /* 801 * ======== DSPNode_RegisterNotify ======== 802 * Purpose: 803 * Register to be notified of specific events for this node. 804 */ 805 DBAPI 806 DSPNode_RegisterNotify(DSP_HNODE hNode, UINT uEventMask, 807 UINT uNotifyType, struct DSP_NOTIFICATION *hNotification) 808 { 809 DSP_STATUS status = DSP_SOK; 810 Trapped_Args tempStruct; 811 812 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 813 (TEXT("NODE: DSPNode_RegisterNotify:\r\n"))); 814 815 if ((hNode) && (hNotification)) { 816 if (IsValidNodeEvent(uEventMask)) { 817 if (IsValidNotifyMask(uNotifyType)) { 818 /* Set up the structure */ 819 /* Call DSP Trap */ 820 tempStruct.ARGS_NODE_REGISTERNOTIFY.hNode = 821 hNode; 822 tempStruct.ARGS_NODE_REGISTERNOTIFY.uEventMask = 823 uEventMask; 824 tempStruct.ARGS_NODE_REGISTERNOTIFY\ 825 .uNotifyType = uNotifyType; 826 tempStruct.ARGS_NODE_REGISTERNOTIFY\ 827 .hNotification = hNotification; 828 829 status = DSPTRAP_Trap(&tempStruct, 830 CMD_NODE_REGISTERNOTIFY_OFFSET); 831 } else { 832 status = DSP_ENOTIMPL; 833 DEBUGMSG(DSPAPI_ZONE_ERROR, 834 (TEXT("NODE: DSPNode_RegisterNotify: " 835 "Invalid Notification Mask \r\n"))); 836 } 837 } else { 838 status = DSP_EVALUE; 839 DEBUGMSG(DSPAPI_ZONE_ERROR, 840 (TEXT("NODE: DSPNode_RegisterNotify:" 841 "Invalid Event type\r\n"))); 842 } 843 } else { 844 /* Invalid pointer */ 845 status = DSP_EHANDLE; 846 DEBUGMSG(DSPAPI_ZONE_ERROR, 847 (TEXT("NODE: DSPNode_RegisterNotify: " 848 "hNode is Invalid \r\n"))); 849 } 850 851 return status; 852 } 853 854 /* 855 * ======== DSPNode_Run ======== 856 * Purpose: 857 * Start a task node running. 858 */ 859 DBAPI DSPNode_Run(DSP_HNODE hNode) 860 { 861 DSP_STATUS status = DSP_SOK; 862 Trapped_Args tempStruct; 863 864 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Run:\r\n"))); 865 866 if (hNode) { 867 /* Set up the structure */ 868 /* Call DSP Trap */ 869 tempStruct.ARGS_NODE_RUN.hNode = hNode; 870 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_RUN_OFFSET); 871 } else { 872 /* Invalid pointer */ 873 status = DSP_EHANDLE; 874 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Run: " 875 "hNode is Invalid Handle\r\n"))); 876 } 877 878 return status; 879 } 880 881 /* 882 * ======== DSPNode_Terminate ======== 883 * Purpose: 884 * Signal a task node running on a DSP processor that it should 885 * exit its execute-phase function. 886 */ 887 DBAPI DSPNode_Terminate(DSP_HNODE hNode, DSP_STATUS *pStatus) 888 { 889 DSP_STATUS status = DSP_SOK; 890 Trapped_Args tempStruct; 891 892 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Terminate:\r\n"))); 893 894 if (hNode) { 895 /* !DSP_ValidWritePtr means it is a valid write ptr */ 896 if (!DSP_ValidWritePtr(pStatus, sizeof(DSP_STATUS))) { 897 /* Set up the structure */ 898 /* Call DSP Trap */ 899 tempStruct.ARGS_NODE_TERMINATE.hNode = hNode; 900 tempStruct.ARGS_NODE_TERMINATE.pStatus = pStatus; 901 status = DSPTRAP_Trap(&tempStruct, 902 CMD_NODE_TERMINATE_OFFSET); 903 } else 904 status = DSP_EPOINTER; 905 906 } else { 907 /* Invalid pointer */ 908 status = DSP_EHANDLE; 909 DEBUGMSG(DSPAPI_ZONE_ERROR, 910 (TEXT("NODE: DSPNode_Terminate: " 911 "hNode is Invalid Handle\r\n"))); 912 } 913 914 return status; 915 } 916 917 918 /* 919 * ======== DSPNode_GetUUIDProps ======== 920 * Purpose: 921 * Get Node properties from DCD/DOF file given the UUID 922 */ 923 DBAPI DSPNode_GetUUIDProps(DSP_HPROCESSOR hProcessor, 924 IN CONST struct DSP_UUID *pNodeID, 925 OUT struct DSP_NDBPROPS *pNodeProps) 926 { 927 DSP_STATUS status = DSP_SOK; 928 Trapped_Args tempStruct; 929 930 DEBUGMSG(DSPAPI_ZONE_FUNCTION, 931 (TEXT("NODE:DSPNode_GetUUIDProps:\r\n"))); 932 933 if (hProcessor) { 934 if ((pNodeID) && (pNodeProps)) { 935 /* Set up the structure */ 936 /* Call DSP Trap */ 937 tempStruct.ARGS_NODE_GETUUIDPROPS.hProcessor = 938 hProcessor; 939 tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeID = 940 (struct DSP_UUID *)pNodeID; 941 tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeProps = 942 (struct DSP_NDBPROPS *) pNodeProps; 943 status = DSPTRAP_Trap(&tempStruct, 944 CMD_NODE_GETUUIDPROPS_OFFSET); 945 } else { 946 /* Invalid parameter */ 947 status = DSP_EPOINTER; 948 DEBUGMSG(DSPAPI_ZONE_ERROR, 949 (TEXT("NODE: DSPNode_GetUUIDProps: " 950 "Invalid pointer in the Input\r\n"))); 951 } 952 } else { 953 /* Invalid pointer */ 954 status = DSP_EHANDLE; 955 DEBUGMSG(DSPAPI_ZONE_ERROR, 956 (TEXT("NODE: DSPNode_GetUUIDProps: " 957 "hProcessor is Invalid \r\n"))); 958 } 959 960 return status; 961 } 962 963