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 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 */
DSPNode_AllocMsgBuf(DSP_HNODE hNode,UINT uSize,IN OPTIONAL struct DSP_BUFFERATTR * pAttr,OUT BYTE ** pBuffer)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 */
DSPNode_ChangePriority(DSP_HNODE hNode,INT iPriority)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 */
DSPNode_Connect(DSP_HNODE hNode,UINT uStream,DSP_HNODE hOtherNode,UINT uOtherStream,IN OPTIONAL struct DSP_STRMATTR * pAttrs)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 */
DSPNode_ConnectEx(DSP_HNODE hNode,UINT uStream,DSP_HNODE hOtherNode,UINT uOtherStream,IN OPTIONAL struct DSP_STRMATTR * pAttrs,IN OPTIONAL struct DSP_CBDATA * pConnParam)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 */
DSPNode_Create(DSP_HNODE hNode)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 */
DSPNode_Delete(DSP_HNODE hNode)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 */
DSPNode_FreeMsgBuf(DSP_HNODE hNode,IN BYTE * pBuffer,IN OPTIONAL struct DSP_BUFFERATTR * pAttr)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 */
DSPNode_GetAttr(DSP_HNODE hNode,OUT struct DSP_NODEATTR * pAttr,UINT uAttrSize)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 */
DSPNode_GetMessage(DSP_HNODE hNode,OUT struct DSP_MSG * pMessage,UINT uTimeout)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 */
GetNodeType(DSP_HNODE hNode,DSP_NODETYPE * pNodeType)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 */
DSPNode_Pause(DSP_HNODE hNode)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 */
DSPNode_PutMessage(DSP_HNODE hNode,IN CONST struct DSP_MSG * pMessage,UINT uTimeout)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
DSPNode_RegisterNotify(DSP_HNODE hNode,UINT uEventMask,UINT uNotifyType,struct DSP_NOTIFICATION * hNotification)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 */
DSPNode_Run(DSP_HNODE hNode)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 */
DSPNode_Terminate(DSP_HNODE hNode,DSP_STATUS * pStatus)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 */
DSPNode_GetUUIDProps(DSP_HPROCESSOR hProcessor,IN CONST struct DSP_UUID * pNodeID,OUT struct DSP_NDBPROPS * pNodeProps)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