]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
ENGR00222253 Merge vivante 4.6.9_p7 kernel part code
authorLoren Huang <b02279@freescale.com>
Sun, 9 Sep 2012 16:00:13 +0000 (00:00 +0800)
committerLothar Waßmann <LW@KARO-electronics.de>
Fri, 24 May 2013 06:35:24 +0000 (08:35 +0200)
Merge vivante 4.6.9 p7 kernel part code.

Signed-off-by: Loren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
14 files changed:
drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.c
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel.h
drivers/mxc/gpu-viv/hal/kernel/gc_hal_kernel_event.c
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_base.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_engine.h
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h [new file with mode: 0644]
drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_types.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.c
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_debugfs.h
drivers/mxc/gpu-viv/hal/os/linux/kernel/gc_hal_kernel_os.c

index 07c549e8f784b82b806b1282b7142bcdf33e561f..e29a17528c01618e04cb218c47087e1bff6f35cc 100644 (file)
@@ -603,6 +603,8 @@ gckHARDWARE_Construct(
 
     gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex));
     gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore));
+    hardware->startIsr = gcvNULL;
+    hardware->stopIsr = gcvNULL;
 
 #if gcdPOWEROFF_TIMEOUT
     hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT;
@@ -4011,12 +4013,11 @@ gckHARDWARE_SetPowerManagementState(
         /* Stop the command parser. */
         gcmkONERROR(gckCOMMAND_Stop(command, gcvFALSE));
 
-#ifndef __QNXNTO__
         /* Stop the Isr. */
-        gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
-#else
-        /* QNX does not need to attach-dettach ISP that often */
-#endif
+        if (Hardware->stopIsr)
+        {
+            gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+        }
     }
 
     /* Get time until stopped. */
@@ -4102,13 +4103,11 @@ gckHARDWARE_SetPowerManagementState(
         /* Start the command processor. */
         gcmkONERROR(gckCOMMAND_Start(command));
 
-#ifndef __QNXNTO__
-        /* Start the Isr. */
-        gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
-#else
-        /* XSUN: QNX does not need to attach-dettach ISP that often
-         * with the current release */
-#endif
+        if (Hardware->startIsr)
+        {
+            /* Start the Isr. */
+            gcmkONERROR(Hardware->startIsr(Hardware->isrContext));
+        }
 
         /* Set NEW MMU. */
         if (Hardware->mmuVersion != 0 && configMmu)
@@ -4889,6 +4888,8 @@ gckHARDWARE_Reset(
     gceSTATUS status;
     gckCOMMAND command;
     gctBOOL acquired = gcvFALSE;
+    gctBOOL mutexAcquired = gcvFALSE;
+    gctUINT32 process, thread;
 
     gcmkHEADER_ARG("Hardware=0x%x", Hardware);
 
@@ -4904,6 +4905,25 @@ gckHARDWARE_Reset(
         gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
     }
 
+    status = gckOS_AcquireMutex(Hardware->os, Hardware->powerMutex, 0);
+    if (status == gcvSTATUS_TIMEOUT)
+    {
+        gcmkONERROR(gckOS_GetProcessID(&process));
+        gcmkONERROR(gckOS_GetThreadID(&thread));
+
+        if ((Hardware->powerProcess == process)
+        &&  (Hardware->powerThread  == thread))
+        {
+            /* No way to recovery from a error in power management. */
+            gcmkFOOTER_NO();
+            return gcvSTATUS_OK;
+        }
+    }
+    else
+    {
+        mutexAcquired = gcvTRUE;
+    }
+
     if (Hardware->chipPowerState == gcvPOWER_ON)
     {
         /* Acquire the power management semaphore. */
@@ -4920,10 +4940,11 @@ gckHARDWARE_Reset(
         gcmkONERROR(gckCOMMAND_Stop(command, gcvTRUE));
     }
 
-#ifndef __QNXNTO__
     /* Stop isr, we will start it again when power on GPU. */
-    gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
-#endif
+    if (Hardware->stopIsr)
+    {
+        gcmkONERROR(Hardware->stopIsr(Hardware->isrContext));
+    }
 
     /* Hardware reset. */
     status = gckOS_ResetGPU(Hardware->os, Hardware->core);
@@ -4936,7 +4957,9 @@ gckHARDWARE_Reset(
 
     /* Force an OFF to ON power switch. */
     Hardware->chipPowerState = gcvPOWER_OFF;
-    gcmkONERROR(gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON));
+
+    gcmkONERROR(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex));
+    mutexAcquired = gcvFALSE;
 
     /* Success. */
     gcmkFOOTER_NO();
@@ -4950,6 +4973,11 @@ OnError:
             gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore));
     }
 
+    if (mutexAcquired)
+    {
+        gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex);
+    }
+
     /* Return the error. */
     gcmkFOOTER();
     return status;
index b14bf79c038a92ed127d0725b4bdf18609423f53..6db55222b9b3a8ecf030978bc872fb5f2e4780ac 100644 (file)
@@ -89,6 +89,18 @@ gctCONST_STRING _DispatchText[] =
 };
 #endif
 
+#if gcdENABLE_RECOVERY
+void
+_ResetFinishFunction(
+    gctPOINTER Data
+    )
+{
+    gckKERNEL kernel = (gckKERNEL)Data;
+
+    gckOS_AtomSet(kernel->os, kernel->resetAtom, 0);
+}
+#endif
+
 /*******************************************************************************
 **
 **  gckKERNEL_Construct
@@ -246,6 +258,17 @@ gckKERNEL_Construct(
         /* Construct the gckMMU object. */
         gcmkONERROR(
             gckMMU_Construct(kernel, gcdMMU_SIZE, &kernel->mmu));
+
+#if gcdENABLE_RECOVERY
+        gcmkONERROR(
+            gckOS_AtomConstruct(Os, &kernel->resetAtom));
+
+        gcmkVERIFY_OK(
+            gckOS_CreateTimer(Os,
+                              (gctTIMERFUNCTION)_ResetFinishFunction,
+                              (gctPOINTER)kernel,
+                              &kernel->resetFlagClearTimer));
+#endif
     }
 
 #if VIVANTE_PROFILER
@@ -302,6 +325,19 @@ OnError:
             gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->atomClients));
         }
 
+#if gcdENABLE_RECOVERY
+        if (kernel->resetAtom != gcvNULL)
+        {
+            gcmkVERIFY_OK(gckOS_AtomDestroy(Os, kernel->resetAtom));
+        }
+
+        if (kernel->resetFlagClearTimer)
+        {
+            gcmkVERIFY_OK(gckOS_StopTimer(Os, kernel->resetFlagClearTimer));
+            gcmkVERIFY_OK(gckOS_DestoryTimer(Os, kernel->resetFlagClearTimer));
+        }
+#endif
+
         if (kernel->dbCreated && kernel->db != gcvNULL)
         {
             if (kernel->db->dbMutex != gcvNULL)
@@ -409,6 +445,16 @@ gckKERNEL_Destroy(
 
         /* Destroy the gckHARDWARE object. */
         gcmkVERIFY_OK(gckHARDWARE_Destroy(Kernel->hardware));
+
+#if gcdENABLE_RECOVERY
+        gcmkVERIFY_OK(gckOS_AtomDestroy(Kernel->os, Kernel->resetAtom));
+
+        if (Kernel->resetFlagClearTimer)
+        {
+            gcmkVERIFY_OK(gckOS_StopTimer(Kernel->os, Kernel->resetFlagClearTimer));
+            gcmkVERIFY_OK(gckOS_DestoryTimer(Kernel->os, Kernel->resetFlagClearTimer));
+        }
+#endif
     }
 
     /* Detsroy the client atom. */
@@ -1124,10 +1170,70 @@ gckKERNEL_Dispatch(
             break;
 
         case gcvUSER_SIGNAL_WAIT:
-            /* Wait on the signal. */
-            status = gckOS_WaitUserSignal(Kernel->os,
-                                          Interface->u.UserSignal.id,
-                                          Interface->u.UserSignal.wait);
+#if gcdGPU_TIMEOUT
+            if (Interface->u.UserSignal.wait == gcvINFINITE)
+            {
+                gckHARDWARE hardware;
+                gctUINT32 timer = 0;
+
+                for(;;)
+                {
+                    /* Wait on the signal. */
+                    status = gckOS_WaitUserSignal(Kernel->os,
+                                                  Interface->u.UserSignal.id,
+                                                  gcdGPU_ADVANCETIMER);
+
+                    if (status == gcvSTATUS_TIMEOUT)
+                    {
+                        gcmkONERROR(
+                            gckOS_SignalQueryHardware(Kernel->os,
+                                                      (gctSIGNAL)Interface->u.UserSignal.id,
+                                                      &hardware));
+
+                        if (hardware)
+                        {
+                            /* This signal is bound to a hardware,
+                            ** so the timeout is limited by gcdGPU_TIMEOUT.
+                            */
+                            timer += gcdGPU_ADVANCETIMER;
+                        }
+
+                        if (timer >= gcdGPU_TIMEOUT)
+                        {
+                            gcmkONERROR(
+                                gckOS_Broadcast(Kernel->os,
+                                                hardware,
+                                                gcvBROADCAST_GPU_STUCK));
+
+                            timer = 0;
+
+                            /* If a few process try to reset GPU, only one
+                            ** of them can do the real reset, other processes
+                            ** still need to wait for this signal is triggered,
+                            ** which menas reset is finished.
+                            */
+                            continue;
+                        }
+                    }
+                    else
+                    {
+                        /* Bail out on other error. */
+                        gcmkONERROR(status);
+
+                        /* Wait for signal successfully. */
+                        break;
+                    }
+                }
+            }
+            else
+#endif
+            {
+                /* Wait on the signal. */
+                status = gckOS_WaitUserSignal(Kernel->os,
+                                              Interface->u.UserSignal.id,
+                                              Interface->u.UserSignal.wait);
+            }
+
             break;
 
         case gcvUSER_SIGNAL_MAP:
@@ -2530,7 +2636,7 @@ gckKERNEL_Recovery(
     )
 {
 #if gcdENABLE_RECOVERY
-#define gcvEVENT_MASK 0x3FFFFFFF
+#define gcdEVENT_MASK 0x3FFFFFFF
     gceSTATUS status;
     gckEVENT eventObj;
     gckHARDWARE hardware;
@@ -2538,7 +2644,7 @@ gckKERNEL_Recovery(
     gctUINT32 processID;
     gcskSECURE_CACHE_PTR cache;
 #endif
-
+    gctUINT32 oldValue;
     gcmkHEADER_ARG("Kernel=0x%x", Kernel);
 
     /* Validate the arguemnts. */
@@ -2552,22 +2658,6 @@ gckKERNEL_Recovery(
     hardware = Kernel->hardware;
     gcmkVERIFY_OBJECT(hardware, gcvOBJ_HARDWARE);
 
-    /* Handle all outstanding events now. */
-#if gcdSMP
-    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcvEVENT_MASK));
-#else
-    eventObj->pending = gcvEVENT_MASK;
-#endif
-    gcmkONERROR(gckEVENT_Notify(eventObj, 1));
-
-    /* Again in case more events got submitted. */
-#if gcdSMP
-    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcvEVENT_MASK));
-#else
-    eventObj->pending = gcvEVENT_MASK;
-#endif
-    gcmkONERROR(gckEVENT_Notify(eventObj, 2));
-
 #if gcdSECURE_USER
     /* Flush the secure mapping cache. */
     gcmkONERROR(gckOS_GetProcessID(&processID));
@@ -2575,6 +2665,23 @@ gckKERNEL_Recovery(
     gcmkONERROR(gckKERNEL_FlushTranslationCache(Kernel, cache, gcvNULL, 0));
 #endif
 
+    gcmkONERROR(
+        gckOS_AtomicExchange(Kernel->os, Kernel->resetAtom, 1, &oldValue));
+
+    if (oldValue)
+    {
+        /* Some one else will recovery GPU. */
+        return gcvSTATUS_OK;
+    }
+
+    /* Start a timer to clear reset flag, before timer is expired,
+    ** other recovery request is ignored. */
+    gcmkVERIFY_OK(
+        gckOS_StartTimer(Kernel->os,
+                         Kernel->resetFlagClearTimer,
+                         gcdGPU_TIMEOUT - 500));
+
+
     /* Try issuing a soft reset for the GPU. */
     status = gckHARDWARE_Reset(hardware);
     if (status == gcvSTATUS_NOT_SUPPORTED)
@@ -2591,6 +2698,22 @@ gckKERNEL_Recovery(
         gcmkONERROR(status);
     }
 
+    /* Handle all outstanding events now. */
+#if gcdSMP
+    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
+#else
+    eventObj->pending = gcdEVENT_MASK;
+#endif
+    gcmkONERROR(gckEVENT_Notify(eventObj, 1));
+
+    /* Again in case more events got submitted. */
+#if gcdSMP
+    gcmkONERROR(gckOS_AtomSet(Kernel->os, eventObj->pending, gcdEVENT_MASK));
+#else
+    eventObj->pending = gcdEVENT_MASK;
+#endif
+    gcmkONERROR(gckEVENT_Notify(eventObj, 2));
+
     /* Success. */
     gcmkFOOTER_NO();
     return gcvSTATUS_OK;
index b627f3b1d5f9852615fcf3adcb35c96d60d4b99a..e4322aab249972d23dc60e26299b9170df114fa1 100644 (file)
@@ -338,6 +338,11 @@ struct _gckKERNEL
     gckDB                       db;
     gctBOOL                     dbCreated;
 
+#if gcdENABLE_RECOVERY
+    gctPOINTER                  resetFlagClearTimer;
+    gctPOINTER                  resetAtom;
+#endif
+
     /* Pointer to gckEVENT object. */
     gcsTIMER                    timers[8];
     gctUINT32                   timeOut;
index e1b21a0df70b46098b5c4cdead4e0f02d685349f..6c518488871d8d8f94448776b332a8f0ec494de9 100644 (file)
@@ -328,6 +328,12 @@ __RemoveRecordFromProcessDB(
                 Record->info.u.UnmapUserMemory.info));
             break;
 
+        case gcvHAL_SIGNAL:
+            gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
+                Record->info.u.Signal.signal,
+                Event->kernel->hardware));
+            break;
+
         default:
             break;
         }
@@ -723,11 +729,6 @@ gckEVENT_GetEvent(
                 __FUNCTION__, __LINE__
                 );
 
-            /* Broadcast GPU stuck. */
-            gcmkONERROR(gckOS_Broadcast(Event->os,
-                                        Event->kernel->hardware,
-                                        gcvBROADCAST_GPU_STUCK));
-
             /* Bail out. */
             gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING);
         }
@@ -1494,6 +1495,14 @@ OnError:
         Event->queues[id].head = gcvNULL;
     }
 
+    if (status == gcvSTATUS_GPU_NOT_RESPONDING)
+    {
+        /* Broadcast GPU stuck. */
+        status = gckOS_Broadcast(Event->os,
+                                 Event->kernel->hardware,
+                                 gcvBROADCAST_GPU_STUCK);
+    }
+
     /* Return the status. */
     gcmkFOOTER();
     return status;
index 25ec3eab95f25142718c2fc88e28be62a6612713..c976f7e9b7c1f22445901d1102becddb1a07328f 100644 (file)
@@ -30,6 +30,8 @@
 #include "gc_hal_base.h"
 #include "gc_hal_profiler.h"
 #include "gc_hal_driver.h"
+#include "gc_hal_statistics.h"
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -2361,7 +2363,19 @@ gckHARDWARE_QueryProfileRegisters(
     );
 #endif
 
+gceSTATUS
+gckOS_SignalQueryHardware(
+    IN gckOS Os,
+    IN gctSIGNAL Signal,
+    OUT gckHARDWARE * Hardware
+    );
 
+gceSTATUS
+gckOS_SignalSetHardware(
+    IN gckOS Os,
+    IN gctSIGNAL Signal,
+    gckHARDWARE Hardware
+    );
 
 #ifdef __cplusplus
 }
index 85b41312f7723c06ca7dd5c1920d95df55e9bdc1..7cfd2e119f00d14a76760414802f06b96287e3c9 100644 (file)
@@ -747,6 +747,25 @@ gcoOS_FreeContiguous(
     IN gctSIZE_T Bytes
     );
 
+/* Allocate video memory. */
+gceSTATUS
+gcoOS_AllocateVideoMemory(
+    IN gcoOS Os,
+    IN gctBOOL InUserSpace,
+    IN gctBOOL InCacheable,
+    IN OUT gctSIZE_T * Bytes,
+    OUT gctUINT32 * Physical,
+    OUT gctPOINTER * Logical,
+    OUT gctPOINTER * Handle
+    );
+
+/* Free video memory. */
+gceSTATUS
+gcoOS_FreeVideoMemory(
+    IN gcoOS Os,
+    IN gctPOINTER Handle
+    );
+
 #if gcdENABLE_BANK_ALIGNMENT
 gceSTATUS
 gcoSURF_GetBankOffsetBytes(
@@ -3659,6 +3678,42 @@ gckOS_DebugStatus2Name(
 
 #define MAX_LOOP_COUNT 0x7FFFFFFF
 
+/******************************************************************************\
+****************************** User Debug Option ******************************
+\******************************************************************************/
+
+/* User option. */
+typedef enum _gceDEBUG_MSG
+{
+    gcvDEBUG_MSG_NONE,
+    gcvDEBUG_MSG_ERROR,
+    gcvDEBUG_MSG_WARNING
+}
+gceDEBUG_MSG;
+
+typedef struct _gcsUSER_DEBUG_OPTION
+{
+    gceDEBUG_MSG        debugMsg;
+}
+gcsUSER_DEBUG_OPTION;
+
+gcsUSER_DEBUG_OPTION *
+gcGetUserDebugOption(
+    void
+    );
+
+#define gcmUSER_DEBUG_MSG(level, ...) \
+    do \
+    { \
+        if (level <= gcGetUserDebugOption()->debugMsg) \
+        { \
+            gcoOS_Print(__VA_ARGS__); \
+        } \
+    } while (gcvFALSE)
+
+#define gcmUSER_DEBUG_ERROR_MSG(...)   gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_ERROR, "Error: " __VA_ARGS__)
+#define gcmUSER_DEBUG_WARNING_MSG(...) gcmUSER_DEBUG_MSG(gcvDEBUG_MSG_WARNING, "Warring: " __VA_ARGS__)
+
 #ifdef __cplusplus
 }
 #endif
index d0a98a2b71c80a1b5b7e8d21ccb0f84c9dbb9992..4f8901db0ab5892eda083b1fcc0a04363b9ea1ad 100644 (file)
 /* Include VDK types. */
 #include "gc_hal_types.h"
 #include "gc_hal_base.h"
+#include "gc_hal_eglplatform_type.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/*******************************************************************************
-** Events. *********************************************************************
-*/
-
-typedef enum _halEventType
-{
-       /* Keyboard event. */
-    HAL_KEYBOARD,
-
-       /* Mouse move event. */
-    HAL_POINTER,
-
-       /* Mouse button event. */
-    HAL_BUTTON,
-
-       /* Application close event. */
-       HAL_CLOSE,
-
-       /* Application window has been updated. */
-       HAL_WINDOW_UPDATE
-}
-halEventType;
-
-/* Scancodes for keyboard. */
-typedef enum _halKeys
-{
-    HAL_UNKNOWN = -1,
-
-    HAL_BACKSPACE = 0x08,
-    HAL_TAB,
-    HAL_ENTER = 0x0D,
-    HAL_ESCAPE = 0x1B,
-
-    HAL_SPACE = 0x20,
-    HAL_SINGLEQUOTE = 0x27,
-    HAL_PAD_ASTERISK = 0x2A,
-    HAL_COMMA = 0x2C,
-    HAL_HYPHEN,
-    HAL_PERIOD,
-    HAL_SLASH,
-    HAL_0,
-    HAL_1,
-    HAL_2,
-    HAL_3,
-    HAL_4,
-    HAL_5,
-    HAL_6,
-    HAL_7,
-    HAL_8,
-    HAL_9,
-    HAL_SEMICOLON = 0x3B,
-    HAL_EQUAL = 0x3D,
-    HAL_A = 0x41,
-    HAL_B,
-    HAL_C,
-    HAL_D,
-    HAL_E,
-    HAL_F,
-    HAL_G,
-    HAL_H,
-    HAL_I,
-    HAL_J,
-    HAL_K,
-    HAL_L,
-    HAL_M,
-    HAL_N,
-    HAL_O,
-    HAL_P,
-    HAL_Q,
-    HAL_R,
-    HAL_S,
-    HAL_T,
-    HAL_U,
-    HAL_V,
-    HAL_W,
-    HAL_X,
-    HAL_Y,
-    HAL_Z,
-    HAL_LBRACKET,
-    HAL_BACKSLASH,
-    HAL_RBRACKET,
-    HAL_BACKQUOTE = 0x60,
-
-    HAL_F1 = 0x80,
-    HAL_F2,
-    HAL_F3,
-    HAL_F4,
-    HAL_F5,
-    HAL_F6,
-    HAL_F7,
-    HAL_F8,
-    HAL_F9,
-    HAL_F10,
-    HAL_F11,
-    HAL_F12,
-
-    HAL_LCTRL,
-    HAL_RCTRL,
-    HAL_LSHIFT,
-    HAL_RSHIFT,
-    HAL_LALT,
-    HAL_RALT,
-    HAL_CAPSLOCK,
-    HAL_NUMLOCK,
-    HAL_SCROLLLOCK,
-    HAL_PAD_0,
-    HAL_PAD_1,
-    HAL_PAD_2,
-    HAL_PAD_3,
-    HAL_PAD_4,
-    HAL_PAD_5,
-    HAL_PAD_6,
-    HAL_PAD_7,
-    HAL_PAD_8,
-    HAL_PAD_9,
-    HAL_PAD_HYPHEN,
-    HAL_PAD_PLUS,
-    HAL_PAD_SLASH,
-    HAL_PAD_PERIOD,
-    HAL_PAD_ENTER,
-    HAL_SYSRQ,
-    HAL_PRNTSCRN,
-    HAL_BREAK,
-    HAL_UP,
-    HAL_LEFT,
-    HAL_RIGHT,
-    HAL_DOWN,
-    HAL_HOME,
-    HAL_END,
-    HAL_PGUP,
-    HAL_PGDN,
-    HAL_INSERT,
-    HAL_DELETE,
-    HAL_LWINDOW,
-    HAL_RWINDOW,
-    HAL_MENU,
-    HAL_POWER,
-    HAL_SLEEP,
-    HAL_WAKE
-}
-halKeys;
-
-/* Structure that defined keyboard mapping. */
-typedef struct _halKeyMap
-{
-       /* Normal key. */
-    halKeys normal;
-
-       /* Extended key. */
-    halKeys extended;
-}
-halKeyMap;
-
-/* Event structure. */
-typedef struct _halEvent
-{
-       /* Event type. */
-    halEventType type;
-
-       /* Event data union. */
-    union _halEventData
-    {
-               /* Event data for keyboard. */
-        struct _halKeyboard
-        {
-                       /* Scancode. */
-            halKeys    scancode;
-
-                       /* ASCII characte of the key pressed. */
-            gctCHAR    key;
-
-                       /* Flag whether the key was pressed (1) or released (0). */
-            gctCHAR    pressed;
-        }
-        keyboard;
-
-               /* Event data for pointer. */
-        struct _halPointer
-        {
-                       /* Current pointer coordinate. */
-            gctINT             x;
-            gctINT             y;
-        }
-        pointer;
-
-               /* Event data for mouse buttons. */
-        struct _halButton
-        {
-                       /* Left button state. */
-            gctINT             left;
-
-                       /* Middle button state. */
-            gctINT             middle;
-
-                       /* Right button state. */
-            gctINT             right;
-
-                       /* Current pointer coordinate. */
-                       gctINT          x;
-                       gctINT          y;
-        }
-        button;
-    }
-    data;
-}
-halEvent;
 
 #if defined(_WIN32) || defined(__VC32__) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
 /* Win32 and Windows CE platforms. */
@@ -408,51 +203,7 @@ gcoOS_GetDisplayInfo(
     OUT gctINT * BitsPerPixel
     );
 
-/* VFK_DISPLAY_INFO structure defining information returned by
-   vdkGetDisplayInfoEx. */
-typedef struct _halDISPLAY_INFO
-{
-    /* The size of the display in pixels. */
-    gctINT                         width;
-    gctINT                         height;
-
-    /* The stride of the dispay. -1 is returned if the stride is not known
-    ** for the specified display.*/
-    gctINT                         stride;
-
-    /* The color depth of the display in bits per pixel. */
-    gctINT                         bitsPerPixel;
-
-    /* The logical pointer to the display memory buffer. NULL is returned
-    ** if the pointer is not known for the specified display. */
-    gctPOINTER                      logical;
 
-    /* The physical address of the display memory buffer. ~0 is returned
-    ** if the address is not known for the specified display. */
-    gctSIZE_T               physical;
-
-    gctBOOL                wrapFB;   /* true if compositor, false otherwise. */
-
-#ifndef __QNXNTO__
-    /* 355_FB_MULTI_BUFFER */
-    gctINT                      multiBuffer;
-    gctINT                      backBufferY;
-#endif
-
-    /* The color info of the display. */
-    gctUINT                alphaLength;
-    gctUINT                alphaOffset;
-    gctUINT                redLength;
-    gctUINT                redOffset;
-    gctUINT                greenLength;
-    gctUINT                greenOffset;
-    gctUINT                blueLength;
-    gctUINT                blueOffset;
-
-    /* Display flip support. */
-    gctINT                         flip;
-}
-halDISPLAY_INFO;
 
 gceSTATUS
 gcoOS_GetDisplayInfoEx(
@@ -779,7 +530,48 @@ gcoOS_DestroyClientBuffer(
     IN gctPOINTER ClientBuffer
     );
 
+gceSTATUS
+gcoOS_DestroyContext(
+    IN gctPOINTER Display,
+    IN gctPOINTER Context
+    );
+
+gceSTATUS
+gcoOS_CreateContext(
+    IN gctPOINTER LocalDisplay,
+    IN gctPOINTER Context
+    );
+
+gceSTATUS
+gcoOS_MakeCurrent(
+    IN gctPOINTER LocalDisplay,
+    IN HALNativeWindowType DrawDrawable,
+    IN HALNativeWindowType ReadDrawable,
+    IN gctPOINTER Context,
+    IN gcoSURF ResolveTarget
+    );
 
+gceSTATUS
+gcoOS_CreateDrawable(
+    IN gctPOINTER LocalDisplay,
+    IN HALNativeWindowType Drawable
+    );
+
+gceSTATUS
+gcoOS_DestroyDrawable(
+    IN gctPOINTER LocalDisplay,
+    IN HALNativeWindowType Drawable
+    );
+gceSTATUS
+gcoOS_SwapBuffers(
+    IN gctPOINTER LocalDisplay,
+    IN HALNativeWindowType Drawable,
+    IN gcoSURF RenderTarget,
+    IN gcoSURF ResolveTarget,
+    IN gctPOINTER ResolveBits,
+    OUT gctUINT *Width,
+    OUT gctUINT *Height
+    );
 #ifdef __cplusplus
 }
 #endif
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_eglplatform_type.h
new file mode 100644 (file)
index 0000000..727758f
--- /dev/null
@@ -0,0 +1,287 @@
+/****************************************************************************
+*
+*    Copyright (C) 2005 - 2012 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
+*    the Free Software Foundation; either version 2 of the license, or
+*    (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+#ifndef __gc_hal_eglplatform_type_h_
+#define __gc_hal_eglplatform_type_h_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*******************************************************************************
+** Events. *********************************************************************
+*/
+
+typedef enum _halEventType
+{
+       /* Keyboard event. */
+    HAL_KEYBOARD,
+
+       /* Mouse move event. */
+    HAL_POINTER,
+
+       /* Mouse button event. */
+    HAL_BUTTON,
+
+       /* Application close event. */
+       HAL_CLOSE,
+
+       /* Application window has been updated. */
+       HAL_WINDOW_UPDATE
+}
+halEventType;
+
+/* Scancodes for keyboard. */
+typedef enum _halKeys
+{
+    HAL_UNKNOWN = -1,
+
+    HAL_BACKSPACE = 0x08,
+    HAL_TAB,
+    HAL_ENTER = 0x0D,
+    HAL_ESCAPE = 0x1B,
+
+    HAL_SPACE = 0x20,
+    HAL_SINGLEQUOTE = 0x27,
+    HAL_PAD_ASTERISK = 0x2A,
+    HAL_COMMA = 0x2C,
+    HAL_HYPHEN,
+    HAL_PERIOD,
+    HAL_SLASH,
+    HAL_0,
+    HAL_1,
+    HAL_2,
+    HAL_3,
+    HAL_4,
+    HAL_5,
+    HAL_6,
+    HAL_7,
+    HAL_8,
+    HAL_9,
+    HAL_SEMICOLON = 0x3B,
+    HAL_EQUAL = 0x3D,
+    HAL_A = 0x41,
+    HAL_B,
+    HAL_C,
+    HAL_D,
+    HAL_E,
+    HAL_F,
+    HAL_G,
+    HAL_H,
+    HAL_I,
+    HAL_J,
+    HAL_K,
+    HAL_L,
+    HAL_M,
+    HAL_N,
+    HAL_O,
+    HAL_P,
+    HAL_Q,
+    HAL_R,
+    HAL_S,
+    HAL_T,
+    HAL_U,
+    HAL_V,
+    HAL_W,
+    HAL_X,
+    HAL_Y,
+    HAL_Z,
+    HAL_LBRACKET,
+    HAL_BACKSLASH,
+    HAL_RBRACKET,
+    HAL_BACKQUOTE = 0x60,
+
+    HAL_F1 = 0x80,
+    HAL_F2,
+    HAL_F3,
+    HAL_F4,
+    HAL_F5,
+    HAL_F6,
+    HAL_F7,
+    HAL_F8,
+    HAL_F9,
+    HAL_F10,
+    HAL_F11,
+    HAL_F12,
+
+    HAL_LCTRL,
+    HAL_RCTRL,
+    HAL_LSHIFT,
+    HAL_RSHIFT,
+    HAL_LALT,
+    HAL_RALT,
+    HAL_CAPSLOCK,
+    HAL_NUMLOCK,
+    HAL_SCROLLLOCK,
+    HAL_PAD_0,
+    HAL_PAD_1,
+    HAL_PAD_2,
+    HAL_PAD_3,
+    HAL_PAD_4,
+    HAL_PAD_5,
+    HAL_PAD_6,
+    HAL_PAD_7,
+    HAL_PAD_8,
+    HAL_PAD_9,
+    HAL_PAD_HYPHEN,
+    HAL_PAD_PLUS,
+    HAL_PAD_SLASH,
+    HAL_PAD_PERIOD,
+    HAL_PAD_ENTER,
+    HAL_SYSRQ,
+    HAL_PRNTSCRN,
+    HAL_BREAK,
+    HAL_UP,
+    HAL_LEFT,
+    HAL_RIGHT,
+    HAL_DOWN,
+    HAL_HOME,
+    HAL_END,
+    HAL_PGUP,
+    HAL_PGDN,
+    HAL_INSERT,
+    HAL_DELETE,
+    HAL_LWINDOW,
+    HAL_RWINDOW,
+    HAL_MENU,
+    HAL_POWER,
+    HAL_SLEEP,
+    HAL_WAKE
+}
+halKeys;
+
+/* Structure that defined keyboard mapping. */
+typedef struct _halKeyMap
+{
+       /* Normal key. */
+    halKeys normal;
+
+       /* Extended key. */
+    halKeys extended;
+}
+halKeyMap;
+
+/* Event structure. */
+typedef struct _halEvent
+{
+       /* Event type. */
+    halEventType type;
+
+       /* Event data union. */
+    union _halEventData
+    {
+               /* Event data for keyboard. */
+        struct _halKeyboard
+        {
+                       /* Scancode. */
+            halKeys    scancode;
+
+                       /* ASCII characte of the key pressed. */
+            char       key;
+
+                       /* Flag whether the key was pressed (1) or released (0). */
+            char       pressed;
+        }
+        keyboard;
+
+               /* Event data for pointer. */
+        struct _halPointer
+        {
+                       /* Current pointer coordinate. */
+            int                x;
+            int                y;
+        }
+        pointer;
+
+               /* Event data for mouse buttons. */
+        struct _halButton
+        {
+                       /* Left button state. */
+            int                left;
+
+                       /* Middle button state. */
+            int                middle;
+
+                       /* Right button state. */
+            int                right;
+
+                       /* Current pointer coordinate. */
+                       int             x;
+                       int             y;
+        }
+        button;
+    }
+    data;
+}
+halEvent;
+
+/* VFK_DISPLAY_INFO structure defining information returned by
+   vdkGetDisplayInfoEx. */
+typedef struct _halDISPLAY_INFO
+{
+    /* The size of the display in pixels. */
+    int                         width;
+    int                         height;
+
+    /* The stride of the dispay. -1 is returned if the stride is not known
+    ** for the specified display.*/
+    int                         stride;
+
+    /* The color depth of the display in bits per pixel. */
+    int                         bitsPerPixel;
+
+    /* The logical pointer to the display memory buffer. NULL is returned
+    ** if the pointer is not known for the specified display. */
+    void *                      logical;
+
+    /* The physical address of the display memory buffer. ~0 is returned
+    ** if the address is not known for the specified display. */
+    unsigned long               physical;
+
+    int                wrapFB;   /* true if compositor, false otherwise. */
+
+#ifndef __QNXNTO__
+    /* 355_FB_MULTI_BUFFER */
+    int                      multiBuffer;
+    int                      backBufferY;
+#endif
+
+    /* The color info of the display. */
+    unsigned int                alphaLength;
+    unsigned int                alphaOffset;
+    unsigned int                redLength;
+    unsigned int                redOffset;
+    unsigned int                greenLength;
+    unsigned int                greenOffset;
+    unsigned int                blueLength;
+    unsigned int                blueOffset;
+
+    /* Display flip support. */
+    int                         flip;
+}
+halDISPLAY_INFO;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __gc_hal_eglplatform_type_h_ */
index c7543072f349c2313b9f0d3d61c2ef9122193810..9aa2fe596f3239a6b9a5405c88e1db3d602dfcc4 100644 (file)
@@ -871,6 +871,19 @@ gco3D_SetAllEarlyDepthModes(
     IN gctBOOL Disable
     );
 
+/* Switch dynamic early mode */
+gceSTATUS
+gco3D_SwitchDynamicEarlyDepthMode(
+    IN gco3D Engine
+    );
+
+/* Set dynamic early mode */
+gceSTATUS
+gco3D_DisableDynamicEarlyDepthMode(
+    IN gco3D Engine,
+    IN gctBOOL Disable
+    );
+
 /* Enable or disable depth-only mode. */
 gceSTATUS
 gco3D_SetDepthOnly(
@@ -1780,6 +1793,16 @@ gcoVERTEXARRAY_Bind(
     IN OUT gctUINT * PrimitiveCount
     );
 
+gctUINT
+gcoVERTEXARRAY_GetMaxStream(
+    IN gcoVERTEXARRAY Vertex
+);
+
+gceSTATUS
+gcoVERTEXARRAY_SetMaxStream(
+    IN gcoVERTEXARRAY Vertex,
+    gctUINT maxStreams
+);
 /*******************************************************************************
 ***** Composition *************************************************************/
 
diff --git a/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h b/drivers/mxc/gpu-viv/hal/kernel/inc/gc_hal_statistics.h
new file mode 100644 (file)
index 0000000..1e85458
--- /dev/null
@@ -0,0 +1,116 @@
+/****************************************************************************
+*
+*    Copyright (C) 2005 - 2012 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
+*    the Free Software Foundation; either version 2 of the license, or
+*    (at your option) any later version.
+*
+*    This program is distributed in the hope that it will be useful,
+*    but 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*
+*****************************************************************************/
+
+
+
+#ifndef __gc_hal_statistics_h_
+#define __gc_hal_statistics_h_
+
+
+#define VIV_STAT_ENABLE_STATISTICS              0
+
+/*  Toal number of frames for which the frame time is accounted. We have storage
+    to keep frame times for last this many frames.
+*/
+#define VIV_STAT_FRAME_BUFFER_SIZE              30
+
+/*
+    Total number of frames sampled for a mode. This means
+
+    # of frames for HZ Current  : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+    # of frames for HZ Switched : VIV_STAT_EARLY_Z_SAMPLE_FRAMES
+  +
+  --------------------------------------------------------
+                                : (2 * VIV_STAT_EARLY_Z_SAMPLE_FRAMES) frames needed
+
+    IMPORTANT: This total must be smaller than VIV_STAT_FRAME_BUFFER_SIZE
+*/
+#define VIV_STAT_EARLY_Z_SAMPLE_FRAMES          7
+#define VIV_STAT_EARLY_Z_LATENCY_FRAMES         2
+
+/* Multiplication factor for previous Hz off mode. Make it more than 1.0 to advertise HZ on.*/
+#define VIV_STAT_EARLY_Z_FACTOR                 (1.05f)
+
+/* Defines the statistical data keys monitored by the statistics module */
+typedef enum _gceSTATISTICS
+{
+    gcvFRAME_FPS        =   1,
+}
+gceSTATISTICS;
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS_EARLYZ
+{
+    gctUINT                     switchBackCount;
+    gctUINT                     nextCheckPoint;
+    gctBOOL                     disabled;
+}
+gcsSTATISTICS_EARLYZ;
+
+
+/* Defines the statistical data keys monitored by the statistics module */
+typedef enum _gceSTATISTICS_Call
+{
+       gcvSTAT_ES11_GLDRAWELEMENTS      =   1,
+}
+gceSTATISTICS_Call;
+
+
+/* HAL statistics information. */
+typedef struct _gcsSTATISTICS
+{
+    gctUINT64                   frameTime[VIV_STAT_FRAME_BUFFER_SIZE];
+    gctUINT64                   previousFrameTime;
+    gctUINT                     frame;
+    gcsSTATISTICS_EARLYZ        earlyZ;
+       gctUINT                                         ES11_drawElementsCount;
+       gctBOOL                                         applyRTestVAFix;
+}
+gcsSTATISTICS;
+
+
+/* Add a frame based data into current statistics. */
+void
+gcfSTATISTICS_AddData(
+    IN gceSTATISTICS Key,
+    IN gctUINT Value
+    );
+
+/* Marks the frame end and triggers statistical calculations and decisions.*/
+void
+gcfSTATISTICS_MarkFrameEnd (
+    void
+    );
+
+/* Sets whether the dynmaic HZ is disabled or not .*/
+void
+gcfSTATISTICS_DisableDynamicEarlyZ (
+    IN gctBOOL Disabled
+    );
+
+/* Checks whether or not glDrawArray function call will be discarded */
+gctBOOL
+gcfSTATISTICS_DiscardCall(
+       gceSTATISTICS_Call Function
+       );
+
+
+#endif /*__gc_hal_statistics_h_ */
+
index e9ad6f611820aefc5b91edd96085af01226f60ac..4e063776cd44032f7b55c4abe31d81a6f3344552 100644 (file)
@@ -285,6 +285,8 @@ typedef enum _gceSTATUS
        gcvSTATUS_EXECUTED                              =       18,
     gcvSTATUS_TERMINATE             =   19,
 
+    gcvSTATUS_CONVERT_TO_SINGLE_STREAM    =   20,
+
     gcvSTATUS_INVALID_ARGUMENT      =   -1,
     gcvSTATUS_INVALID_OBJECT        =   -2,
     gcvSTATUS_OUT_OF_MEMORY         =   -3,
index cff2448d7f92c40e53f21e5c2bc5a21d3bf3224c..5a21a94ed7fd1f87844acf69164690df9e719954 100644 (file)
 #include <linux/completion.h>
 #include "gc_hal_kernel_linux.h"
 
-/* 
+/*
    Prequsite:
 
    1) Debugfs feature must be enabled in the kernel.
        1.a) You can enable this, in the compilation of the uImage, all you have to do is, In the "make menuconfig" part,
        you have to enable the debugfs in the kernel hacking part of the menu.
-  
+
    HOW TO USE:
-   1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240 
+   1) insert the driver with the following option logFileSize, Ex: insmod galcore.ko ...... logFileSize=10240
    This gives a circular buffer of 10 MB
-   
+
    2)Usually after inserting the driver, the debug file system is mounted under /sys/kernel/debug/
 
         2.a)If the debugfs is not mounted, you must do "mount -t debugfs none /sys/kernel/debug"
-       
+
    3) To read what is being printed in the debugfs file system:
         Ex : cat /sys/kernel/debug/gpu/galcore_trace
 
@@ -81,7 +81,7 @@
     4) insmod it with the logFileSize option
     5) Run an application
     6) You can get the dump by cat /sys/kernel/debug/gpu/galcore_trace
-   
+
  */
 
 /**/
@@ -151,7 +151,7 @@ static gcsDebugFileSystem gc_dbgfs ;
 /*******************************************************************************
  **
  **            READ & WRITE FUNCTIONS (START)
- **              
+ **
  *******************************************************************************/
 
 /*******************************************************************************
@@ -159,9 +159,9 @@ static gcsDebugFileSystem gc_dbgfs ;
  **  _ReadFromNode
  **
  **    1) reading bytes out of a circular buffer with wraparound.
- **    2)returns caddr_t, pointer to data read, which the caller must free.  
+ **    2)returns caddr_t, pointer to data read, which the caller must free.
  **    3) length is (a pointer to) the number of bytes to be read, which will be set by this function to
- **        be the number of bytes actually returned 
+ **        be the number of bytes actually returned
  **
  *******************************************************************************/
 static caddr_t
@@ -222,7 +222,7 @@ _ReadFromNode (
  **
  **  _WriteToNode
  **
- ** 1) writes to a circular buffer with wraparound. 
+ ** 1) writes to a circular buffer with wraparound.
  ** 2)in case of an overflow, it overwrites the oldest unread data.
  **
  *********************************************************************************/
@@ -275,7 +275,7 @@ _WriteToNode (
 /*******************************************************************************
  **
  **            PRINTING UTILITY (START)
- **            
+ **
  *******************************************************************************/
 
 /*******************************************************************************
@@ -369,7 +369,7 @@ _DebugFSPrint (
 /*******************************************************************************
  **
  **                     LINUX SYSTEM FUNCTIONS (START)
- **              
+ **
  *******************************************************************************/
 
 /*******************************************************************************
@@ -538,7 +538,7 @@ static const struct file_operations debugfs_operations = {
 /*******************************************************************************
  **
  **                             INTERFACE FUNCTIONS (START)
- **              
+ **
  *******************************************************************************/
 
 /*******************************************************************************
index b0031a83ef4122d9febb919e28596e1335b80e5b..e0b61424482f1f92fefdbba043c3a57aa05bf59f 100644 (file)
@@ -35,7 +35,7 @@
 /*******************************************************************************
  **
  **                             System Related
- **              
+ **
  *******************************************************************************/
 
 gctINT    gckDebugFileSystemIsEnabled(void);
@@ -48,7 +48,7 @@ gctINT   gckDebugFileSystemTerminate(void);
 /*******************************************************************************
  **
  **                             Node Related
- **              
+ **
  *******************************************************************************/
 
 gctINT gckDebugFileSystemCreateNode(
index 21e6a22317e562191d665e265792cce7e455dab3..4d1a71dfa91aa3beea89a175953daf77181341ea 100644 (file)
@@ -197,6 +197,8 @@ typedef struct _gcsSIGNAL
     /* The owner of the signal. */
     gctHANDLE process;
 
+    gckHARDWARE hardware;
+
     /* ID. */
     gctUINT32 id;
 }
@@ -6517,7 +6519,9 @@ gckOS_Broadcast(
 
     case gcvBROADCAST_GPU_STUCK:
         gcmkTRACE_N(gcvLEVEL_ERROR, 0, "gcvBROADCAST_GPU_STUCK\n");
+#if !gcdENABLE_RECOVERY
         gcmkONERROR(_DumpGPUState(Os, Hardware->core));
+#endif
         gcmkONERROR(gckKERNEL_Recovery(Hardware->kernel));
         break;
 
@@ -7195,6 +7199,7 @@ gckOS_CreateSignal(
     /* Save the process ID. */
     signal->process = (gctHANDLE) _GetProcessID();
     signal->manualReset = ManualReset;
+    signal->hardware = gcvNULL;
     init_completion(&signal->obj);
     atomic_set(&signal->ref, 1);
 
@@ -7215,6 +7220,61 @@ OnError:
     return status;
 }
 
+gceSTATUS
+gckOS_SignalQueryHardware(
+    IN gckOS Os,
+    IN gctSIGNAL Signal,
+    OUT gckHARDWARE * Hardware
+    )
+{
+    gceSTATUS status;
+    gcsSIGNAL_PTR signal;
+
+    gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+    gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+    gcmkVERIFY_ARGUMENT(Hardware != gcvNULL);
+
+    gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+
+    *Hardware = signal->hardware;
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
+gceSTATUS
+gckOS_SignalSetHardware(
+    IN gckOS Os,
+    IN gctSIGNAL Signal,
+    IN gckHARDWARE Hardware
+    )
+{
+    gceSTATUS status;
+    gcsSIGNAL_PTR signal;
+
+    gcmkHEADER_ARG("Os=0x%X Signal=0x%X Hardware=0x%X", Os, Signal, Hardware);
+
+    /* Verify the arguments. */
+    gcmkVERIFY_OBJECT(Os, gcvOBJ_OS);
+    gcmkVERIFY_ARGUMENT(Signal != gcvNULL);
+
+    gcmkONERROR(_QueryIntegerId(&Os->signalDB, (gctUINT32)Signal, (gctPOINTER)&signal));
+
+    signal->hardware = Hardware;
+
+    gcmkFOOTER_NO();
+    return gcvSTATUS_OK;
+OnError:
+    gcmkFOOTER();
+    return status;
+}
+
 /*******************************************************************************
 **
 **  gckOS_DestroySignal
@@ -7330,6 +7390,9 @@ gckOS_Signal(
 
     if (State)
     {
+        /* unbind the signal from hardware. */
+        signal->hardware = gcvNULL;
+
         /* Set the event to a signaled state. */
         complete(&signal->obj);
     }