1/*
2 * dspbridge/src/api/linux/DSPProcessor.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 *  ======== DSPProcessor.c ========
21 *  Description:
22 *      This is the source for the DSP/BIOS Bridge API processor 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 PM PROC module.
25 *
26 *  Public Functions:
27 *      DSPProcessor_Attach
28 *      DSPProcessor_Detach
29 *      DSPProcessor_EnumNodes
30 *      DSPProcessor_FlushMemory
31 *      DSPProcessor_GetResourceInfo
32 *      DSPProcessor_GetState
33 *      DSPProcessor_Map
34 *      DSPProcessor_RegisterNotify
35 *      DSPProcessor_ReserveMemory
36 *      DSPProcessor_UnMap
37 *      DSPProcessor_UnReserveMemory
38 *      DSPProcessor_InvalidateMemory
39
40 *! Revision History
41 *! ================
42 *! 04-Apr-2007 sh  Added DSPProcessor_InvalidateMemory
43 *! 19-Apr-2004 sb  Aligned DMM definitions with Symbian
44 *! 08-Mar-2004 sb  Added the Dynamic Memory Mapping APIs
45 *! 27-Jun-2001 rr: DSPProcessor_RegisterNotify allows EventMask =0
46 *!                 for De Registration.
47 *! 16-Feb-2001 jeh Fixed message in DSPProcessor_Detach.
48 *! 12-Dec-2000 rr: DSP_ProcessorEnumNodes returns DSP_ESIZE if
49 *!                 uNodeTabSize is zero and valid aNodeTab.
50 *! 29-Nov-2000 rr: Incorporated code review changes.
51 *! 09-Nov-2000 rr: Code cleaned up. Use of IsValidEvent/Mask Macros.
52 *! 28-Sep-2000 rr: Updated to version 0.9.
53 *! 07-Sep-2000 jeh Changed type HANDLE in DSPProcessor_RegisterNotify to
54 *!                 DSP_HNOTIFICATION.
55 *! 07-Aug-2000 rr: Enum fxns do not return ESIZE if the size of the data
56 *!                 structure is less than the actual size for backward
57 *!                 compatibility.
58 *! 04-Aug-2000 rr: DSPProcessor_Attach does not check for pAttrin for NULL.
59 *!                 file name changed to DSPProcessor.c
60 *! 27-Jul-2000 rr: Updated to 0.8 ver API. GetTrace Implemented.
61 *! 10-Jul-2000 rr: Calls into DSP Trap for the bulk of the functionality.
62 *! 12-May-2000 gp: Removed PROC_UNKNOWN state.  Mapped to return DSP_EFAIL.
63 *!                 Return DSP_EHANDLE in DSPProcessor_Ctrl()/Detach().
64 *!                 Return DSP_EWRONGSTATE from DSPProcessor_Start().
65 *! 03-May-2000 rr: Uses SERVICES CSL fxns
66 *! 19-Apr-2000 ww: Updated based on code review.
67 *! 12-Apr-2000 ww: Created based on DirectDSP API specification, Version 0.6.
68 *
69 */
70
71/*  ----------------------------------- Host OS */
72#include <host_os.h>
73
74/*  ----------------------------------- DSP/BIOS Bridge */
75#include <dbdefs.h>
76#include <errbase.h>
77
78/*  ----------------------------------- Others */
79#include <dsptrap.h>
80
81#ifdef DEBUG_BRIDGE_PERF
82#include <perfutils.h>
83#endif
84/*  ----------------------------------- This */
85#include "_dbdebug.h"
86#include "_dbpriv.h"
87#include <DSPProcessor.h>
88
89/*
90 *  ======== DSPProcessor_Attach ========
91 *  Purpose:
92 *      Prepare for communication with a particular DSP processor, and
93 *		return a handle to the processor object.
94 */
95DBAPI DSPProcessor_Attach(UINT uProcessor,
96		    OPTIONAL CONST struct DSP_PROCESSORATTRIN *pAttrIn,
97		    OUT DSP_HPROCESSOR *phProcessor)
98{
99	DSP_STATUS status = DSP_SOK;
100	Trapped_Args tempStruct;
101
102	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_Attach\r\n")));
103	if (!DSP_ValidWritePtr(phProcessor, sizeof(DSP_HPROCESSOR))) {
104		if (uProcessor <= DSP_MAX_PROCESSOR) {
105			tempStruct.ARGS_PROC_ATTACH.uProcessor = uProcessor;
106			tempStruct.ARGS_PROC_ATTACH.pAttrIn =
107				(struct DSP_PROCESSORATTRIN *)pAttrIn;
108			tempStruct.ARGS_PROC_ATTACH.phProcessor = phProcessor;
109			status = DSPTRAP_Trap(&tempStruct,
110					CMD_PROC_ATTACH_OFFSET);
111		} else {
112			status = DSP_EINVALIDARG;
113			DEBUGMSG(DSPAPI_ZONE_ERROR,
114				(TEXT("PROC: invalid processor number\r\n")));
115		}
116	} else {
117		/* Invalid pointer */
118		status = DSP_EPOINTER;
119		DEBUGMSG(DSPAPI_ZONE_ERROR,
120				(TEXT("PROC: Invalid Pointer \r\n")));
121	}
122
123	return status;
124}
125
126/*
127 *  ======== DSPProcessor_Detach ========
128 *  Purpose:
129 *      Close a DSP processor and de-allocate all (GPP) resources.
130 */
131DBAPI DSPProcessor_Detach(DSP_HPROCESSOR hProcessor)
132{
133	DSP_STATUS status = DSP_SOK;
134	Trapped_Args tempStruct;
135
136	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_Detach\r\n")));
137	/* Check the handle */
138	if (hProcessor) {
139		tempStruct.ARGS_PROC_DETACH.hProcessor = hProcessor;
140		status = DSPTRAP_Trap(&tempStruct, CMD_PROC_DETACH_OFFSET);
141	} else {
142		/* Invalid handle */
143		status = DSP_EHANDLE;
144		DEBUGMSG(DSPAPI_ZONE_ERROR,
145			(TEXT("PROC: Invalid Handle \r\n")));
146	}
147
148	return status;
149}
150
151/*
152 *  ======== DSPProcessor_EnumNodes ========
153 *  Purpose:
154 *      Enumerate and get configuration information about nodes allocated
155 *      on a DSP processor.
156 */
157DBAPI DSPProcessor_EnumNodes(DSP_HPROCESSOR hProcessor,
158		       IN DSP_HNODE *aNodeTab, IN UINT uNodeTabSize,
159		       OUT UINT *puNumNodes, OUT UINT *puAllocated)
160{
161	DSP_STATUS status = DSP_SOK;
162	Trapped_Args tempStruct;
163
164	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
165			(TEXT("PROC:DSPProcessor_EnumNodes\r\n")));
166
167	/* Check the handle */
168	if (hProcessor) {
169		if (!DSP_ValidWritePtr(puNumNodes, sizeof(UINT)) &&
170		    !DSP_ValidWritePtr(puAllocated, sizeof(UINT)) &&
171			(uNodeTabSize && !DSP_ValidWritePtr(aNodeTab,
172					(sizeof(DSP_HNODE)*uNodeTabSize)))) {
173			tempStruct.ARGS_PROC_ENUMNODE_INFO.hProcessor =
174						hProcessor;
175			tempStruct.ARGS_PROC_ENUMNODE_INFO.aNodeTab = aNodeTab;
176			tempStruct.ARGS_PROC_ENUMNODE_INFO.uNodeTabSize =
177						uNodeTabSize;
178			tempStruct.ARGS_PROC_ENUMNODE_INFO.puNumNodes =
179						puNumNodes;
180			tempStruct.ARGS_PROC_ENUMNODE_INFO.puAllocated =
181						puAllocated;
182			status = DSPTRAP_Trap(&tempStruct,
183					CMD_PROC_ENUMNODE_OFFSET);
184		} else {
185			if (uNodeTabSize <= 0 &&
186			    !DSP_ValidWritePtr(puNumNodes, sizeof(UINT)) &&
187			    !DSP_ValidWritePtr(puAllocated, sizeof(UINT)) &&
188			    !DSP_ValidWritePtr(aNodeTab, sizeof(DSP_HNODE)*1)) {
189				status = DSP_ESIZE;
190			} else
191				status = DSP_EPOINTER;
192
193			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: "
194					"pNodeInfo is invalid \r\n")));
195		}
196	} else {
197		/* Invalid handle */
198		status = DSP_EHANDLE;
199		DEBUGMSG(DSPAPI_ZONE_ERROR,
200				(TEXT("PROC: Invalid Handle \r\n")));
201	}
202
203	return status;
204}
205
206/*
207 *  ======== DSPProcessor_FlushMemory ========
208 *  Purpose:
209 *      Flushes a buffer from the MPU data cache.
210 */
211DBAPI DSPProcessor_FlushMemory(DSP_HPROCESSOR hProcessor, PVOID pMpuAddr,
212			 ULONG ulSize, ULONG ulFlags)
213{
214	DSP_STATUS status = DSP_SOK;
215	Trapped_Args tempStruct;
216#ifdef DEBUG_BRIDGE_PERF
217	struct timeval tv_beg;
218	struct timeval tv_end;
219	struct timezone tz;
220	int timeRetVal = 0;
221
222timeRetVal = getTimeStamp(&tv_beg);
223
224#endif
225
226	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
227			(TEXT("PROC: DSPProcessor_FlushMemory\r\n")));
228
229	/* Check the handle */
230	if (hProcessor) {
231		tempStruct.ARGS_PROC_FLUSHMEMORY.hProcessor = hProcessor;
232		tempStruct.ARGS_PROC_FLUSHMEMORY.pMpuAddr = pMpuAddr;
233		tempStruct.ARGS_PROC_FLUSHMEMORY.ulSize = ulSize;
234		tempStruct.ARGS_PROC_FLUSHMEMORY.ulFlags = ulFlags;
235		status = DSPTRAP_Trap(&tempStruct, CMD_PROC_FLUSHMEMORY_OFFSET);
236	} else {
237		/* Invalid handle */
238		status = DSP_EHANDLE;
239		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
240	}
241#ifdef DEBUG_BRIDGE_PERF
242timeRetVal = getTimeStamp(&tv_end);
243	PrintStatistics(&tv_beg, &tv_end, "DSPProcessor_FlushMemory", ulSize);
244#endif
245
246	return status;
247
248}
249
250/*
251 *  ======== DSPProcessor_InvalidateMemory ========
252 *  Purpose:
253 *      Invalidates a buffer from MPU data cache.
254 */
255DBAPI DSPProcessor_InvalidateMemory(DSP_HPROCESSOR hProcessor,
256					PVOID pMpuAddr, ULONG ulSize)
257{
258	DSP_STATUS status = DSP_SOK;
259	Trapped_Args tempStruct;
260#ifdef DEBUG_BRIDGE_PERF
261	struct timeval tv_beg;
262	struct timeval tv_end;
263	struct timezone tz;
264	int timeRetVal = 0;
265
266	timeRetVal = getTimeStamp(&tv_beg);
267#endif
268
269	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
270			(TEXT("PROC: DSPProcessor_InvalidateMemory\r\n")));
271
272	/* Check the handle */
273	if (hProcessor) {
274		tempStruct.ARGS_PROC_INVALIDATEMEMORY.hProcessor = hProcessor;
275		tempStruct.ARGS_PROC_INVALIDATEMEMORY.pMpuAddr = pMpuAddr;
276		tempStruct.ARGS_PROC_INVALIDATEMEMORY.ulSize = ulSize;
277		status = DSPTRAP_Trap(&tempStruct,
278				CMD_PROC_INVALIDATEMEMORY_OFFSET);
279	} else {
280		/* Invalid handle */
281		status = DSP_EHANDLE;
282		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
283	}
284#ifdef DEBUG_BRIDGE_PERF
285	timeRetVal = getTimeStamp(&tv_end);
286	PrintStatistics(&tv_beg, &tv_end,
287			"DSPProcessor_InvalidateMemory", ulSize);
288#endif
289
290	return status;
291
292}
293
294/*
295 *  ======== DSPProcessor_GetResourceInfo ========
296 *  Purpose:
297 *      Enumerate the resources currently available on a processor.
298 */
299DBAPI DSPProcessor_GetResourceInfo(DSP_HPROCESSOR hProcessor,
300	     UINT uResourceType, OUT struct DSP_RESOURCEINFO *pResourceInfo,
301	     UINT uResourceInfoSize)
302{
303	DSP_STATUS status = DSP_SOK;
304	Trapped_Args tempStruct;
305
306	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_Ctrl\r\n")));
307
308	if (hProcessor) {
309		if (!DSP_ValidWritePtr(pResourceInfo,
310				sizeof(struct DSP_RESOURCEINFO))) {
311			if (uResourceInfoSize >=
312					sizeof(struct DSP_RESOURCEINFO)) {
313				tempStruct.ARGS_PROC_ENUMRESOURCES.hProcessor =
314							hProcessor;
315				tempStruct.ARGS_PROC_ENUMRESOURCES\
316					.uResourceType = uResourceType;
317				tempStruct.ARGS_PROC_ENUMRESOURCES\
318					.pResourceInfo = pResourceInfo;
319				tempStruct.ARGS_PROC_ENUMRESOURCES\
320					.uResourceInfoSize = uResourceInfoSize;
321				status = DSPTRAP_Trap(&tempStruct,
322						CMD_PROC_ENUMRESOURCES_OFFSET);
323			} else {
324				status = DSP_ESIZE;
325				DEBUGMSG(DSPAPI_ZONE_ERROR,
326					 (TEXT("PROC: uResourceInfoSize "
327							"is small \r\n")));
328			}
329		} else {
330			/* Invalid pointer */
331			status = DSP_EPOINTER;
332			DEBUGMSG(DSPAPI_ZONE_ERROR,
333				(TEXT("PROC: pResourceInfo is invalid \r\n")));
334		}
335	} else {
336		/* Invalid handle */
337		status = DSP_EHANDLE;
338		DEBUGMSG(DSPAPI_ZONE_ERROR,
339			 (TEXT("PROC: Invalid Handle \r\n")));
340	}
341
342	return status;
343}
344
345/*
346 *  ======== DSPProcessor_GetState ========
347 *  Purpose:
348 *      Report the state of the specified DSP processor.
349 */
350DBAPI DSPProcessor_GetState(DSP_HPROCESSOR hProcessor,
351	      OUT struct DSP_PROCESSORSTATE *pProcStatus, UINT uStateInfoSize)
352{
353	DSP_STATUS status = DSP_SOK;
354	Trapped_Args tempStruct;
355
356	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_Ctrl\r\n")));
357
358	/* Check the handle */
359	if (hProcessor) {
360		if (!DSP_ValidWritePtr(pProcStatus,
361			sizeof(struct DSP_PROCESSORSTATE))) {
362			if (uStateInfoSize >=
363				sizeof(struct DSP_PROCESSORSTATE)) {
364				tempStruct.ARGS_PROC_GETSTATE.hProcessor =
365							hProcessor;
366				tempStruct.ARGS_PROC_GETSTATE.pProcStatus =
367							pProcStatus;
368				tempStruct.ARGS_PROC_GETSTATE.uStateInfoSize =
369							uStateInfoSize;
370				status = DSPTRAP_Trap(&tempStruct,
371						CMD_PROC_GETSTATE_OFFSET);
372			} else {
373				status = DSP_ESIZE;
374				DEBUGMSG(DSPAPI_ZONE_ERROR,
375				(TEXT("PROC: uStateInfoSize is small \r\n")));
376			}
377		} else {
378			status = DSP_EPOINTER;
379			DEBUGMSG(DSPAPI_ZONE_ERROR,
380				(TEXT("PROC: pProcStatus is invalid \r\n")));
381		}
382	} else {
383		/* Invalid handle */
384		status = DSP_EHANDLE;
385		DEBUGMSG(DSPAPI_ZONE_ERROR,
386			(TEXT("PROC: Invalid Handle \r\n")));
387	}
388
389	return status;
390}
391
392/*
393 *  ======== DSPProcessor_Map ========
394 *  Purpose:
395 *      Map an MPU buffer to a reserved virtual address
396 */
397DBAPI DSPProcessor_Map(DSP_HPROCESSOR hProcessor, PVOID pMpuAddr,
398		ULONG ulSize, PVOID pReqAddr, PVOID *ppMapAddr, ULONG ulMapAttr)
399{
400	DSP_STATUS status = DSP_SOK;
401	Trapped_Args tempStruct;
402#ifdef DEBUG_BRIDGE_PERF
403	struct timeval tv_beg;
404	struct timeval tv_end;
405	struct timezone tz;
406	int timeRetVal = 0;
407
408	timeRetVal = getTimeStamp(&tv_beg);
409#endif
410
411	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_Map\r\n")));
412
413	/* Check the handle */
414	if (hProcessor) {
415		if (!DSP_ValidWritePtr(ppMapAddr, sizeof(PVOID *))
416			&& !DSP_ValidReadPtr(pMpuAddr, sizeof(PVOID))
417			&& (pReqAddr != NULL)) {
418			if (ulSize > 0) {
419#if 0
420				INT i;
421				ULONG ulLastByte;
422				/* Physical memory pages are reserved by the
423				 * driver (get_user_pages), so no need to
424				 * reserve here. Ensure that physical memory
425				 * pages are reserved */
426				size_t page_size = getpagesize();
427				for (i = 0; i < (INT)ulSize; i += page_size) {
428					*(volatile BYTE *)(pMpuAddr + i) =
429						*(BYTE *)(pMpuAddr + i);
430				}
431				/* Non page-aligned size: Write final byte */
432				ulLastByte = pMpuAddr + ulSize - 1;
433				*(volatile BYTE *)(ulLastByte) =
434				    *(BYTE *)(ulLastByte);
435#endif
436				tempStruct.ARGS_PROC_MAPMEM.hProcessor =
437						hProcessor;
438				tempStruct.ARGS_PROC_MAPMEM.pMpuAddr = pMpuAddr;
439				tempStruct.ARGS_PROC_MAPMEM.ulSize = ulSize;
440				tempStruct.ARGS_PROC_MAPMEM.pReqAddr = pReqAddr;
441				tempStruct.ARGS_PROC_MAPMEM.ppMapAddr =
442						ppMapAddr;
443				tempStruct.ARGS_PROC_MAPMEM.ulMapAttr =
444						ulMapAttr;
445				status = DSPTRAP_Trap(&tempStruct,
446						CMD_PROC_MAPMEM_OFFSET);
447			} else {
448				status = DSP_ESIZE;
449				DEBUGMSG(DSPAPI_ZONE_ERROR,
450					(TEXT("PROC:size is zero\r\n")));
451			}
452		} else {
453			status = DSP_EPOINTER;
454			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT
455				  ("PROC: Atleast one pointer argument "
456					"is invalid\r\n")));
457		}
458	} else {
459		/* Invalid handle */
460		status = DSP_EHANDLE;
461		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
462	}
463
464#ifdef DEBUG_BRIDGE_PERF
465	timeRetVal = getTimeStamp(&tv_end);
466	PrintStatistics(&tv_beg, &tv_end, "DSPProcessor_Map", ulSize);
467#endif
468
469
470	return status;
471}
472
473/*
474 *  ======== DSPProcessor_RegisterNotify ========
475 *  Purpose:
476 *      Register to be notified of specific processor events
477 */
478DBAPI DSPProcessor_RegisterNotify(DSP_HPROCESSOR hProcessor, UINT uEventMask,
479		    UINT uNotifyType, struct DSP_NOTIFICATION *hNotification)
480{
481	DSP_STATUS status = DSP_SOK;
482	Trapped_Args tempStruct;
483
484	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
485			(TEXT("PROC: DSPProcessor_RegisterNotify\r\n")));
486
487	/* Check the handle */
488	if ((hProcessor) && (hNotification)) {
489		if (IsValidProcEvent(uEventMask)) {
490			if (IsValidNotifyMask(uNotifyType)) {
491				tempStruct.ARGS_PROC_REGISTER_NOTIFY\
492						.hProcessor = hProcessor;
493				tempStruct.ARGS_PROC_REGISTER_NOTIFY\
494						.uEventMask = uEventMask;
495				tempStruct.ARGS_PROC_REGISTER_NOTIFY\
496						.uNotifyType = uNotifyType;
497				tempStruct.ARGS_PROC_REGISTER_NOTIFY\
498						.hNotification = hNotification;
499
500				status = DSPTRAP_Trap(&tempStruct,
501						CMD_PROC_REGISTERNOTIFY_OFFSET);
502			} else {
503				status = DSP_ENOTIMPL;
504				DEBUGMSG(DSPAPI_ZONE_ERROR,
505				(TEXT("PROC: Invalid Notify Mask \r\n")));
506			}
507		} else {
508			status = DSP_EVALUE;
509			DEBUGMSG(DSPAPI_ZONE_ERROR,
510				(TEXT("PROC: Invalid Evnet Mask \r\n")));
511		}
512	} else {
513		/* Invalid handle */
514		status = DSP_EHANDLE;
515		DEBUGMSG(DSPAPI_ZONE_ERROR,
516			(TEXT("PROC: Invalid Handle \r\n")));
517	}
518
519	return status;
520}
521
522/*
523 *  ======== DSPProcessor_ReserveMemory ========
524 *  Purpose:
525 *      Reserve a chunk of memory from the DMM
526 */
527DBAPI DSPProcessor_ReserveMemory(DSP_HPROCESSOR hProcessor, ULONG ulSize,
528		PVOID *ppRsvAddr)
529{
530	DSP_STATUS status = DSP_SOK;
531	Trapped_Args tempStruct;
532#ifdef DEBUG_BRIDGE_PERF
533	struct timeval tv_beg;
534	struct timeval tv_end;
535	struct timezone tz;
536	int timeRetVal = 0;
537
538	timeRetVal = getTimeStamp(&tv_beg);
539#endif
540
541
542	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
543			(TEXT("PROC: DSPProcessor_ReserveMemory\r\n")));
544
545	/* Check the handle */
546	if (hProcessor) {
547		if (!DSP_ValidWritePtr(ppRsvAddr, sizeof(PVOID *))) {
548			if (ulSize > 0) {
549				if ((ulSize & (PG_SIZE_4K - 1)) == 0) {
550					tempStruct.ARGS_PROC_RSVMEM.hProcessor =
551							hProcessor;
552					tempStruct.ARGS_PROC_RSVMEM.ulSize =
553							ulSize;
554					tempStruct.ARGS_PROC_RSVMEM.ppRsvAddr =
555							ppRsvAddr;
556					status = DSPTRAP_Trap(&tempStruct,
557							CMD_PROC_RSVMEM_OFFSET);
558				} else {
559					status = DSP_EINVALIDARG;
560					DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT
561						("PROC: size is not 4KB "
562							"page-aligned\r\n")));
563				}
564			} else {
565				status = DSP_ESIZE;
566				DEBUGMSG(DSPAPI_ZONE_ERROR,
567					(TEXT("PROC:size is zero\r\n")));
568			}
569		} else {
570			status = DSP_EPOINTER;
571			DEBUGMSG(DSPAPI_ZONE_ERROR,
572				(TEXT("PROC:ppRsvAddr is invalid\r\n")));
573		}
574	} else {
575		/* Invalid handle */
576		status = DSP_EHANDLE;
577		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
578	}
579
580#ifdef DEBUG_BRIDGE_PERF
581	timeRetVal = getTimeStamp(&tv_end);
582	PrintStatistics(&tv_beg, &tv_end, "DSPProcessor_ReserveMemory", ulSize);
583#endif
584
585	return status;
586}
587
588/*  ======== DSPProcessor_UnMap ========
589 *  Purpose:
590 *      UnMap an MPU buffer from a reserved virtual address
591 */
592DBAPI DSPProcessor_UnMap(DSP_HPROCESSOR hProcessor, PVOID pMapAddr)
593{
594	DSP_STATUS status = DSP_SOK;
595	Trapped_Args tempStruct;
596#ifdef DEBUG_BRIDGE_PERF
597	struct timeval tv_beg;
598	struct timeval tv_end;
599	struct timezone tz;
600	int timeRetVal = 0;
601
602	timeRetVal = getTimeStamp(&tv_beg);
603#endif
604
605	DEBUGMSG(DSPAPI_ZONE_FUNCTION, (TEXT("PROC: DSPProcessor_UnMap\r\n")));
606
607	/* Check the handle */
608	if (hProcessor) {
609		if ((pMapAddr != NULL)) {
610			tempStruct.ARGS_PROC_UNMAPMEM.hProcessor = hProcessor;
611			tempStruct.ARGS_PROC_UNMAPMEM.pMapAddr = pMapAddr;
612			status = DSPTRAP_Trap(&tempStruct,
613				CMD_PROC_UNMAPMEM_OFFSET);
614		} else {
615			status = DSP_EPOINTER;
616			DEBUGMSG(DSPAPI_ZONE_ERROR,
617				(TEXT("PROC: pMapAddr is invalid\r\n")));
618		}
619	} else {
620		/* Invalid handle */
621		status = DSP_EHANDLE;
622		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
623	}
624
625#ifdef DEBUG_BRIDGE_PERF
626	timeRetVal = getTimeStamp(&tv_end);
627	PrintStatistics(&tv_beg, &tv_end, "DSPProcessor_UnMap", 0);
628#endif
629
630	return status;
631}
632
633/*
634 *  ======== DSPProcessor_UnReserveMemory ========
635 *  Purpose:
636 *      Free a chunk of memory from the DMM
637 */
638DBAPI DSPProcessor_UnReserveMemory(DSP_HPROCESSOR hProcessor, PVOID pRsvAddr)
639{
640	DSP_STATUS status = DSP_SOK;
641	Trapped_Args tempStruct;
642#ifdef DEBUG_BRIDGE_PERF
643	struct timeval tv_beg;
644	struct timeval tv_end;
645	struct timezone tz;
646	int timeRetVal = 0;
647
648	timeRetVal = getTimeStamp(&tv_beg);
649#endif
650
651	DEBUGMSG(DSPAPI_ZONE_FUNCTION,
652			(TEXT("PROC: DSPProcessor_UnReserveMemory\r\n")));
653
654	/* Check the handle */
655	if (hProcessor) {
656		if (pRsvAddr != NULL) {
657			tempStruct.ARGS_PROC_UNRSVMEM.hProcessor = hProcessor;
658			tempStruct.ARGS_PROC_UNRSVMEM.pRsvAddr = pRsvAddr;
659			status = DSPTRAP_Trap(&tempStruct,
660					CMD_PROC_UNRSVMEM_OFFSET);
661		} else {
662			status = DSP_EPOINTER;
663			DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT(
664					"PROC: pRsvAddr is invalid\r\n")));
665		}
666	} else {
667		/* Invalid handle */
668		status = DSP_EHANDLE;
669		DEBUGMSG(DSPAPI_ZONE_ERROR, (TEXT("PROC: Invalid Handle\r\n")));
670	}
671#ifdef DEBUG_BRIDGE_PERF
672	timeRetVal = getTimeStamp(&tv_end);
673	PrintStatistics(&tv_beg, &tv_end, "DSPProcessor_UnReserveMemory", 0);
674#endif
675
676	return status;
677}
678
679