blob: 18c88987a0109a6dc34d8400dba48473075c448b [file] [log] [blame]
/**********************************************************************
*
* Copyright (C) Imagination Technologies Ltd. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful but, except
* as otherwise stated in writing, without any warranty; without even the
* implied warranty of merchantability or fitness for a particular purpose.
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* The full GNU General Public License is included in this distribution in
* the file called "COPYING".
*
* Contact Information:
* Imagination Technologies Ltd. <gpl-support@imgtec.com>
* Home Park Estate, Kings Langley, Herts, WD4 8LZ, UK
*
******************************************************************************/
#include <linux/version.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <asm/page.h>
#include <linux/vmalloc.h>
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15))
#include <linux/mutex.h>
#else
#include <asm/semaphore.h>
#endif
#include <linux/hardirq.h>
#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/jiffies.h>
#include <linux/delay.h>
#endif
#include "img_types.h"
#include "pvr_debug.h"
#include "dbgdrvif.h"
#include "hostfunc.h"
#include "dbgdriv.h"
#if defined(MODULE) && defined(DEBUG) && !defined(SUPPORT_DRI_DRM)
IMG_UINT32 gPVRDebugLevel = (DBGPRIV_FATAL | DBGPRIV_ERROR | DBGPRIV_WARNING);
#define PVR_STRING_TERMINATOR '\0'
#define PVR_IS_FILE_SEPARATOR(character) ( ((character) == '\\') || ((character) == '/') )
void PVRSRVDebugPrintf (
IMG_UINT32 ui32DebugLevel,
const IMG_CHAR* pszFileName,
IMG_UINT32 ui32Line,
const IMG_CHAR* pszFormat,
...
)
{
IMG_BOOL bTrace;
#if !defined(__sh__)
IMG_CHAR *pszLeafName;
pszLeafName = (char *)strrchr (pszFileName, '\\');
if (pszLeafName)
{
pszFileName = pszLeafName;
}
#endif
bTrace = (IMG_BOOL)(ui32DebugLevel & DBGPRIV_CALLTRACE) ? IMG_TRUE : IMG_FALSE;
if (gPVRDebugLevel & ui32DebugLevel)
{
va_list vaArgs;
char szBuffer[256];
char *szBufferEnd = szBuffer;
char *szBufferLimit = szBuffer + sizeof(szBuffer) - 1;
*szBufferLimit = '\0';
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "PVR_K:");
szBufferEnd += strlen(szBufferEnd);
if (bTrace == IMG_FALSE)
{
switch(ui32DebugLevel)
{
case DBGPRIV_FATAL:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Fatal):");
break;
}
case DBGPRIV_ERROR:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Error):");
break;
}
case DBGPRIV_WARNING:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Warning):");
break;
}
case DBGPRIV_MESSAGE:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Message):");
break;
}
case DBGPRIV_VERBOSE:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Verbose):");
break;
}
default:
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, "(Unknown message level)");
break;
}
}
szBufferEnd += strlen(szBufferEnd);
}
snprintf(szBufferEnd, szBufferLimit - szBufferEnd, " ");
szBufferEnd += strlen(szBufferEnd);
va_start (vaArgs, pszFormat);
vsnprintf(szBufferEnd, szBufferLimit - szBufferEnd, pszFormat, vaArgs);
va_end (vaArgs);
szBufferEnd += strlen(szBufferEnd);
if (bTrace == IMG_FALSE)
{
snprintf(szBufferEnd, szBufferLimit - szBufferEnd,
" [%d, %s]", (int)ui32Line, pszFileName);
szBufferEnd += strlen(szBufferEnd);
}
printk(KERN_INFO "%s\r\n", szBuffer);
}
}
#endif
IMG_VOID HostMemSet(IMG_VOID *pvDest, IMG_UINT8 ui8Value, IMG_UINT32 ui32Size)
{
memset(pvDest, (int) ui8Value, (size_t) ui32Size);
}
IMG_VOID HostMemCopy(IMG_VOID *pvDst, IMG_VOID *pvSrc, IMG_UINT32 ui32Size)
{
#if defined(USE_UNOPTIMISED_MEMCPY)
unsigned char *src,*dst;
int i;
src=(unsigned char *)pvSrc;
dst=(unsigned char *)pvDst;
for(i=0;i<ui32Size;i++)
{
dst[i]=src[i];
}
#else
memcpy(pvDst, pvSrc, ui32Size);
#endif
}
IMG_UINT32 HostReadRegistryDWORDFromString(char *pcKey, char *pcValueName, IMG_UINT32 *pui32Data)
{
return 0;
}
IMG_VOID * HostPageablePageAlloc(IMG_UINT32 ui32Pages)
{
return (void*)vmalloc(ui32Pages * PAGE_SIZE);
}
IMG_VOID HostPageablePageFree(IMG_VOID * pvBase)
{
vfree(pvBase);
}
IMG_VOID * HostNonPageablePageAlloc(IMG_UINT32 ui32Pages)
{
return (void*)vmalloc(ui32Pages * PAGE_SIZE);
}
IMG_VOID HostNonPageablePageFree(IMG_VOID * pvBase)
{
vfree(pvBase);
}
IMG_VOID * HostMapKrnBufIntoUser(IMG_VOID * pvKrnAddr, IMG_UINT32 ui32Size, IMG_VOID **ppvMdl)
{
return IMG_NULL;
}
IMG_VOID HostUnMapKrnBufFromUser(IMG_VOID * pvUserAddr, IMG_VOID * pvMdl, IMG_VOID * pvProcess)
{
}
IMG_VOID HostCreateRegDeclStreams(IMG_VOID)
{
}
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
typedef struct mutex MUTEX;
#define INIT_MUTEX(m) mutex_init(m)
#define DOWN_TRYLOCK(m) (!mutex_trylock(m))
#define DOWN(m) mutex_lock(m)
#define UP(m) mutex_unlock(m)
#else
typedef struct semaphore MUTEX;
#define INIT_MUTEX(m) init_MUTEX(m)
#define DOWN_TRYLOCK(m) down_trylock(m)
#define DOWN(m) down(m)
#define UP(m) up(m)
#endif
IMG_VOID *HostCreateMutex(IMG_VOID)
{
MUTEX *psMutex;
psMutex = kmalloc(sizeof(*psMutex), GFP_KERNEL);
if (psMutex)
{
INIT_MUTEX(psMutex);
}
return psMutex;
}
IMG_VOID HostAquireMutex(IMG_VOID * pvMutex)
{
BUG_ON(in_interrupt());
#if defined(PVR_DEBUG_DBGDRV_DETECT_HOST_MUTEX_COLLISIONS)
if (DOWN_TRYLOCK((MUTEX *)pvMutex))
{
printk(KERN_INFO "HostAquireMutex: Waiting for mutex\n");
DOWN((MUTEX *)pvMutex);
}
#else
DOWN((MUTEX *)pvMutex);
#endif
}
IMG_VOID HostReleaseMutex(IMG_VOID * pvMutex)
{
UP((MUTEX *)pvMutex);
}
IMG_VOID HostDestroyMutex(IMG_VOID * pvMutex)
{
if (pvMutex)
{
kfree(pvMutex);
}
}
#if defined(SUPPORT_DBGDRV_EVENT_OBJECTS)
#define EVENT_WAIT_TIMEOUT_MS 500
#define EVENT_WAIT_TIMEOUT_JIFFIES (EVENT_WAIT_TIMEOUT_MS * HZ / 1000)
static int iStreamData;
static wait_queue_head_t sStreamDataEvent;
IMG_INT32 HostCreateEventObjects(IMG_VOID)
{
init_waitqueue_head(&sStreamDataEvent);
return 0;
}
IMG_VOID HostWaitForEvent(DBG_EVENT eEvent)
{
switch(eEvent)
{
case DBG_EVENT_STREAM_DATA:
wait_event_interruptible_timeout(sStreamDataEvent, iStreamData != 0, EVENT_WAIT_TIMEOUT_JIFFIES);
iStreamData = 0;
break;
default:
msleep_interruptible(EVENT_WAIT_TIMEOUT_MS);
break;
}
}
IMG_VOID HostSignalEvent(DBG_EVENT eEvent)
{
switch(eEvent)
{
case DBG_EVENT_STREAM_DATA:
iStreamData = 1;
wake_up_interruptible(&sStreamDataEvent);
break;
default:
break;
}
}
IMG_VOID HostDestroyEventObjects(IMG_VOID)
{
}
#endif