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 */
DSPNode_Allocate(DSP_HPROCESSOR hProcessor,IN CONST struct DSP_UUID * pNodeID,IN CONST OPTIONAL struct DSP_CBDATA * pArgs,IN OPTIONAL struct DSP_NODEATTRIN * pAttrIn,OUT DSP_HNODE * phNode)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 return status;
221
222 GetNodeType(*phNode, &nodeType);
223 if ((nodeType != NODE_DEVICE) && (pInfo.ulNumGPPSMSegs > 0)) {
224 /* Messaging uses 1st segment */
225 if ((pInfo.segInfo[0].dwSegBasePa != 0) &&
226 (pInfo.segInfo[0].ulTotalSegSize) > 0) {
227 pVirtBase = mmap(NULL, pInfo.segInfo[0].ulTotalSegSize,
228 PROT_READ | PROT_WRITE, MAP_SHARED |
229 MAP_LOCKED, hMediaFile,
230 pInfo.segInfo[0].dwSegBasePa);
231 if (!pVirtBase) {
232 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: "
233 "DSPNode_Allocate:Virt alloc failed\r\n")));
234 status = DSP_EMEMORY;
235 /* Clean up */
236 tempStruct.ARGS_NODE_DELETE.hNode = *phNode;
237 DSPTRAP_Trap(&tempStruct,
238 CMD_NODE_DELETE_OFFSET);
239 return status;
240 }
241 /* set node translator's virt addr range for seg */
242 bufAttr.uAlignment = 0;
243 bufAttr.uSegment = 1 | MEMRY_SETVIRTUALSEGID;
244 bufAttr.cbStruct = 0;
245 status = DSPNode_AllocMsgBuf(*phNode,
246 pInfo.segInfo[0].ulTotalSegSize,
247 &bufAttr, (BYTE **)&pVirtBase);
248 if (DSP_FAILED(status)) {
249 /* If failed to set segment, unmap */
250 munmap(pVirtBase,
251 pInfo.segInfo[0].ulTotalSegSize);
252 /* Clean up */
253 tempStruct.ARGS_NODE_DELETE.hNode = *phNode;
254 DSPTRAP_Trap(&tempStruct,
255 CMD_NODE_DELETE_OFFSET);
256 }
257 }
258 }
259 return status;
260 }
261
262 /*
263 * ======== DSPNode_AllocMsgBuf ========
264 */
DSPNode_AllocMsgBuf(DSP_HNODE hNode,UINT uSize,IN OPTIONAL struct DSP_BUFFERATTR * pAttr,OUT BYTE ** pBuffer)265 DBAPI DSPNode_AllocMsgBuf(DSP_HNODE hNode, UINT uSize,
266 IN OPTIONAL struct DSP_BUFFERATTR *pAttr, OUT BYTE **pBuffer)
267 {
268 DSP_STATUS status = DSP_SOK;
269 Trapped_Args tempStruct;
270 DEBUGMSG(DSPAPI_ZONE_FUNCTION,
271 (TEXT("NODE: DSPNode_AllocMsgBuf:\r\n")));
272
273 if (uSize == 0) {
274 status = DSP_ESIZE;
275 if (pBuffer)
276 *pBuffer = NULL;
277
278 } else if (hNode) {
279 if (pBuffer) {
280 /* Set up the structure */
281 tempStruct.ARGS_NODE_ALLOCMSGBUF.hNode = hNode;
282 tempStruct.ARGS_NODE_ALLOCMSGBUF.uSize = uSize;
283 tempStruct.ARGS_NODE_ALLOCMSGBUF.pAttr = pAttr;
284 /* Va Base */
285 tempStruct.ARGS_NODE_ALLOCMSGBUF.pBuffer = pBuffer;
286 /* Call DSP Trap */
287 status = DSPTRAP_Trap(&tempStruct,
288 CMD_NODE_ALLOCMSGBUF_OFFSET);
289 if (DSP_SUCCEEDED(status)) {
290 if (*pBuffer == NULL) {
291 DEBUGMSG(DSPAPI_ZONE_FUNCTION,
292 (TEXT("NODE: DSPNode_AllocMsgBuf: "
293 "No SM\r\n")));
294 status = DSP_EMEMORY; /* No SM */
295 }
296 } else
297 *pBuffer = NULL;
298
299 } else {
300 /* Invalid pointer */
301 status = DSP_EPOINTER;
302 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: "
303 "DSPNode_AllocBuf: Invalid pointer in the Input\r\n")));
304 }
305 } else {
306 /* Invalid handle */
307 status = DSP_EHANDLE;
308 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_AllocMsgBuf: "
309 "hNode is Invalid \r\n")));
310 if (pBuffer)
311 *pBuffer = NULL;
312
313 }
314
315 return status;
316 }
317
318 /*
319 * ======== DSPNode_ChangePriority ========
320 * Purpose:
321 * Change a task node's runtime priority within the DSP RTOS.
322 */
DSPNode_ChangePriority(DSP_HNODE hNode,INT iPriority)323 DBAPI DSPNode_ChangePriority(DSP_HNODE hNode, INT iPriority)
324 {
325 DSP_STATUS status = DSP_SOK;
326 Trapped_Args tempStruct;
327
328 DEBUGMSG(DSPAPI_ZONE_FUNCTION,
329 (TEXT("NODE: DSPNode_ChangePriority:\r\n")));
330
331 if (hNode) {
332 /* Set up the structure */
333 if (iPriority >= DSP_NODE_MIN_PRIORITY &&
334 iPriority <= DSP_NODE_MAX_PRIORITY) {
335 /* Call DSP Trap */
336 tempStruct.ARGS_NODE_CHANGEPRIORITY.hNode = hNode;
337 tempStruct.ARGS_NODE_CHANGEPRIORITY.iPriority =
338 iPriority;
339 status = DSPTRAP_Trap(&tempStruct,
340 CMD_NODE_CHANGEPRIORITY_OFFSET);
341 } else
342 status = DSP_ERANGE;
343
344 } else {
345 /* Invalid pointer */
346 status = DSP_EHANDLE;
347 DEBUGMSG(DSPAPI_ZONE_ERROR,
348 (TEXT("NODE: DSPNode_ChangePriority: "
349 "hNode is Invalid \r\n")));
350 }
351
352 return status;
353 }
354
355 /*
356 * ======== DSPNode_Connect ========
357 * Purpose:
358 * Make a stream connection, either between two nodes on a DSP,
359 * or between a node on a DSP and the GPP.
360 */
DSPNode_Connect(DSP_HNODE hNode,UINT uStream,DSP_HNODE hOtherNode,UINT uOtherStream,IN OPTIONAL struct DSP_STRMATTR * pAttrs)361 DBAPI DSPNode_Connect(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode,
362 UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs)
363 {
364 return DSPNode_ConnectEx(hNode, uStream, hOtherNode, uOtherStream,
365 pAttrs, NULL);
366 }
367
368 /*
369 * ======== DSPNode_ConnectEx ========
370 * Purpose:
371 * Make a stream connection, either between two nodes on a DSP,
372 * or between a node on a DSP and the GPP.
373 */
DSPNode_ConnectEx(DSP_HNODE hNode,UINT uStream,DSP_HNODE hOtherNode,UINT uOtherStream,IN OPTIONAL struct DSP_STRMATTR * pAttrs,IN OPTIONAL struct DSP_CBDATA * pConnParam)374 DBAPI DSPNode_ConnectEx(DSP_HNODE hNode, UINT uStream, DSP_HNODE hOtherNode,
375 UINT uOtherStream, IN OPTIONAL struct DSP_STRMATTR *pAttrs,
376 IN OPTIONAL struct DSP_CBDATA *pConnParam)
377 {
378 DSP_STATUS status = DSP_SOK;
379 Trapped_Args tempStruct;
380
381 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_ConnectEx:\r\n")));
382
383 if ((hNode) && (hOtherNode)) {
384 /* Set up the structure */
385 /* Call DSP Trap */
386 tempStruct.ARGS_NODE_CONNECT.hNode = hNode;
387 tempStruct.ARGS_NODE_CONNECT.uStream = uStream;
388 tempStruct.ARGS_NODE_CONNECT.hOtherNode = hOtherNode;
389 tempStruct.ARGS_NODE_CONNECT.uOtherStream = uOtherStream;
390 tempStruct.ARGS_NODE_CONNECT.pAttrs = pAttrs;
391 tempStruct.ARGS_NODE_CONNECT.pConnParam = pConnParam;
392 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CONNECT_OFFSET);
393 } else {
394 /* Invalid pointer */
395 status = DSP_EHANDLE;
396 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Connect: "
397 "hNode or hOtherNode is Invalid Handle\r\n")));
398 }
399
400 return status;
401 }
402
403 /*
404 * ======== DSPNode_Create ========
405 * Purpose:
406 * Create a node in a pre-run (i.e., inactive) state on its
407 * DSP processor.
408 */
DSPNode_Create(DSP_HNODE hNode)409 DBAPI DSPNode_Create(DSP_HNODE hNode)
410 {
411 DSP_STATUS status = DSP_SOK;
412 Trapped_Args tempStruct;
413 #ifdef DEBUG_BRIDGE_PERF
414 struct timeval tv_beg;
415 struct timeval tv_end;
416 struct timezone tz;
417 int timeRetVal = 0;
418
419 timeRetVal = getTimeStamp(&tv_beg);
420 #endif
421
422
423 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Create:\r\n")));
424
425 if (hNode) {
426 /* Set up the structure */
427 /* Call DSP Trap */
428 tempStruct.ARGS_NODE_CREATE.hNode = hNode;
429 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_CREATE_OFFSET);
430 } else {
431 /* Invalid pointer */
432 status = DSP_EHANDLE;
433 DEBUGMSG(DSPAPI_ZONE_ERROR,
434 (TEXT("NODE: DSPNode_Create: hNode is Invalid Handle\r\n")));
435 }
436
437 #ifdef DEBUG_BRIDGE_PERF
438 timeRetVal = getTimeStamp(&tv_end);
439 PrintStatistics(&tv_beg, &tv_end, "DSPNode_Create", 0);
440
441 #endif
442
443 return status;
444 }
445
446 /*
447 * ======== DSPNode_Delete ========
448 * Purpose:
449 * Delete all DSP-side and GPP-side resources for the node.
450 */
DSPNode_Delete(DSP_HNODE hNode)451 DBAPI DSPNode_Delete(DSP_HNODE hNode)
452 {
453 DSP_STATUS status = DSP_SOK;
454 Trapped_Args tempStruct;
455 BYTE *pVirtBase = NULL;
456 struct DSP_BUFFERATTR bufAttr;
457 struct CMM_OBJECT *hCmm; /* shared memory mngr handle */
458 struct CMM_INFO pInfo; /* Used for virtual space allocation */
459 DSP_NODETYPE nodeType;
460 struct DSP_NODEATTR nodeAttr;
461 #ifdef DEBUG_BRIDGE_PERF
462 struct timeval tv_beg;
463 struct timeval tv_end;
464 struct timezone tz;
465 int timeRetVal = 0;
466
467 timeRetVal = getTimeStamp(&tv_beg);
468 #endif
469
470 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Delete:\r\n")));
471 if (!hNode) {
472 /* Invalid pointer */
473 status = DSP_EHANDLE;
474 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: "
475 "hNode is Invalid Handle\r\n")));
476 return status;
477 }
478 /* Get segment size.
479 >0 is SM segment. Get default SM Mgr*/
480 tempStruct.ARGS_CMM_GETHANDLE.hProcessor = NULL;
481 tempStruct.ARGS_CMM_GETHANDLE.phCmmMgr = &hCmm;
482 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETHANDLE_OFFSET);
483 if (DSP_SUCCEEDED(status)) {
484 /* Get SM segment info from CMM */
485 tempStruct.ARGS_CMM_GETINFO.hCmmMgr = hCmm;
486 tempStruct.ARGS_CMM_GETINFO.pCmmInfo = &pInfo;
487 status = DSPTRAP_Trap(&tempStruct, CMD_CMM_GETINFO_OFFSET);
488 if (DSP_FAILED(status)) {
489 status = DSP_EFAIL;
490 DEBUGMSG(DSPAPI_ZONE_ERROR,
491 (TEXT("NODE: DSPNode_Delete:"
492 " Failed to get SM segment\r\n")));
493 } else
494 status = DSP_SOK;
495
496 } else {
497 status = DSP_EFAIL;
498 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Delete: "
499 "Failed to CMM handle\r\n")));
500 }
501 if (!DSP_SUCCEEDED(status)) {
502 status = DSP_EBADSEGID; /* no SM segments*/
503 return status;
504 }
505 status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr));
506 GetNodeType(hNode, &nodeType);
507 if (nodeType != NODE_DEVICE) {
508 /*segInfo index starts at 0.These checks may not be required*/
509 if ((pInfo.segInfo[0].dwSegBasePa != 0) &&
510 (pInfo.segInfo[0].ulTotalSegSize) > 0) {
511 /* get node translator's virtual address range
512 so we can free it */
513 bufAttr.uAlignment = 0;
514 bufAttr.uSegment = 1 | MEMRY_GETVIRTUALSEGID;
515 DSPNode_AllocMsgBuf(hNode, 1, &bufAttr, &pVirtBase);
516 /* Free virtual space */
517 if (!pVirtBase)
518 goto loop_end;
519
520 if (munmap(pVirtBase,
521 pInfo.segInfo[0].ulTotalSegSize)) {
522 status = DSP_EFAIL;
523 }
524 }
525 }
526 loop_end:
527 if (DSP_SUCCEEDED(status)) {
528 /* Set up the structure Call DSP Trap */
529 tempStruct.ARGS_NODE_DELETE.hNode = hNode;
530 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_DELETE_OFFSET);
531 /* Free any node heap memory */
532 if (nodeAttr.inNodeAttrIn.pGPPVirtAddr) {
533 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("DSPNodeDelete:"
534 "Freeing Node heap addr \n")));
535 free(nodeAttr.inNodeAttrIn.pGPPVirtAddr);
536 }
537 }
538 #ifdef DEBUG_BRIDGE_PERF
539 timeRetVal = getTimeStamp(&tv_end);
540 PrintStatistics(&tv_beg, &tv_end, "DSPNode_Delete", 0);
541 #endif
542
543 return status;
544 }
545
546 /*
547 * ======== DSPNode_FreeMsgBuf ========
548 */
DSPNode_FreeMsgBuf(DSP_HNODE hNode,IN BYTE * pBuffer,IN OPTIONAL struct DSP_BUFFERATTR * pAttr)549 DBAPI DSPNode_FreeMsgBuf(DSP_HNODE hNode, IN BYTE *pBuffer,
550 IN OPTIONAL struct DSP_BUFFERATTR *pAttr)
551 {
552 DSP_STATUS status = DSP_SOK;
553 Trapped_Args tempStruct;
554
555 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_FreeMsgBuf:\r\n")));
556
557 if (hNode) {
558 if (pBuffer) {
559 /* Set up the structure */
560 /* Call DSP Trap */
561 tempStruct.ARGS_NODE_FREEMSGBUF.hNode = hNode;
562 tempStruct.ARGS_NODE_FREEMSGBUF.pBuffer = pBuffer;
563 tempStruct.ARGS_NODE_FREEMSGBUF.pAttr = pAttr;
564 status = DSPTRAP_Trap(&tempStruct,
565 CMD_NODE_FREEMSGBUF_OFFSET);
566 if (DSP_FAILED(status)) {
567 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: "
568 "DSPNode_FreeMsgBuf:"
569 "Failed to Free SM buf\r\n")));
570 }
571 } else {
572 /* Invalid parameter */
573 status = DSP_EPOINTER;
574 DEBUGMSG(DSPAPI_ZONE_ERROR,
575 (TEXT("NODE: DSPNode_FreeMsgBuf: "
576 "Invalid pointer in the Input\r\n")));
577 }
578 } else {
579 /* Invalid pointer */
580 status = DSP_EHANDLE;
581 DEBUGMSG(DSPAPI_ZONE_ERROR,
582 (TEXT("NODE: DSPNode_FreeMsgBuf: "
583 "hNode is Invalid \r\n")));
584 }
585
586 return status;
587 }
588
589 /*
590 * ======== DSPNode_GetAttr ========
591 * Purpose:
592 * Copy the current attributes of the specified node.
593 */
DSPNode_GetAttr(DSP_HNODE hNode,OUT struct DSP_NODEATTR * pAttr,UINT uAttrSize)594 DBAPI DSPNode_GetAttr(DSP_HNODE hNode, OUT struct DSP_NODEATTR *pAttr,
595 UINT uAttrSize)
596 {
597 DSP_STATUS status = DSP_SOK;
598 Trapped_Args tempStruct;
599
600 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetAttr:\r\n")));
601
602 if (hNode) {
603 if (pAttr) {
604 if (uAttrSize >= sizeof(struct DSP_NODEATTR)) {
605 /* Set up the structure */
606 /* Call DSP Trap */
607 tempStruct.ARGS_NODE_GETATTR.hNode = hNode;
608 tempStruct.ARGS_NODE_GETATTR.pAttr = pAttr;
609 tempStruct.ARGS_NODE_GETATTR.uAttrSize =
610 uAttrSize;
611 status = DSPTRAP_Trap(&tempStruct,
612 CMD_NODE_GETATTR_OFFSET);
613 } else {
614 status = DSP_ESIZE;
615 DEBUGMSG(DSPAPI_ZONE_ERROR,
616 (TEXT("NODE: DSPNode_GetAttr: "
617 "Size is too small \r\n")));
618 }
619 } else {
620 /* Invalid parameter */
621 status = DSP_EPOINTER;
622 DEBUGMSG(DSPAPI_ZONE_ERROR,
623 (TEXT("NODE: DSPNode_GetAttr: "
624 "Invalid pointer in the Input\r\n")));
625 }
626 } else {
627 /* Invalid pointer */
628 status = DSP_EHANDLE;
629 DEBUGMSG(DSPAPI_ZONE_ERROR,
630 (TEXT("NODE: DSPNode_GetAttr: "
631 "hNode is Invalid \r\n")));
632 }
633
634 return status;
635 }
636
637 /*
638 * ======== DSPNode_GetMessage ========
639 * Purpose:
640 * Retrieve an event message from a task node.
641 */
DSPNode_GetMessage(DSP_HNODE hNode,OUT struct DSP_MSG * pMessage,UINT uTimeout)642 DBAPI DSPNode_GetMessage(DSP_HNODE hNode, OUT struct DSP_MSG *pMessage,
643 UINT uTimeout)
644 {
645 DSP_STATUS status = DSP_SOK;
646 Trapped_Args tempStruct;
647 #ifdef DEBUG_BRIDGE_PERF
648 struct timeval tv_beg;
649 struct timeval tv_end;
650 struct timezone tz;
651 int timeRetVal = 0;
652
653 timeRetVal = getTimeStamp(&tv_beg);
654
655 #endif
656
657 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_GetMessage:\r\n")));
658
659 if (hNode) {
660 if (pMessage) {
661 /* Set up the structure */
662 /* Call DSP Trap */
663 tempStruct.ARGS_NODE_GETMESSAGE.hNode = hNode;
664 tempStruct.ARGS_NODE_GETMESSAGE.pMessage = pMessage;
665 tempStruct.ARGS_NODE_GETMESSAGE.uTimeout = uTimeout;
666 status = DSPTRAP_Trap(&tempStruct,
667 CMD_NODE_GETMESSAGE_OFFSET);
668 } else {
669 status = DSP_EPOINTER;
670 DEBUGMSG(DSPAPI_ZONE_ERROR,
671 (TEXT("NODE: DSPNode_GetMessage:"
672 "pMessage is Invalid \r\n")));
673 }
674 } else {
675 status = DSP_EHANDLE;
676 DEBUGMSG(DSPAPI_ZONE_ERROR,
677 (TEXT("NODE: DSPNode_GetMessage: "
678 "hNode is Invalid \r\n")));
679 }
680 #ifdef DEBUG_BRIDGE_PERF
681 timeRetVal = getTimeStamp(&tv_end);
682 PrintStatistics(&tv_beg, &tv_end, "DSPNode_GetMessage", 0);
683 #endif
684
685
686 return status;
687 }
688
689 /*
690 * ======== GetNodeType ========
691 * Purpose:
692 * Return the node type
693 */
GetNodeType(DSP_HNODE hNode,DSP_NODETYPE * pNodeType)694 DSP_STATUS GetNodeType(DSP_HNODE hNode, DSP_NODETYPE *pNodeType)
695 {
696 /*DSP_STATUS status;*/
697 DSP_STATUS status = DSP_SOK;
698 struct DSP_NODEATTR nodeAttr;
699
700 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("GetNodeType:\r\n")));
701
702 if (hNode) {
703 status = DSPNode_GetAttr(hNode, &nodeAttr, sizeof(nodeAttr));
704 if (DSP_SUCCEEDED(status)) {
705 *pNodeType =
706 nodeAttr.iNodeInfo.nbNodeDatabaseProps.uNodeType;
707 }
708 } else {
709 status = DSP_EHANDLE;
710 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("GetNodeType: "
711 "hNode is Invalid \r\n")));
712 }
713
714 return status;
715 }
716
717 /*
718 * ======== DSPNode_Pause ========
719 * Purpose:
720 * Temporarily suspend execution of a node that is currently running
721 * on a DSP.
722 */
DSPNode_Pause(DSP_HNODE hNode)723 DBAPI DSPNode_Pause(DSP_HNODE hNode)
724 {
725 DSP_STATUS status = DSP_SOK;
726 Trapped_Args tempStruct;
727
728 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Pause:\r\n")));
729
730 if (hNode) {
731 /* Set up the structure */
732 /* Call DSP Trap */
733 tempStruct.ARGS_NODE_PAUSE.hNode = hNode;
734 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_PAUSE_OFFSET);
735 } else {
736 /* Invalid pointer */
737 status = DSP_EHANDLE;
738 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Pause: "
739 "hNode is Invalid Handle\r\n")));
740 }
741
742 return status;
743 }
744
745 /*
746 * ======== DSPNode_PutMessage ========
747 * Purpose:
748 * Send an event message to a task node.
749 */
DSPNode_PutMessage(DSP_HNODE hNode,IN CONST struct DSP_MSG * pMessage,UINT uTimeout)750 DBAPI DSPNode_PutMessage(DSP_HNODE hNode, IN CONST struct DSP_MSG *pMessage,
751 UINT uTimeout)
752 {
753 DSP_STATUS status = DSP_SOK;
754 Trapped_Args tempStruct;
755 #ifdef DEBUG_BRIDGE_PERF
756 struct timeval tv_beg;
757 struct timeval tv_end;
758 struct timeval tz;
759 int timeRetVal = 0;
760
761 timeRetVal = getTimeStamp(&tv_beg);
762 #endif
763
764 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_PutMessage:\r\n")));
765
766 if (hNode) {
767 if (pMessage) {
768 /* Set up the structure */
769 /* Call DSP Trap */
770 tempStruct.ARGS_NODE_PUTMESSAGE.hNode = hNode;
771 tempStruct.ARGS_NODE_PUTMESSAGE.pMessage =
772 (struct DSP_MSG *)pMessage;
773 tempStruct.ARGS_NODE_PUTMESSAGE.uTimeout = uTimeout;
774 status = DSPTRAP_Trap(&tempStruct,
775 CMD_NODE_PUTMESSAGE_OFFSET);
776 } else {
777 status = DSP_EPOINTER;
778 DEBUGMSG(DSPAPI_ZONE_ERROR,
779 (TEXT("NODE: DSPNode_PutMessage: "
780 "pMessage is Invalid \r\n")));
781 }
782 } else {
783 /* Invalid pointer */
784 status = DSP_EHANDLE;
785 DEBUGMSG(DSPAPI_ZONE_ERROR,
786 (TEXT("NODE: DSPNode_PutMessage: "
787 "hNode is Invalid \r\n")));
788 }
789 #ifdef DEBUG_BRIDGE_PERF
790 timeRetVal = getTimeStamp(&tv_end);
791 PrintStatistics(&tv_beg, &tv_end, "DSPNode_PutMessage", 0);
792 #endif
793
794
795 return status;
796 }
797
798 /*
799 * ======== DSPNode_RegisterNotify ========
800 * Purpose:
801 * Register to be notified of specific events for this node.
802 */
803 DBAPI
DSPNode_RegisterNotify(DSP_HNODE hNode,UINT uEventMask,UINT uNotifyType,struct DSP_NOTIFICATION * hNotification)804 DSPNode_RegisterNotify(DSP_HNODE hNode, UINT uEventMask,
805 UINT uNotifyType, struct DSP_NOTIFICATION *hNotification)
806 {
807 DSP_STATUS status = DSP_SOK;
808 Trapped_Args tempStruct;
809
810 DEBUGMSG(DSPAPI_ZONE_FUNCTION,
811 (TEXT("NODE: DSPNode_RegisterNotify:\r\n")));
812
813 if ((hNode) && (hNotification)) {
814 if (IsValidNodeEvent(uEventMask)) {
815 if (IsValidNotifyMask(uNotifyType)) {
816 /* Set up the structure */
817 /* Call DSP Trap */
818 tempStruct.ARGS_NODE_REGISTERNOTIFY.hNode =
819 hNode;
820 tempStruct.ARGS_NODE_REGISTERNOTIFY.uEventMask =
821 uEventMask;
822 tempStruct.ARGS_NODE_REGISTERNOTIFY\
823 .uNotifyType = uNotifyType;
824 tempStruct.ARGS_NODE_REGISTERNOTIFY\
825 .hNotification = hNotification;
826
827 status = DSPTRAP_Trap(&tempStruct,
828 CMD_NODE_REGISTERNOTIFY_OFFSET);
829 } else {
830 status = DSP_ENOTIMPL;
831 DEBUGMSG(DSPAPI_ZONE_ERROR,
832 (TEXT("NODE: DSPNode_RegisterNotify: "
833 "Invalid Notification Mask \r\n")));
834 }
835 } else {
836 status = DSP_EVALUE;
837 DEBUGMSG(DSPAPI_ZONE_ERROR,
838 (TEXT("NODE: DSPNode_RegisterNotify:"
839 "Invalid Event type\r\n")));
840 }
841 } else {
842 /* Invalid pointer */
843 status = DSP_EHANDLE;
844 DEBUGMSG(DSPAPI_ZONE_ERROR,
845 (TEXT("NODE: DSPNode_RegisterNotify: "
846 "hNode is Invalid \r\n")));
847 }
848
849 return status;
850 }
851
852 /*
853 * ======== DSPNode_Run ========
854 * Purpose:
855 * Start a task node running.
856 */
DSPNode_Run(DSP_HNODE hNode)857 DBAPI DSPNode_Run(DSP_HNODE hNode)
858 {
859 DSP_STATUS status = DSP_SOK;
860 Trapped_Args tempStruct;
861
862 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Run:\r\n")));
863
864 if (hNode) {
865 /* Set up the structure */
866 /* Call DSP Trap */
867 tempStruct.ARGS_NODE_RUN.hNode = hNode;
868 status = DSPTRAP_Trap(&tempStruct, CMD_NODE_RUN_OFFSET);
869 } else {
870 /* Invalid pointer */
871 status = DSP_EHANDLE;
872 DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("NODE: DSPNode_Run: "
873 "hNode is Invalid Handle\r\n")));
874 }
875
876 return status;
877 }
878
879 /*
880 * ======== DSPNode_Terminate ========
881 * Purpose:
882 * Signal a task node running on a DSP processor that it should
883 * exit its execute-phase function.
884 */
DSPNode_Terminate(DSP_HNODE hNode,DSP_STATUS * pStatus)885 DBAPI DSPNode_Terminate(DSP_HNODE hNode, DSP_STATUS *pStatus)
886 {
887 DSP_STATUS status = DSP_SOK;
888 Trapped_Args tempStruct;
889
890 DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("NODE: DSPNode_Terminate:\r\n")));
891
892 if (hNode) {
893 /* !DSP_ValidWritePtr means it is a valid write ptr */
894 if (!DSP_ValidWritePtr(pStatus, sizeof(DSP_STATUS))) {
895 /* Set up the structure */
896 /* Call DSP Trap */
897 tempStruct.ARGS_NODE_TERMINATE.hNode = hNode;
898 tempStruct.ARGS_NODE_TERMINATE.pStatus = pStatus;
899 status = DSPTRAP_Trap(&tempStruct,
900 CMD_NODE_TERMINATE_OFFSET);
901 } else
902 status = DSP_EPOINTER;
903
904 } else {
905 /* Invalid pointer */
906 status = DSP_EHANDLE;
907 DEBUGMSG(DSPAPI_ZONE_ERROR,
908 (TEXT("NODE: DSPNode_Terminate: "
909 "hNode is Invalid Handle\r\n")));
910 }
911
912 return status;
913 }
914
915
916 /*
917 * ======== DSPNode_GetUUIDProps ========
918 * Purpose:
919 * Get Node properties from DCD/DOF file given the UUID
920 */
DSPNode_GetUUIDProps(DSP_HPROCESSOR hProcessor,IN CONST struct DSP_UUID * pNodeID,OUT struct DSP_NDBPROPS * pNodeProps)921 DBAPI DSPNode_GetUUIDProps(DSP_HPROCESSOR hProcessor,
922 IN CONST struct DSP_UUID *pNodeID,
923 OUT struct DSP_NDBPROPS *pNodeProps)
924 {
925 DSP_STATUS status = DSP_SOK;
926 Trapped_Args tempStruct;
927
928 DEBUGMSG(DSPAPI_ZONE_FUNCTION,
929 (TEXT("NODE:DSPNode_GetUUIDProps:\r\n")));
930
931 if (hProcessor) {
932 if ((pNodeID) && (pNodeProps)) {
933 /* Set up the structure */
934 /* Call DSP Trap */
935 tempStruct.ARGS_NODE_GETUUIDPROPS.hProcessor =
936 hProcessor;
937 tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeID =
938 (struct DSP_UUID *)pNodeID;
939 tempStruct.ARGS_NODE_GETUUIDPROPS.pNodeProps =
940 (struct DSP_NDBPROPS *) pNodeProps;
941 status = DSPTRAP_Trap(&tempStruct,
942 CMD_NODE_GETUUIDPROPS_OFFSET);
943 } else {
944 /* Invalid parameter */
945 status = DSP_EPOINTER;
946 DEBUGMSG(DSPAPI_ZONE_ERROR,
947 (TEXT("NODE: DSPNode_GetUUIDProps: "
948 "Invalid pointer in the Input\r\n")));
949 }
950 } else {
951 /* Invalid pointer */
952 status = DSP_EHANDLE;
953 DEBUGMSG(DSPAPI_ZONE_ERROR,
954 (TEXT("NODE: DSPNode_GetUUIDProps: "
955 "hProcessor is Invalid \r\n")));
956 }
957
958 return status;
959 }
960
961