/*
 * Copyright (c) 2003 Linuxant inc.
 * Copyright (c) 2001-2003 Conexant Systems, Inc.
 *
 * NOTE: The use and distribution of this software is governed by the terms in
 * the file LICENSE, which is included in the package. You must read this and
 * agree to these terms before using or distributing this software.
 *
 */
#ifndef _OSTIME_EX_H_
#define _OSTIME_EX_H_
 
#include "comtypes.h"
#include "rtmgr_ex.h"
#ifdef __cplusplus
extern "C"
{
#endif
 
#if (OS_TYPE == OS_VXWORKS)
#define OSCriticalSectionCreate() OSSemaphoreCreate(1)
#define OSCriticalSectionDestroy OSSemaphoreDestroy
#define OSCriticalSectionAcquire OSSemaphoreWait
#define OSCriticalSectionRelease OSSemaphoreSignal
#define OsSetPeriodicTimer OSSetPeriodicTimeOut
#define OsDestroyPeriodicTimer OSDestroyPeriodicTimeOut
#define OsCallOnMyStack OSCallOnMyStack
#endif
 
#if (PRJ_FLAVOUR == PRJFLVR_CYPRUS)
HANDLE	OsCreatePeriodicTimer	(	IN	UINT32			InitialTimeOut,
										IN	PCBFUNC			pTimeOutCallBack,
										IN	PALLOC_FUNC		pFuncAlloc,
										IN	PFREE_FUNC		pFuncFree,
										IN	PVOID			pRefData,
										OUT	HANDLE*		pThreadId);
 
#else
 
/**********************************************************************************
Function name :	OsModemThreadSchedule
**********************************************************************************/
int OsModemThreadSchedule(PVOID task);

/**********************************************************************************
Function name :	OSCreatePeriodicTimeOut
Parameters :	Irql				- IRQ level at wich the timer should be called
				InitialTimeOut		- initial interval between 2 timeout callbacks
				pTimeOutCallBack	- Callback to be periodically called back
				pFuncAlloc			- wrapper function for allocations
				pFuncFree			- wrapper function for deallocations
				pRefData			- Reference Data to be passed to wrapper functions
Return value :	Returns a handle to the periodic timeout. This handle is to be
				passed to OS functions acting on periodic timeout. Returns NULL
				on failure.
functionality :	Creates a periodic timeout of InitialTimeOut interval. pTimeOutCallBack
				function will be called on each timer interval. 
**********************************************************************************/
GLOBAL	HANDLE	OSCreatePeriodicTimeOut	(	IN	TIMER_IRQL_TYPE	Irql,
											IN	UINT32			InitialTimeOut,
											IN	PCBFUNC			pTimeOutCallBack,
											IN	PALLOC_FUNC		pFuncAllc,
											IN	PFREE_FUNC		pFuncFree,
											IN	PVOID			pRefData);
#endif
/**********************************************************************************
Function name :	OSDestroyPeriodicTimeOut
Parameters :	hTimeOut -	Handle to the periodic time out returned by 
							OSCreatePeriodicTimeOut.
Return value :	none
functionality : destroys a periodic timeout resource.
**********************************************************************************/
GLOBAL	VOID	OSDestroyPeriodicTimeOut	(	IN	HANDLE			hTimeOut);

/**********************************************************************************
Function name :	OSSetPeriodicTimeOut
Parameters :	hTimeOut	-	Handle to the periodic timeout
				NewTimeOut	-	New timeout interval
Return value :	returns TRUE when the timeout interval was successfully changed to 
				NewTimeOut
functionality : resets the timeout inteval to a new value.
**********************************************************************************/
GLOBAL	BOOL	OSSetPeriodicTimeOut	(	IN	HANDLE			hTimeOut,
											IN	UINT32			NewTimeOut);


/**********************************************************************************
Function name :	OSCallOnMyStack
Parameters :	pFunc			-	function to be called
				lParam			-	parameter to pass for pFunc
				pTopOfStack		-	Pointer to stack
				StackSizeBytes	-	stack size in bytes.
Return value :	None
functionality :	Temporarily switches a stack to a different locked block of memory.
**********************************************************************************/
#if (OS_TYPE != OS_LINUX)
GLOBAL	VOID	OSCallOnMyStack(			IN	PCBFUNC			pFunc, 
											IN	UINT32			lParam, 
											PUINT32			pTopOfStack, 
											IN	UINT32			StackSizeBytes);
#else
#define OSCallOnMyStack(pFunc, lParam, pTopOfStack, StackSizeBytes) (pFunc)((PVOID)(lParam))
#endif

/**********************************************************************************
Function name :	OSGetSystemTime
Parameters :	None
Return value :	returns timestamp in milliseconds
functionality	The function returnes a milliseconds timestamp.
**********************************************************************************/
/* returns time stamp in milli-seconds					*/
GLOBAL	UINT32	OSGetSystemTime(			VOID	);

/* initialize epoch to reduce wrap around risk; all values returned by
 * OSGetSystemTime() will be relative to the time OSInitTime() was called */
GLOBAL	VOID	OSInitTime(			VOID	);
 
/**********************************************************************************
Function name :	OSSemaphoreCreate
Parameters :	InitCount - specifies the initial token count for the semaphore
Return value :	Handle to the created semaphore to be passed as parameter for OS 
				functions acting on semaphores. Returns NULL on failure.
functionality	The tokenCount should correspond to the number of clients that can 
				simultaneously acquire the resource the semaphore controls
**********************************************************************************/
GLOBAL	HANDLE	OSSemaphoreCreate(			IN	int				InitCount);

/**********************************************************************************
Function name :	OSSemaphoreDestroy
Parameters :	hSemaphore	-	Handle identifing the semaphore.
Return value :	None
functionality :	Destroys a semaphore. Any tasks currently locked by the semaphore 
				become reschedules.
**********************************************************************************/
GLOBAL	VOID	OSSemaphoreDestroy(			IN	HANDLE			hSemaphore);

/**********************************************************************************
Function name :	OSSemaphoreWait
Parameters :	hSemaphore	-	Handle identifing the semaphore.
Return value :	None
functionality	Blocks the calling run time  if all the tokens of the semaphore are 
				currently claimed.  If the number of clients that currently hold 
				the controlled resource is less than the initial token count, 
				then wait returns immediately and the caller holds the resource.  
				Otherwise, the client is blocked until another client releases 
				the resource.
**********************************************************************************/
GLOBAL	VOID	OSSemaphoreWait(			IN	HANDLE			hSemaphore);

/**********************************************************************************
Function name :	OSSemaphoreSignal
Parameters :	hSemaphore	-	Handle identifing the semaphore.
Return value :	None
functionality :	increments the token count of the semaphore.  If run times are waiting 
				on the semaphore, one of them will be unblocked.  
				The current run time may be rescheduled this function is called.
**********************************************************************************/
GLOBAL	VOID	OSSemaphoreSignal(			IN	HANDLE			hSemaphore);

#if (OS_TYPE != OS_VXWORKS)
 
/**********************************************************************************
Function name :	OSCriticalSectionCreate
Parameters :	None
Return value :	Handle to the created critical section to be passed as parameter for OS 
				functions acting on critical section. Returns NULL on failure.
functionality :	Creates an instance of a critical section. Returns NULL on failure
**********************************************************************************/
#ifdef USE_DDK
GLOBAL HANDLE	OSCriticalSectionCreate();
#else
#if (PROJECT == PRJ_SDSL) || (PROJECT == PRJ_OCTOLOADER)
GLOBAL HANDLE	OSCriticalSectionCreate();
#else
#define OSCriticalSectionCreate() __OSCriticalSectionCreate( __FILE__, __LINE__ )
GLOBAL	HANDLE	__OSCriticalSectionCreate( char *file, int line );
#endif
#endif
/**********************************************************************************
Function name :	OSCriticalSectionDestroy
Parameters :	hMutex	-	Handle identifing the mutex.
Return value :	None
functionality : Destroys a mutex instance. Do not attemt to destroy a mutex while 
				it is acquired.
**********************************************************************************/
GLOBAL	VOID	OSCriticalSectionDestroy(	IN	HANDLE			hMutex);

/**********************************************************************************
Function name :	OSCriticalSectionAcquire
Parameters :	hMutex	-	Handle identifing the mutex.
Return value :	None
functionality:	If the mutex is unowned, the calling run time becomes the owner
				If a run time  other than the calling run time owns the mutex, 
				the calling run time is blocked until the mutex  becomes unowned.  
				If the calling run time already owns the mutex, the run time continues 
				execution.

**********************************************************************************/
GLOBAL	VOID	OSCriticalSectionAcquire(	IN	HANDLE			hMutex);

/**********************************************************************************
Function name :	OSCriticalSectionRelease
Parameters :	hMutex	-	Handle identifing the mutex.
Return value :	None
functionality:	A mutex is initially unowned, and the ownership count is zero.  For 
				each call to acquire, there must be a corresponding call to release.  
				Each time acquire is called, the ownership count  increments, and each 
				time release is called, the ownership count decrements.  Only the run time
				that owns a mutex may leave it.
				When the ownership count falls to zero, the mutex becomes unowned.  At 
				this point, a run time blocked by the mutex, with the highest priority 
				becomes schedulable.
**********************************************************************************/
GLOBAL	VOID	OSCriticalSectionRelease(	IN	HANDLE			hMutex);

#endif /** OS_VXWORKS **/
/**********************************************************************************
Function name : OSSetTimeSensitivity
Parameters :	Interval - timer interrupt interval
Return value :	None
functionality:	Determines the operatin system timeout interval, to enable timer 
				resolution control. For each call to OSSetTimeSensitivity there
				should be a matching call to OSRestoreTimeSensitivity with same Interval 
				value
**********************************************************************************/
GLOBAL	VOID	OSSetTimeSensitivity(	IN	UINT32				Interval);				

/**********************************************************************************
Function name :	OSRestoreTimeSensitivity
Parameters :	Interval - timer interrupt interval
Return value :	None
functionality :	Restores the timer interrupt to the value before OSSetTimeSensitivity
				was called
**********************************************************************************/
GLOBAL	VOID	OSRestoreTimeSensitivity(		IN	UINT32				Interval);				

/**********************************************************************************
Function name :	OSDisableInterrupt
Parameters :	None
Return value :	handle to be passed to OSRestoreInterrupt
functionality :	Disables interrupt.
**********************************************************************************/
GLOBAL	HANDLE	OSDisableInterrupt(void);

/**********************************************************************************
Function name :	OSRestoreInterrupts
Parameters :	hStatus - handle returned by OSDisableInterrupt
Return value :	None
functionality :	Restores the interrupt status as before the OSDisableInterrupt was called
**********************************************************************************/
GLOBAL	VOID	OSRestoreInterrupts(		IN	HANDLE			hStatus);



/**********************************************************************************
Function name :	OSFloatPrefix
Parameters :	None
Return value :	None
functionality :	Treats the FPU in order to enable float operations.
**********************************************************************************/
GLOBAL	int  OSFloatPrefix(void);

/**********************************************************************************
Function name :	OSFloatPrefix
Parameters :	None
Return value :	None
functionality :	Restores the FPU after float operations.
**********************************************************************************/
GLOBAL	BOOL  OSFloatSuffix(int Id);

#if (OS_TYPE == OS_LINUX) || (OS_TYPE == OS_VXWORKS)

HANDLE OSCreateTimer(UINT32 msec, PVOID pCBFunc, PVOID pRefData);
void OSSetTimer(PVOID pTimer);
void OSCancelTimer(PVOID Timer);
void OSChangeTimerTimeOut(PVOID Timer, UINT32 msec);
void OSDestroyTimer(PVOID pTimer);

#endif
 
#define OsLockCreate() OSSemaphoreCreate(1)
#define OsLockDestroy OSSemaphoreDestroy
#define OsLockLock OSSemaphoreWait
#define OsLockUnlock OSSemaphoreSignal
#define OsGetSystemTime OSGetSystemTime

 
GLOBAL  VOID    OSImmediateTimeOut      (	IN	HANDLE			hTimeOut);
 
GLOBAL VOID OSCancelPeriodicTimeOut		(	IN HANDLE			hTimeOut);
 
#if (PROJECT == PRJ_SDSL) || (PROJECT == PRJ_OCTOLOADER)
/**********************************************************************************
Function name :	OSHookInterrupt
Parameters :	pResources  - Different for each Os - includes resources needed for
                              for connecting to interrupt.
                pCallBack   - Interrupt handler 
                pConext     - Contect to be sent to interrupt handler
Return value :	HANDLE to be called to OsUnhookInterrupt
functionality :	Registers an ISR to be called on specified interrupt.
**********************************************************************************/
GLOBAL	HANDLE  OSHookInterrupt(    IN  PVOID   pResources,
                                    IN  PISR    pISRCallBack,
                                    IN  PISR    pDPCCallBack,
                                    IN  HANDLE  pConext);
 
 
/**********************************************************************************
Function name :	OSUnhookInterrupt
Parameters :	hHook  - Hnadle returned by OsHookInterrupt
Return value :	None
functionality :	Unregisters from an interrupt.
**********************************************************************************/
GLOBAL	VOID  OSUnhookInterrupt(    IN  HANDLE   hHook);
 
#endif
/********************************************************************/
/* Utilities                                                        */
/********************************************************************/

BOOL OsAtomicCompareAndSwap (PVOID oldValue, PVOID newValue, PVOID* address);
INT32	OsAtomicAdd   (INT32 amount, INT32* address);
INT32   OsAtomicIncrement (PINT32 address);
INT32   OsAtomicDecrement (PINT32 address);
void OsSleep(UINT32 SleepTime);

#if (OS_TYPE == OS_WIN_9X)
#define __FUNCTION__
#endif
 
#if (OS_TYPE == OS_VXWORKS)
int OsTaskSpawn(char *  name,      /* name of new task (stored at pStackBase) */
				int     priority,  /* priority of new task */
				int     options,   /* task option word */
				int     stackSize, /* size (bytes) of stack needed plus name */
				void*   entryPt,   /* entry point of new task */
				int     arg1,      /* 1st of 10 req'd task args to pass to func */
				int     arg2,
				int     arg3,
				int     arg4,
				int     arg5,
				int     arg6,
				int     arg7,
				int     arg8,
				int     arg9,
				int     arg10);
#endif
 
#if (OS_TYPE == OS_LINUX)
typedef unsigned long tMuSecTimeStamp;

#define GlobalProcessorFreq OsGlobalProcessorFreq
#define GetMuSecStartStamp OsGetMuSecStartStamp
#define DeltaTimeMuSec OsDeltaTimeMuSec
#define BusyLoopMilliSec OsBusyLoopMilliSec
#define BusyLoopMuSec OsBusyLoopMuSec
#define PerfCntGuardBusyLoop() {}

extern DWORD GlobalProcessorFreq;  // in MHz

tMuSecTimeStamp OsGetMuSecStartStamp(void);
tMuSecTimeStamp OsDeltaTimeMuSec(tMuSecTimeStamp PrevStamp, tMuSecTimeStamp NextStamp);
void OsBusyLoopMilliSec(DWORD DelayInMilliSecs);
void OsBusyLoopMuSec(DWORD DelayInMicroSecs);
#endif

#ifdef __cplusplus
}
#endif
 
#endif /* _OSTIME_EX_H_ */
