• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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