Home | History | Annotate | Download | only in libbridge
      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  */
     95 DBAPI 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  */
    131 DBAPI 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  */
    157 DBAPI 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  */
    211 DBAPI 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 
    222 timeRetVal = 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
    242 timeRetVal = 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  */
    255 DBAPI 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  */
    299 DBAPI 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  */
    350 DBAPI 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  */
    397 DBAPI 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  */
    478 DBAPI 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  */
    527 DBAPI 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  */
    592 DBAPI 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  */
    638 DBAPI 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