diff options
Diffstat (limited to 'drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c')
-rw-r--r-- | drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c | 736 |
1 files changed, 582 insertions, 154 deletions
diff --git a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c index 0a0253a23e33..7964585e7afa 100644 --- a/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c +++ b/drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c @@ -1,6 +1,6 @@ /**************************************************************************** * -* Copyright (C) 2005 - 2012 by Vivante Corp. +* Copyright (C) 2005 - 2013 by Vivante Corp. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,8 +19,6 @@ *****************************************************************************/ - - #include "gc_hal_kernel_precomp.h" #define _GC_OBJ_ZONE gcvZONE_KERNEL @@ -176,6 +174,15 @@ gckKERNEL_Construct( kernel->command = gcvNULL; kernel->eventObj = gcvNULL; kernel->mmu = gcvNULL; +#if gcdDVFS + kernel->dvfs = gcvNULL; +#endif + + /* Initialize the gckKERNEL object. */ + kernel->object.type = gcvOBJ_KERNEL; + kernel->os = Os; + kernel->core = Core; + if (SharedDB == gcvNULL) { @@ -200,6 +207,12 @@ gckKERNEL_Construct( /* Construct a database mutex. */ gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->dbMutex)); + + /* Construct a id-pointer database. */ + gcmkONERROR(gckKERNEL_CreateIntegerDatabase(kernel, &kernel->db->pointerDatabase)); + + /* Construct a id-pointer database mutex. */ + gcmkONERROR(gckOS_CreateMutex(Os, &kernel->db->pointerDatabaseMutex)); } else { @@ -215,11 +228,6 @@ gckKERNEL_Construct( kernel->timeOut = gcdGPU_TIMEOUT; - /* Initialize the gckKERNEL object. */ - kernel->object.type = gcvOBJ_KERNEL; - kernel->os = Os; - kernel->core = Core; - /* Save context. */ kernel->context = Context; @@ -279,6 +287,16 @@ gckKERNEL_Construct( (gctTIMERFUNCTION)_ResetFinishFunction, (gctPOINTER)kernel, &kernel->resetFlagClearTimer)); + kernel->resetTimeStamp = 0; +#endif + +#if gcdDVFS + if (gckHARDWARE_IsFeatureAvailable(kernel->hardware, + gcvFEATURE_DYNAMIC_FREQUENCY_SCALING)) + { + gcmkONERROR(gckDVFS_Construct(kernel->hardware, &kernel->dvfs)); + gcmkONERROR(gckDVFS_Start(kernel->dvfs)); + } #endif } @@ -346,7 +364,7 @@ OnError: if (kernel->resetFlagClearTimer) { gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer)); - gcmkVERIFY_OK(gckOS_DestoryTimer(Os, kernel->resetFlagClearTimer)); + gcmkVERIFY_OK(gckOS_DestroyTimer(Os, kernel->resetFlagClearTimer)); } #endif @@ -369,6 +387,14 @@ OnError: } #endif +#if gcdDVFS + if (kernel->dvfs) + { + gcmkVERIFY_OK(gckDVFS_Stop(kernel->dvfs)); + gcmkVERIFY_OK(gckDVFS_Destroy(kernel->dvfs)); + } +#endif + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, kernel)); } @@ -444,6 +470,13 @@ gckKERNEL_Destroy( /* Destroy the database mutex. */ gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->dbMutex)); + + + /* Destroy id-pointer database. */ + gcmkVERIFY_OK(gckKERNEL_DestroyIntegerDatabase(Kernel, Kernel->db->pointerDatabase)); + + /* Destroy id-pointer database mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->db->pointerDatabaseMutex)); } #if gcdENABLE_VG @@ -472,7 +505,7 @@ gckKERNEL_Destroy( if (Kernel->resetFlagClearTimer) { gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer)); - gcmkVERIFY_OK(gckOS_DestoryTimer(Kernel->os, Kernel->resetFlagClearTimer)); + gcmkVERIFY_OK(gckOS_DestroyTimer(Kernel->os, Kernel->resetFlagClearTimer)); } #endif } @@ -484,6 +517,14 @@ gckKERNEL_Destroy( gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, Kernel->virtualBufferLock)); #endif +#if gcdDVFS + if (Kernel->dvfs) + { + gcmkVERIFY_OK(gckDVFS_Stop(Kernel->dvfs)); + gcmkVERIFY_OK(gckDVFS_Destroy(Kernel->dvfs)); + } +#endif + /* Mark the gckKERNEL object as unknown. */ Kernel->object.type = gcvOBJ_UNKNOWN; @@ -502,27 +543,9 @@ gckKERNEL_Destroy( #include <linux/sched.h> #include <linux/notifier.h> -static struct task_struct *lowmem_deathpending; +extern struct task_struct *lowmem_deathpending; static unsigned long lowmem_deathpending_timeout; -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data); - -static struct notifier_block task_nb = { - .notifier_call = task_notify_func, -}; - -static int -task_notify_func(struct notifier_block *self, unsigned long val, void *data) -{ - struct task_struct *task = data; - - if (task == lowmem_deathpending) - lowmem_deathpending = NULL; - - return NOTIFY_OK; -} - static int force_contiguous_lowmem_shrink(IN gckKERNEL Kernel) { struct task_struct *p; @@ -644,9 +667,6 @@ _AllocateMemory( gcuVIDMEM_NODE_PTR node = gcvNULL; gctBOOL tileStatusInVirtual; gctBOOL forceContiguous = gcvFALSE; -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT - gctBOOL forceContiguousShrinking = gcvFALSE; -#endif gcmkHEADER_ARG("Kernel=0x%x *Pool=%d Bytes=%lu Alignment=%lu Type=%d", Kernel, *Pool, Bytes, Alignment, Type); @@ -806,12 +826,6 @@ _AllocateMemory_Retry: #ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT if(forceContiguous == gcvTRUE) { - if(forceContiguousShrinking == gcvFALSE) - { - forceContiguousShrinking = gcvTRUE; - task_free_register(&task_nb); - } - if(force_contiguous_lowmem_shrink(Kernel) == 0) { /* Sleep 1 millisecond. */ @@ -824,13 +838,6 @@ _AllocateMemory_Retry: gcmkONERROR(gcvSTATUS_OUT_OF_MEMORY); } -#ifdef CONFIG_ANDROID_RESERVED_MEMORY_ACCOUNT - if(forceContiguous == gcvTRUE && forceContiguousShrinking == gcvTRUE) - { - task_free_unregister(&task_nb); - } -#endif - /* Return node and pool used for allocation. */ *Node = node; *Pool = pool; @@ -882,11 +889,14 @@ gckKERNEL_Dispatch( gcuVIDMEM_NODE_PTR node; gctBOOL locked = gcvFALSE; gctPHYS_ADDR physical = gcvNULL; + gctPOINTER logical = gcvNULL; + gctPOINTER info = gcvNULL; + gckCONTEXT context = gcvNULL; gctUINT32 address; gctUINT32 processID; + gckKERNEL kernel = Kernel; #if gcdSECURE_USER gcskSECURE_CACHE_PTR cache; - gctPOINTER logical; #endif gctBOOL asynchronous; gctPOINTER paddr = gcvNULL; @@ -944,156 +954,185 @@ gckKERNEL_Dispatch( break; case gcvHAL_MAP_MEMORY: - physical = Interface->u.MapMemory.physical; + physical = gcmINT2PTR(Interface->u.MapMemory.physical); /* Map memory. */ gcmkONERROR( gckKERNEL_MapMemory(Kernel, physical, - Interface->u.MapMemory.bytes, - &Interface->u.MapMemory.logical)); + (gctSIZE_T) Interface->u.MapMemory.bytes, + &logical)); + + Interface->u.MapMemory.logical = gcmPTR_TO_UINT64(logical); + gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_MAP_MEMORY, - Interface->u.MapMemory.logical, + logical, physical, - Interface->u.MapMemory.bytes)); + (gctSIZE_T) Interface->u.MapMemory.bytes)); break; case gcvHAL_UNMAP_MEMORY: - physical = Interface->u.UnmapMemory.physical; + physical = gcmINT2PTR(Interface->u.UnmapMemory.physical); /* Unmap memory. */ gcmkONERROR( gckKERNEL_UnmapMemory(Kernel, physical, - Interface->u.UnmapMemory.bytes, - Interface->u.UnmapMemory.logical)); + (gctSIZE_T) Interface->u.UnmapMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_MAP_MEMORY, - Interface->u.UnmapMemory.logical)); + gcmUINT64_TO_PTR(Interface->u.UnmapMemory.logical))); break; case gcvHAL_ALLOCATE_NON_PAGED_MEMORY: + bytes = (gctSIZE_T) Interface->u.AllocateNonPagedMemory.bytes; + /* Allocate non-paged memory. */ gcmkONERROR( gckOS_AllocateNonPagedMemory( Kernel->os, FromUser, - &Interface->u.AllocateNonPagedMemory.bytes, - &Interface->u.AllocateNonPagedMemory.physical, - &Interface->u.AllocateNonPagedMemory.logical)); + &bytes, + &physical, + &logical)); + + Interface->u.AllocateNonPagedMemory.bytes = bytes; + Interface->u.AllocateNonPagedMemory.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateNonPagedMemory.physical = gcmPTR_TO_NAME(physical); gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_NON_PAGED, - Interface->u.AllocateNonPagedMemory.logical, - Interface->u.AllocateNonPagedMemory.physical, - Interface->u.AllocateNonPagedMemory.bytes)); + logical, + gcmINT2PTR(Interface->u.AllocateNonPagedMemory.physical), + bytes)); + break; case gcvHAL_ALLOCATE_VIRTUAL_COMMAND_BUFFER: #if gcdVIRTUAL_COMMAND_BUFFER + bytes = (gctSIZE_T) Interface->u.AllocateVirtualCommandBuffer.bytes; + gcmkONERROR( gckKERNEL_AllocateVirtualCommandBuffer( Kernel, FromUser, - &Interface->u.AllocateVirtualCommandBuffer.bytes, - &Interface->u.AllocateVirtualCommandBuffer.physical, - &Interface->u.AllocateVirtualCommandBuffer.logical)); + &bytes, + &physical, + &logical)); + + Interface->u.AllocateVirtualCommandBuffer.bytes = bytes; + Interface->u.AllocateVirtualCommandBuffer.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateVirtualCommandBuffer.physical = gcmPTR_TO_NAME(physical); gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_COMMAND_BUFFER, - Interface->u.AllocateVirtualCommandBuffer.logical, - Interface->u.AllocateVirtualCommandBuffer.physical, - Interface->u.AllocateVirtualCommandBuffer.bytes)); + logical, + gcmINT2PTR(Interface->u.AllocateVirtualCommandBuffer.physical), + bytes)); #else status = gcvSTATUS_NOT_SUPPORTED; #endif break; case gcvHAL_FREE_NON_PAGED_MEMORY: - physical = Interface->u.FreeNonPagedMemory.physical; + physical = gcmNAME_TO_PTR(Interface->u.FreeNonPagedMemory.physical); /* Unmap user logical out of physical memory first. */ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, physical, - Interface->u.FreeNonPagedMemory.bytes, - Interface->u.FreeNonPagedMemory.logical)); + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); /* Free non-paged memory. */ gcmkONERROR( gckOS_FreeNonPagedMemory(Kernel->os, - Interface->u.FreeNonPagedMemory.bytes, + (gctSIZE_T) Interface->u.FreeNonPagedMemory.bytes, physical, - Interface->u.FreeNonPagedMemory.logical)); + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_NON_PAGED, - Interface->u.FreeNonPagedMemory.logical)); + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); #if gcdSECURE_USER gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( Kernel, cache, - Interface->u.FreeNonPagedMemory.logical, + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical), Interface->u.FreeNonPagedMemory.bytes)); #endif + + gcmRELEASE_NAME(Interface->u.FreeNonPagedMemory.physical); + break; case gcvHAL_ALLOCATE_CONTIGUOUS_MEMORY: + bytes = (gctSIZE_T) Interface->u.AllocateContiguousMemory.bytes; + /* Allocate contiguous memory. */ gcmkONERROR(gckOS_AllocateContiguous( Kernel->os, FromUser, - &Interface->u.AllocateContiguousMemory.bytes, - &Interface->u.AllocateContiguousMemory.physical, - &Interface->u.AllocateContiguousMemory.logical)); + &bytes, + &physical, + &logical)); + + Interface->u.AllocateContiguousMemory.bytes = bytes; + Interface->u.AllocateContiguousMemory.logical = gcmPTR_TO_UINT64(logical); + Interface->u.AllocateContiguousMemory.physical = gcmPTR_TO_NAME(physical); gcmkONERROR(gckHARDWARE_ConvertLogical( Kernel->hardware, - Interface->u.AllocateContiguousMemory.logical, + gcmUINT64_TO_PTR(Interface->u.AllocateContiguousMemory.logical), &Interface->u.AllocateContiguousMemory.address)); gcmkVERIFY_OK(gckKERNEL_AddProcessDB( Kernel, processID, gcvDB_CONTIGUOUS, - Interface->u.AllocateContiguousMemory.logical, - Interface->u.AllocateContiguousMemory.physical, - Interface->u.AllocateContiguousMemory.bytes)); + logical, + gcmINT2PTR(Interface->u.AllocateContiguousMemory.physical), + bytes)); + break; case gcvHAL_FREE_CONTIGUOUS_MEMORY: - physical = Interface->u.FreeContiguousMemory.physical; + physical = gcmNAME_TO_PTR(Interface->u.FreeContiguousMemory.physical); /* Unmap user logical out of physical memory first. */ gcmkONERROR(gckOS_UnmapUserLogical(Kernel->os, physical, - Interface->u.FreeContiguousMemory.bytes, - Interface->u.FreeContiguousMemory.logical)); + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes, + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical))); /* Free contiguous memory. */ gcmkONERROR( gckOS_FreeContiguous(Kernel->os, physical, - Interface->u.FreeContiguousMemory.logical, - Interface->u.FreeContiguousMemory.bytes)); + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), + (gctSIZE_T) Interface->u.FreeContiguousMemory.bytes)); gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_CONTIGUOUS, - Interface->u.FreeNonPagedMemory.logical)); + gcmUINT64_TO_PTR(Interface->u.FreeNonPagedMemory.logical))); #if gcdSECURE_USER gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( Kernel, cache, - Interface->u.FreeContiguousMemory.logical, + gcmUINT64_TO_PTR(Interface->u.FreeContiguousMemory.logical), Interface->u.FreeContiguousMemory.bytes)); #endif + + gcmRELEASE_NAME(Interface->u.FreeContiguousMemory.physical); + break; case gcvHAL_ALLOCATE_VIDEO_MEMORY: @@ -1110,10 +1149,8 @@ gckKERNEL_Dispatch( Interface->u.AllocateLinearVideoMemory.bytes, Interface->u.AllocateLinearVideoMemory.alignment, Interface->u.AllocateLinearVideoMemory.type, - &Interface->u.AllocateLinearVideoMemory.node)); + &node)); - /* Get actual size of node. */ - node = Interface->u.AllocateLinearVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { bytes = node->VidMem.bytes; @@ -1126,14 +1163,17 @@ gckKERNEL_Dispatch( gcmkONERROR( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_VIDEO_MEMORY, - Interface->u.AllocateLinearVideoMemory.node, + node, gcvNULL, bytes)); + + /* Get the node. */ + Interface->u.AllocateLinearVideoMemory.node = gcmPTR_TO_UINT64(node); break; case gcvHAL_FREE_VIDEO_MEMORY: + node = gcmUINT64_TO_PTR(Interface->u.FreeVideoMemory.node); #ifdef __QNXNTO__ - node = Interface->u.FreeVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM && node->VidMem.logical != gcvNULL) { @@ -1147,25 +1187,27 @@ gckKERNEL_Dispatch( #endif /* Free video memory. */ gcmkONERROR( - gckVIDMEM_Free(Interface->u.FreeVideoMemory.node)); + gckVIDMEM_Free(node)); gcmkONERROR( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_VIDEO_MEMORY, - Interface->u.FreeVideoMemory.node)); + node)); + break; case gcvHAL_LOCK_VIDEO_MEMORY: + node = gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node); + /* Lock video memory. */ gcmkONERROR( gckVIDMEM_Lock(Kernel, - Interface->u.LockVideoMemory.node, + node, Interface->u.LockVideoMemory.cacheable, &Interface->u.LockVideoMemory.address)); locked = gcvTRUE; - node = Interface->u.LockVideoMemory.node; if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { /* Map video memory address into user space. */ @@ -1182,18 +1224,20 @@ gckKERNEL_Dispatch( } gcmkASSERT(node->VidMem.logical != gcvNULL); - Interface->u.LockVideoMemory.memory = node->VidMem.logical; + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->VidMem.logical); #else gcmkONERROR( gckKERNEL_MapVideoMemory(Kernel, FromUser, Interface->u.LockVideoMemory.address, - &Interface->u.LockVideoMemory.memory)); + &logical)); + + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(logical); #endif } else { - Interface->u.LockVideoMemory.memory = node->Virtual.logical; + Interface->u.LockVideoMemory.memory = gcmPTR_TO_UINT64(node->Virtual.logical); /* Success. */ status = gcvSTATUS_OK; @@ -1202,12 +1246,12 @@ gckKERNEL_Dispatch( #if gcdSECURE_USER /* Return logical address as physical address. */ Interface->u.LockVideoMemory.address = - gcmPTR2INT(Interface->u.LockVideoMemory.memory); + Interface->u.LockVideoMemory.memory; #endif gcmkONERROR( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_VIDEO_MEMORY_LOCKED, - Interface->u.LockVideoMemory.node, + node, gcvNULL, 0)); @@ -1215,7 +1259,7 @@ gckKERNEL_Dispatch( case gcvHAL_UNLOCK_VIDEO_MEMORY: /* Unlock video memory. */ - node = Interface->u.UnlockVideoMemory.node; + node = gcmUINT64_TO_PTR(Interface->u.UnlockVideoMemory.node); #if gcdSECURE_USER /* Save node information before it disappears. */ @@ -1254,26 +1298,25 @@ gckKERNEL_Dispatch( gcmkONERROR( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_VIDEO_MEMORY_LOCKED, - Interface->u.UnlockVideoMemory.node)); + node)); } - break; case gcvHAL_EVENT_COMMIT: /* Commit an event queue. */ gcmkONERROR( gckEVENT_Commit(Kernel->eventObj, - Interface->u.Event.queue)); + gcmUINT64_TO_PTR(Interface->u.Event.queue))); break; case gcvHAL_COMMIT: /* Commit a command and context buffer. */ gcmkONERROR( gckCOMMAND_Commit(Kernel->command, - Interface->u.Commit.context, - Interface->u.Commit.commandBuffer, - Interface->u.Commit.delta, - Interface->u.Commit.queue, + gcmNAME_TO_PTR(Interface->u.Commit.context), + gcmUINT64_TO_PTR(Interface->u.Commit.commandBuffer), + gcmUINT64_TO_PTR(Interface->u.Commit.delta), + gcmUINT64_TO_PTR(Interface->u.Commit.queue), processID)); break; @@ -1287,42 +1330,49 @@ gckKERNEL_Dispatch( gcmkONERROR( gckOS_MapUserMemory(Kernel->os, Kernel->core, - Interface->u.MapUserMemory.memory, + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory), Interface->u.MapUserMemory.physical, - Interface->u.MapUserMemory.size, - &Interface->u.MapUserMemory.info, + (gctSIZE_T) Interface->u.MapUserMemory.size, + &info, &Interface->u.MapUserMemory.address)); + + Interface->u.MapUserMemory.info = gcmPTR_TO_NAME(info); + gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_MAP_USER_MEMORY, - Interface->u.MapUserMemory.info, - Interface->u.MapUserMemory.memory, - Interface->u.MapUserMemory.size)); + gcmINT2PTR(Interface->u.MapUserMemory.info), + gcmUINT64_TO_PTR(Interface->u.MapUserMemory.memory), + (gctSIZE_T) Interface->u.MapUserMemory.size)); break; case gcvHAL_UNMAP_USER_MEMORY: address = Interface->u.UnmapUserMemory.address; + info = gcmNAME_TO_PTR(Interface->u.UnmapUserMemory.info); /* Unmap user memory. */ gcmkONERROR( gckOS_UnmapUserMemory(Kernel->os, Kernel->core, - Interface->u.UnmapUserMemory.memory, - Interface->u.UnmapUserMemory.size, - Interface->u.UnmapUserMemory.info, + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory), + (gctSIZE_T) Interface->u.UnmapUserMemory.size, + info, address)); #if gcdSECURE_USER gcmkVERIFY_OK(gckKERNEL_FlushTranslationCache( Kernel, cache, - Interface->u.UnmapUserMemory.memory, + gcmUINT64_TO_PTR(Interface->u.UnmapUserMemory.memory), Interface->u.UnmapUserMemory.size)); #endif gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_MAP_USER_MEMORY, - Interface->u.UnmapUserMemory.info)); + gcmINT2PTR(Interface->u.UnmapUserMemory.info))); + + gcmRELEASE_NAME(Interface->u.UnmapUserMemory.info); + break; #if !USE_NEW_LINUX_SIGNAL @@ -1571,7 +1621,7 @@ gckKERNEL_Dispatch( gcmkONERROR( gckHARDWARE_ProfileEngine2D( Kernel->hardware, - Interface->u.RegisterProfileData2D.hwProfile2D)); + gcmUINT64_TO_PTR(Interface->u.RegisterProfileData2D.hwProfile2D))); #else status = gcvSTATUS_OK; #endif @@ -1686,14 +1736,15 @@ gckKERNEL_Dispatch( break; case gcvHAL_CACHE: - if (Interface->u.Cache.node == gcvNULL) + node = gcmUINT64_TO_PTR(Interface->u.Cache.node); + if (node == gcvNULL) { /* FIXME Surface wrap some memory which is not allocated by us, ** So we don't have physical address to handle outer cache, ignore it*/ status = gcvSTATUS_OK; break; } - else if (Interface->u.Cache.node->VidMem.memory->object.type == gcvOBJ_VIDMEM) + else if (node->VidMem.memory->object.type == gcvOBJ_VIDMEM) { /* Video memory has no physical handles. */ physical = gcvNULL; @@ -1701,9 +1752,11 @@ gckKERNEL_Dispatch( else { /* Grab physical handle. */ - physical = Interface->u.Cache.node->Virtual.physical; + physical = node->Virtual.physical; } + logical = gcmUINT64_TO_PTR(Interface->u.Cache.logical); + bytes = (gctSIZE_T) Interface->u.Cache.bytes; switch(Interface->u.Cache.operation) { case gcvCACHE_FLUSH: @@ -1712,8 +1765,8 @@ gckKERNEL_Dispatch( processID, physical, paddr, - Interface->u.Cache.logical, - Interface->u.Cache.bytes); + logical, + bytes); break; case gcvCACHE_CLEAN: /* Clean the cache. */ @@ -1721,8 +1774,8 @@ gckKERNEL_Dispatch( processID, physical, paddr, - Interface->u.Cache.logical, - Interface->u.Cache.bytes); + logical, + bytes); break; case gcvCACHE_INVALIDATE: /* Invalidate the cache. */ @@ -1730,13 +1783,13 @@ gckKERNEL_Dispatch( processID, physical, paddr, - Interface->u.Cache.logical, - Interface->u.Cache.bytes); + logical, + bytes); break; case gcvCACHE_MEMORY_BARRIER: status = gckOS_MemoryBarrier(Kernel->os, - Interface->u.Cache.logical); + logical); break; default: status = gcvSTATUS_INVALID_ARGUMENT; @@ -1836,14 +1889,17 @@ gckKERNEL_Dispatch( /* Attach user process. */ gcmkONERROR( gckCOMMAND_Attach(Kernel->command, - &Interface->u.Attach.context, - &Interface->u.Attach.stateCount, + &context, + &bytes, processID)); + Interface->u.Attach.stateCount = bytes; + Interface->u.Attach.context = gcmPTR_TO_NAME(context); + gcmkVERIFY_OK( gckKERNEL_AddProcessDB(Kernel, processID, gcvDB_CONTEXT, - Interface->u.Attach.context, + gcmINT2PTR(Interface->u.Attach.context), gcvNULL, 0)); break; @@ -1852,15 +1908,18 @@ gckKERNEL_Dispatch( /* Detach user process. */ gcmkONERROR( gckCOMMAND_Detach(Kernel->command, - Interface->u.Detach.context)); + gcmNAME_TO_PTR(Interface->u.Detach.context))); gcmkVERIFY_OK( gckKERNEL_RemoveProcessDB(Kernel, processID, gcvDB_CONTEXT, - Interface->u.Detach.context)); + gcmINT2PTR(Interface->u.Detach.context))); + + gcmRELEASE_NAME(Interface->u.Detach.context); break; case gcvHAL_COMPOSE: + Interface->u.Compose.physical = gcmPTR_TO_UINT64(gcmNAME_TO_PTR(Interface->u.Compose.physical)); /* Start composition. */ gcmkONERROR( gckEVENT_Compose(Kernel->eventObj, @@ -1876,11 +1935,13 @@ gckKERNEL_Dispatch( case gcvHAL_GET_FRAME_INFO: gcmkONERROR(gckHARDWARE_GetFrameInfo( Kernel->hardware, - Interface->u.GetFrameInfo.frameInfo)); + gcmUINT64_TO_PTR(Interface->u.GetFrameInfo.frameInfo))); break; #endif case gcvHAL_GET_SHARED_INFO: + bytes = (gctSIZE_T) Interface->u.GetSharedInfo.size; + if (Interface->u.GetSharedInfo.dataId != 0) { gcmkONERROR(gckKERNEL_FindProcessDB(Kernel, @@ -1891,7 +1952,7 @@ gckKERNEL_Dispatch( &record)); /* find a record in db, check size */ - if (record.bytes != Interface->u.GetSharedInfo.size) + if (record.bytes != bytes) { /* Size change is not allowed */ gcmkONERROR(gcvSTATUS_INVALID_DATA); @@ -1901,13 +1962,13 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyToUserData( Kernel->os, record.physical, - Interface->u.GetSharedInfo.data, - Interface->u.GetSharedInfo.size + gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.data), + bytes )); } - if ((node = Interface->u.GetSharedInfo.node) != gcvNULL) + if ((node = gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.node)) != gcvNULL) { switch (Interface->u.GetSharedInfo.infoType) { @@ -1926,7 +1987,7 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyToUserData( Kernel->os, data, - Interface->u.GetSharedInfo.nodeData, + gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.nodeData), sizeof(gcsVIDMEM_NODE_SHARED_INFO) )); } @@ -1964,7 +2025,7 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyToUserData( Kernel->os, &alignedSharedInfo, - Interface->u.GetSharedInfo.nodeData, + gcmUINT64_TO_PTR(Interface->u.GetSharedInfo.nodeData), sizeof(gcsVIDMEM_NODE_SHARED_INFO) )); @@ -1987,6 +2048,8 @@ gckKERNEL_Dispatch( break; case gcvHAL_SET_SHARED_INFO: + bytes = (gctSIZE_T) Interface->u.SetSharedInfo.size; + if (Interface->u.SetSharedInfo.dataId != 0) { status = gckKERNEL_FindProcessDB(Kernel, processID, 0, @@ -2000,7 +2063,7 @@ gckKERNEL_Dispatch( /* Note: we count on DestoryProcessDB to free it */ gcmkONERROR(gckOS_AllocateMemory( Kernel->os, - Interface->u.SetSharedInfo.size, + bytes, &data )); @@ -2009,7 +2072,7 @@ gckKERNEL_Dispatch( gcvDB_SHARED_INFO, gcmINT2PTR(Interface->u.SetSharedInfo.dataId), data, - Interface->u.SetSharedInfo.size + bytes )); } else @@ -2018,7 +2081,7 @@ gckKERNEL_Dispatch( gcmkONERROR(status); /* find a record in db, check size */ - if (record.bytes != Interface->u.SetSharedInfo.size) + if (record.bytes != bytes) { /* Size change is not allowed */ gcmkONERROR(gcvSTATUS_INVALID_DATA); @@ -2031,12 +2094,12 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyFromUserData( Kernel->os, data, - Interface->u.SetSharedInfo.data, - Interface->u.SetSharedInfo.size + gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.data), + bytes )); } - if ((node = Interface->u.SetSharedInfo.node) != gcvNULL) + if ((node = gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.node)) != gcvNULL) { switch (Interface->u.SetSharedInfo.infoType) { @@ -2054,7 +2117,7 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyFromUserData( Kernel->os, data, - Interface->u.SetSharedInfo.nodeData, + gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.nodeData), sizeof(gcsVIDMEM_NODE_SHARED_INFO) )); } @@ -2070,7 +2133,7 @@ gckKERNEL_Dispatch( gcmkONERROR(gckOS_CopyFromUserData( Kernel->os, &newSharedInfo, - Interface->u.SetSharedInfo.nodeData, + gcmUINT64_TO_PTR(Interface->u.SetSharedInfo.nodeData), gcmSIZEOF(gcsVIDMEM_NODE_SHARED_INFO) )); @@ -2141,6 +2204,14 @@ gckKERNEL_Dispatch( #endif break; + case gcvHAL_QUERY_RESET_TIME_STAMP: +#if gcdENABLE_RECOVERY + Interface->u.QueryResetTimeStamp.timeStamp = Kernel->resetTimeStamp; +#else + Interface->u.QueryResetTimeStamp.timeStamp = 0; +#endif + break; + default: /* Invalid command. */ gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); @@ -2157,7 +2228,7 @@ OnError: /* Roll back the lock. */ gcmkVERIFY_OK( gckVIDMEM_Unlock(Kernel, - Interface->u.LockVideoMemory.node, + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node), gcvSURF_TYPE_UNKNOWN, &asynchronous)); @@ -2166,7 +2237,7 @@ OnError: /* Bottom Half */ gcmkVERIFY_OK( gckVIDMEM_Unlock(Kernel, - Interface->u.LockVideoMemory.node, + gcmUINT64_TO_PTR(Interface->u.LockVideoMemory.node), gcvSURF_TYPE_UNKNOWN, gcvNULL)); } @@ -2944,6 +3015,8 @@ gckKERNEL_Recovery( #endif gcmkONERROR(gckEVENT_Notify(eventObj, 2)); + Kernel->resetTimeStamp++; + /* Success. */ gcmkFOOTER_NO(); return gcvSTATUS_OK; @@ -3472,6 +3545,361 @@ gckLINKQUEUE_GetData( } #endif +/******************************************************************************\ +*************************** Pointer - ID translation *************************** +\******************************************************************************/ +#define gcdID_TABLE_LENGTH 1024 +typedef struct _gcsINTEGERDB * gckINTEGERDB; +typedef struct _gcsINTEGERDB +{ + gckOS os; + gctPOINTER* table; + gctPOINTER mutex; + gctUINT32 tableLen; + gctUINT32 currentID; + gctUINT32 unused; +} +gcsINTEGERDB; + +gceSTATUS +gckKERNEL_CreateIntegerDatabase( + IN gckKERNEL Kernel, + OUT gctPOINTER * Database + ) +{ + gceSTATUS status; + gckINTEGERDB database = gcvNULL; + + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); + + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Database != gcvNULL); + + /* Allocate a database. */ + gcmkONERROR(gckOS_Allocate( + Kernel->os, gcmSIZEOF(gcsINTEGERDB), (gctPOINTER *)&database)); + + gckOS_ZeroMemory(database, gcmSIZEOF(gcsINTEGERDB)); + + /* Allocate a pointer table. */ + gcmkONERROR(gckOS_Allocate( + Kernel->os, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH, (gctPOINTER *)&database->table)); + + gckOS_ZeroMemory(database->table, gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH); + + /* Allocate a database mutex. */ + gcmkONERROR(gckOS_CreateMutex(Kernel->os, &database->mutex)); + + /* Initialize. */ + database->currentID = 0; + database->unused = gcdID_TABLE_LENGTH; + database->os = Kernel->os; + database->tableLen = gcdID_TABLE_LENGTH; + + *Database = database; + + gcmkFOOTER_ARG("*Database=0x%08X", *Database); + return gcvSTATUS_OK; + +OnError: + /* Rollback. */ + if (database) + { + if (database->table) + { + gcmkOS_SAFE_FREE(Kernel->os, database->table); + } + + gcmkOS_SAFE_FREE(Kernel->os, database); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_DestroyIntegerDatabase( + IN gckKERNEL Kernel, + IN gctPOINTER Database + ) +{ + gckINTEGERDB database = Database; + + gcmkHEADER_ARG("Kernel=0x%08X Datbase=0x%08X", Kernel, Database); + + gcmkVERIFY_OBJECT(Kernel, gcvOBJ_KERNEL); + gcmkVERIFY_ARGUMENT(Database != gcvNULL); + + /* Destroy pointer table. */ + gcmkOS_SAFE_FREE(Kernel->os, database->table); + + /* Destroy database mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Kernel->os, database->mutex)); + + /* Destroy database. */ + gcmkOS_SAFE_FREE(Kernel->os, database); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} + +gceSTATUS +gckKERNEL_AllocateIntegerId( + IN gctPOINTER Database, + IN gctPOINTER Pointer, + OUT gctUINT32 * Id + ) +{ + gceSTATUS status; + gckINTEGERDB database = Database; + gctUINT32 i, unused, currentID, tableLen; + gctPOINTER * table; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Database=0x%08X Pointer=0x%08X", Database, Pointer); + + gcmkVERIFY_ARGUMENT(Id != gcvNULL); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; + + if (database->unused < 1) + { + /* Extend table. */ + gcmkONERROR( + gckOS_Allocate(os, + gcmSIZEOF(gctPOINTER) * (database->tableLen + gcdID_TABLE_LENGTH), + (gctPOINTER *)&table)); + + gckOS_ZeroMemory(table + database->tableLen, + gcmSIZEOF(gctPOINTER) * gcdID_TABLE_LENGTH); + + /* Copy data from old table. */ + gckOS_MemCopy(table, + database->table, + database->tableLen * gcmSIZEOF(gctPOINTER)); + + gcmkOS_SAFE_FREE(os, database->table); + + /* Update databse with new allocated table. */ + database->table = table; + database->currentID = database->tableLen; + database->tableLen += gcdID_TABLE_LENGTH; + database->unused += gcdID_TABLE_LENGTH; + } + + table = database->table; + currentID = database->currentID; + tableLen = database->tableLen; + unused = database->unused; + + /* Connect id with pointer. */ + table[currentID] = Pointer; + + *Id = currentID + 1; + + /* Update the currentID. */ + if (--unused > 0) + { + for (i = 0; i < tableLen; i++) + { + if (++currentID >= tableLen) + { + /* Wrap to the begin. */ + currentID = 0; + } + + if (table[currentID] == gcvNULL) + { + break; + } + } + } + + database->table = table; + database->currentID = currentID; + database->tableLen = tableLen; + database->unused = unused; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; + + gcmkFOOTER_ARG("*Id=%d", *Id); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_FreeIntegerId( + IN gctPOINTER Database, + IN gctUINT32 Id + ) +{ + gceSTATUS status; + gckINTEGERDB database = Database; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; + + if (!(Id > 0 && Id <= database->tableLen)) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + + Id -= 1; + + database->table[Id] = gcvNULL; + + if (database->unused++ == 0) + { + database->currentID = Id; + } + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + } + + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckKERNEL_QueryIntegerId( + IN gctPOINTER Database, + IN gctUINT32 Id, + OUT gctPOINTER * Pointer + ) +{ + gceSTATUS status; + gckINTEGERDB database = Database; + gctPOINTER pointer; + gckOS os = database->os; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Database=0x%08X Id=%d", Database, Id); + gcmkVERIFY_ARGUMENT(Pointer != gcvNULL); + + gcmkVERIFY_OK(gckOS_AcquireMutex(os, database->mutex, gcvINFINITE)); + acquired = gcvTRUE; + + if (!(Id > 0 && Id <= database->tableLen)) + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + + Id -= 1; + + pointer = database->table[Id]; + + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + acquired = gcvFALSE; + + if (pointer) + { + *Pointer = pointer; + } + else + { + gcmkONERROR(gcvSTATUS_NOT_FOUND); + } + + gcmkFOOTER_ARG("*Pointer=0x%08X", *Pointer); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(os, database->mutex)); + } + + gcmkFOOTER(); + return status; +} + + +gctUINT32 +gckKERNEL_AllocateNameFromPointer( + IN gckKERNEL Kernel, + IN gctPOINTER Pointer + ) +{ + gceSTATUS status; + gctUINT32 name; + gctPOINTER database = Kernel->db->pointerDatabase; + + gcmkHEADER_ARG("Kernel=0x%X Pointer=0x%X", Kernel, Pointer); + + gcmkONERROR( + gckKERNEL_AllocateIntegerId(database, Pointer, &name)); + + gcmkFOOTER_ARG("name=%d", name); + return name; + +OnError: + gcmkFOOTER(); + return 0; +} + +gctPOINTER +gckKERNEL_QueryPointerFromName( + IN gckKERNEL Kernel, + IN gctUINT32 Name + ) +{ + gceSTATUS status; + gctPOINTER pointer = gcvNULL; + gctPOINTER database = Kernel->db->pointerDatabase; + + gcmkHEADER_ARG("Kernel=0x%X Name=%d", Kernel, Name); + + /* Lookup in database to get pointer. */ + gcmkONERROR(gckKERNEL_QueryIntegerId(database, Name, &pointer)); + + gcmkFOOTER_ARG("pointer=0x%X", pointer); + return pointer; + +OnError: + gcmkFOOTER(); + return gcvNULL; +} + +gceSTATUS +gckKERNEL_DeleteName( + IN gckKERNEL Kernel, + IN gctUINT32 Name + ) +{ + gctPOINTER database = Kernel->db->pointerDatabase; + + gcmkHEADER_ARG("Kernel=0x%X Name=0x%X", Kernel, Name); + + /* Free name if exists. */ + gcmkVERIFY_OK(gckKERNEL_FreeIntegerId(database, Name)); + + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} /******************************************************************************* ***** Test Code **************************************************************** *******************************************************************************/ |