Commit 3a34fe70 authored by Loren Huang's avatar Loren Huang

ENGR00233452 Integrate 4.6.9p9 GPU kernel part driver

Signed-off-by: default avatarLoren Huang <b02279@freescale.com>
Acked-by: Lily Zhang
parent fbd07a2c
......@@ -623,6 +623,7 @@ _InitializeContextBuffer(
index += _State(Context, index, 0x10180 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10200 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10280 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x02C00 >> 2, 0x00000000, 256, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10300 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10380 >> 2, 0x00321000, 32, gcvFALSE, gcvFALSE);
index += _State(Context, index, 0x10400 >> 2, 0x00000000, 32, gcvFALSE, gcvFALSE);
......@@ -905,6 +906,16 @@ _DestroyContext(
/* Free state delta map. */
if (buffer->logical != gcvNULL)
{
#if gcdVIRTUAL_COMMAND_BUFFER
gcmkONERROR(gckEVENT_DestroyVirtualCommandBuffer(
Context->hardware->kernel->eventObj,
Context->totalSize,
buffer->physical,
buffer->logical,
gcvKERNEL_PIXEL
));
#else
gcmkONERROR(gckEVENT_FreeContiguousMemory(
Context->hardware->kernel->eventObj,
Context->totalSize,
......@@ -912,6 +923,7 @@ _DestroyContext(
buffer->logical,
gcvKERNEL_PIXEL
));
#endif
buffer->logical = gcvNULL;
}
......@@ -1149,6 +1161,16 @@ gckCONTEXT_Construct(
));
/* Create a new physical context buffer. */
#if gcdVIRTUAL_COMMAND_BUFFER
gcmkONERROR(gckKERNEL_AllocateVirtualCommandBuffer(
context->hardware->kernel,
gcvFALSE,
&context->totalSize,
&buffer->physical,
&pointer
));
#else
gcmkONERROR(gckOS_AllocateContiguous(
Os,
gcvFALSE,
......@@ -1156,6 +1178,7 @@ gckCONTEXT_Construct(
&buffer->physical,
&pointer
));
#endif
buffer->logical = pointer;
......
......@@ -221,17 +221,8 @@ _IdentifyHardware(
Identity->superTileMode = 0;
}
/* If new HZ is available, disable other early z modes. */
if (((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 26:26) & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 26:26) - (0 ? 26:26) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 26:26) - (0 ? 26:26) + 1)))))))
|| ((((gctUINT32) (Identity->chipMinorFeatures3)) >> (0 ? 8:8) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))))
{
/* Disable EZ. */
Identity->chipFeatures
= ((((gctUINT32) (Identity->chipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)));
}
/* Disable HZ when EZ is present for older chips. */
else if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
if (!((((gctUINT32) (Identity->chipFeatures)) >> (0 ? 16:16) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1))))))))
{
/* Disable HIERARCHICAL_Z. */
Identity->chipMinorFeatures
......@@ -408,7 +399,7 @@ _IdentifyHardware(
(instructionCount == 0) ? " (default)" : "");
/* Get the number of constants. */
Identity->numConstants = numConstants;
Identity->numConstants = (numConstants == 0) ? 168 : numConstants;
gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE,
"Specs: numConstants=%u%s",
......@@ -2344,25 +2335,32 @@ gckHARDWARE_ConvertLogical(
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Address != gcvNULL);
/* Convert logical address into a physical address. */
gcmkONERROR(
gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
#if gcdVIRTUAL_COMMAND_BUFFER
status = gckKERNEL_GetGPUAddress(Hardware->kernel, Logical, Address);
/* For old MMU, get GPU address according to baseAddress. */
if (Hardware->mmuVersion == 0)
if (status == gcvSTATUS_INVALID_ADDRESS)
#endif
{
gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
/* Convert logical address into a physical address. */
gcmkONERROR(
gckOS_GetPhysicalAddress(Hardware->os, Logical, &address));
/* Subtract base address to get a GPU address. */
gcmkASSERT(address >= baseAddress);
address -= baseAddress;
}
/* For old MMU, get GPU address according to baseAddress. */
if (Hardware->mmuVersion == 0)
{
gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress));
/* Return hardware specific address. */
*Address = (Hardware->mmuVersion == 0)
? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
: address;
/* Subtract base address to get a GPU address. */
gcmkASSERT(address >= baseAddress);
address -= baseAddress;
}
/* Return hardware specific address. */
*Address = (Hardware->mmuVersion == 0)
? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31)))
| ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))) | (((gctUINT32) ((gctUINT32) (address) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0)))
: address;
}
/* Success. */
gcmkFOOTER_ARG("*Address=0x%08x", *Address);
......@@ -2621,7 +2619,7 @@ gckHARDWARE_QuerySystemMemory(
return gcvSTATUS_OK;
}
#if !defined(VIVANTE_NO_3D)
#ifndef VIVANTE_NO_3D
/*******************************************************************************
**
** gckHARDWARE_QueryShaderCaps
......@@ -3393,8 +3391,13 @@ gckHARDWARE_SetFastClear(
/* Set fast clear bypass. */
debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20))) | (((gctUINT32) ((gctUINT32) (Enable == 0) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))) << (0 ? 20:20)));
/* Set compression bypass. */
debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
if (
((((gctUINT32) (Hardware->identity.chipMinorFeatures2)) >> (0 ? 27:27) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) ||
(Hardware->identity.chipModel >= gcv4000))
{
/* Set compression bypass. */
debug = ((((gctUINT32) (debug)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21))) | (((gctUINT32) ((gctUINT32) (Compression == 0) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) << (0 ? 21:21)));
}
/* Write back AQMemoryDebug register. */
gcmkONERROR(
......@@ -5250,6 +5253,7 @@ gckHARDWARE_DumpMMUException(
IN gckHARDWARE Hardware
)
{
#if !gcdPOWER_SUSNPEND_WHEN_IDLE && !gcdPOWEROFF_TIMEOUT
gctUINT32 mmu, mmuStatus, address, i;
#if gcdDEBUG
gctUINT32 mtlb, stlb, offset;
......@@ -5339,6 +5343,13 @@ gckHARDWARE_DumpMMUException(
}
gcmkFOOTER_NO();
#else
/* If clock could be off automatically, we can't read mmu debug
** register here; build driver with gcdPOWER_SUSPEND_WHEN_IDLE = 0
** and gcdPOWEROFF_TIMEOUT = 0 to make it safe to read mmu register. */
gcmkPRINT("[galcore] %s(%d): MMU Exception!", __FUNCTION__, __LINE__);
#endif
return gcvSTATUS_OK;
}
......
......@@ -134,6 +134,7 @@ gcskSECURE_CACHE;
typedef enum _gceDATABASE_TYPE
{
gcvDB_VIDEO_MEMORY = 1, /* Video memory created. */
gcvDB_COMMAND_BUFFER, /* Command Buffer. */
gcvDB_NON_PAGED, /* Non paged memory. */
gcvDB_CONTIGUOUS, /* Contiguous memory. */
gcvDB_SIGNAL, /* Signal. */
......@@ -292,6 +293,24 @@ struct _gckDB
gctUINT64 lastSlowdownIdle;
};
#if gcdVIRTUAL_COMMAND_BUFFER
typedef struct _gckVIRTUAL_COMMAND_BUFFER * gckVIRTUAL_COMMAND_BUFFER_PTR;
typedef struct _gckVIRTUAL_COMMAND_BUFFER
{
gctPHYS_ADDR physical;
gctPOINTER userLogical;
gctPOINTER kernelLogical;
gctSIZE_T pageCount;
gctPOINTER pageTable;
gctUINT32 gpuAddress;
gctUINT pid;
gckVIRTUAL_COMMAND_BUFFER_PTR next;
gckVIRTUAL_COMMAND_BUFFER_PTR prev;
gckKERNEL kernel;
}
gckVIRTUAL_COMMAND_BUFFER;
#endif
/* gckKERNEL object. */
struct _gckKERNEL
{
......@@ -350,6 +369,12 @@ struct _gckKERNEL
#if gcdENABLE_VG
gckVGKERNEL vg;
#endif
#if gcdVIRTUAL_COMMAND_BUFFER
gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferHead;
gckVIRTUAL_COMMAND_BUFFER_PTR virtualBufferTail;
gctPOINTER virtualBufferLock;
#endif
};
/* gckCOMMAND object. */
......@@ -452,6 +477,8 @@ typedef struct _gcsEVENT
/* Kernel. */
gckKERNEL kernel;
#endif
gctBOOL fromKernel;
}
gcsEVENT;
......@@ -735,6 +762,44 @@ struct _gckMMU
#endif
};
#if gcdVIRTUAL_COMMAND_BUFFER
gceSTATUS
gckOS_CreateKernelVirtualMapping(
IN gctPHYS_ADDR Physical,
OUT gctSIZE_T * PageCount,
OUT gctPOINTER * Logical
);
gceSTATUS
gckOS_DestroyKernelVirtualMapping(
IN gctPOINTER Logical
);
gceSTATUS
gckKERNEL_AllocateVirtualCommandBuffer(
IN gckKERNEL Kernel,
IN gctBOOL InUserSpace,
IN OUT gctSIZE_T * Bytes,
OUT gctPHYS_ADDR * Physical,
OUT gctPOINTER * Logical
);
gceSTATUS
gckKERNEL_DestroyVirtualCommandBuffer(
IN gckKERNEL Kernel,
IN gctSIZE_T Bytes,
IN gctPHYS_ADDR Physical,
IN gctPOINTER Logical
);
gceSTATUS
gckKERNEL_GetGPUAddress(
IN gckKERNEL Kernel,
IN gctPOINTER Logical,
OUT gctUINT32 * Address
);
#endif
gceSTATUS
gckKERNEL_AttachProcess(
IN gckKERNEL Kernel,
......
......@@ -1971,7 +1971,7 @@ gckCOMMAND_Commit(
/* Append event record to event queue. */
gcmkONERROR(gckEVENT_AddList(
Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE
Command->kernel->eventObj, &eventRecord->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE
));
/* Next record in the queue. */
......
......@@ -915,7 +915,7 @@ _HardwareToKernel(
}
offset = Address - nodePhysical;
*KernelPointer = (gctPOINTER)((gctUINT32)Node->VidMem.kernelVirtual + offset);
*KernelPointer = (gctPOINTER)((gctUINT8_PTR)Node->VidMem.kernelVirtual + offset);
#else
/* Determine the header offset within the pool it is allocated in. */
offset = Address - memory->baseAddress;
......
......@@ -1161,6 +1161,21 @@ gckKERNEL_DestroyProcessDB(
record->data, record->bytes, status);
break;
#if gcdVIRTUAL_COMMAND_BUFFER
case gcvDB_COMMAND_BUFFER:
/* Free the command buffer. */
status = gckEVENT_DestroyVirtualCommandBuffer(record->kernel->eventObj,
record->bytes,
record->physical,
record->data,
gcvKERNEL_PIXEL);
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: COMMAND_BUFFER 0x%x, bytes=%lu (status=%d)",
record->data, record->bytes, status);
break;
#endif
case gcvDB_CONTIGUOUS:
/* Unmap user logical memory first. */
status = gckOS_UnmapUserLogical(Kernel->os,
......@@ -1191,7 +1206,7 @@ gckKERNEL_DestroyProcessDB(
gcmkTRACE_ZONE(gcvLEVEL_WARNING, gcvZONE_DATABASE,
"DB: SIGNAL %d (status=%d)",
(gctINT) record->data, status);
(gctINT)(gctUINTPTR_T)record->data, status);
break;
case gcvDB_VIDEO_MEMORY_LOCKED:
......
......@@ -286,6 +286,21 @@ __RemoveRecordFromProcessDB(
while (Record != gcvNULL)
{
if (Record->info.command == gcvHAL_SIGNAL)
{
/* TODO: Find a better place to bind signal to hardware.*/
gcmkVERIFY_OK(gckOS_SignalSetHardware(Event->os,
Record->info.u.Signal.signal,
Event->kernel->hardware));
}
if (Record->fromKernel)
{
/* No need to check db if event is from kernel. */
Record = Record->next;
continue;
}
switch (Record->info.command)
{
case gcvHAL_FREE_NON_PAGED_MEMORY:
......@@ -328,10 +343,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));
case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
gcmkVERIFY_OK(gckKERNEL_RemoveProcessDB(
Event->kernel,
Record->processID,
gcvDB_COMMAND_BUFFER,
Record->info.u.FreeVirtualCommandBuffer.logical));
break;
default:
......@@ -883,7 +900,8 @@ gckEVENT_AddList(
IN gckEVENT Event,
IN gcsHAL_INTERFACE_PTR Interface,
IN gceKERNEL_WHERE FromWhere,
IN gctBOOL AllocateAllowed
IN gctBOOL AllocateAllowed,
IN gctBOOL FromKernel
)
{
gceSTATUS status;
......@@ -913,6 +931,7 @@ gckEVENT_AddList(
|| (Interface->command == gcvHAL_UNMAP_USER_MEMORY)
|| (Interface->command == gcvHAL_TIMESTAMP)
|| (Interface->command == gcvHAL_COMMIT_DONE)
|| (Interface->command == gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER)
);
/* Validate the source. */
......@@ -928,6 +947,9 @@ gckEVENT_AddList(
/* Termninate the record. */
record->next = gcvNULL;
/* Record the committer. */
record->fromKernel = FromKernel;
/* Copy the event interface into the record. */
gcmkONERROR(gckOS_MemCopy(&record->info, Interface, gcmSIZEOF(record->info)));
......@@ -1081,7 +1103,7 @@ gckEVENT_Unlock(
iface.u.UnlockVideoMemory.asynchroneous = 0;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1136,7 +1158,7 @@ gckEVENT_FreeVideoMemory(
iface.u.FreeVideoMemory.node = VideoMemory;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1200,7 +1222,48 @@ gckEVENT_FreeNonPagedMemory(
iface.u.FreeNonPagedMemory.logical = Logical;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
return gcvSTATUS_OK;
OnError:
/* Return the status. */
gcmkFOOTER();
return status;
}
gceSTATUS
gckEVENT_DestroyVirtualCommandBuffer(
IN gckEVENT Event,
IN gctSIZE_T Bytes,
IN gctPHYS_ADDR Physical,
IN gctPOINTER Logical,
IN gceKERNEL_WHERE FromWhere
)
{
gceSTATUS status;
gcsHAL_INTERFACE iface;
gcmkHEADER_ARG("Event=0x%x Bytes=%lu Physical=0x%x Logical=0x%x "
"FromWhere=%d",
Event, Bytes, Physical, Logical, FromWhere);
/* Verify the arguments. */
gcmkVERIFY_OBJECT(Event, gcvOBJ_EVENT);
gcmkVERIFY_ARGUMENT(Physical != gcvNULL);
gcmkVERIFY_ARGUMENT(Logical != gcvNULL);
gcmkVERIFY_ARGUMENT(Bytes > 0);
/* Create an event. */
iface.command = gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER;
iface.u.FreeVirtualCommandBuffer.bytes = Bytes;
iface.u.FreeVirtualCommandBuffer.physical = Physical;
iface.u.FreeVirtualCommandBuffer.logical = Logical;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1264,7 +1327,7 @@ gckEVENT_FreeContiguousMemory(
iface.u.FreeContiguousMemory.logical = Logical;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1325,7 +1388,7 @@ gckEVENT_Signal(
iface.u.Signal.process = gcvNULL;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1372,7 +1435,7 @@ gckEVENT_CommitDone(
iface.command = gcvHAL_COMMIT_DONE;
/* Append it to the queue. */
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE));
gcmkONERROR(gckEVENT_AddList(Event, &iface, FromWhere, gcvFALSE, gcvTRUE));
/* Success. */
gcmkFOOTER_NO();
......@@ -1624,7 +1687,7 @@ gckEVENT_Commit(
/* Append event record to event queue. */
gcmkONERROR(
gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE));
gckEVENT_AddList(Event, &record->iface, gcvKERNEL_PIXEL, gcvTRUE, gcvFALSE));
/* Next record in the queue. */
next = record->next;
......@@ -2381,6 +2444,17 @@ gckEVENT_Notify(
}
break;
#if gcdVIRTUAL_COMMAND_BUFFER
case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
gcmkVERIFY_OK(
gckKERNEL_DestroyVirtualCommandBuffer(Event->kernel,
record->info.u.FreeVirtualCommandBuffer.bytes,
record->info.u.FreeVirtualCommandBuffer.physical,
record->info.u.FreeVirtualCommandBuffer.logical
));
break;
#endif
case gcvHAL_COMMIT_DONE:
break;
......@@ -2714,6 +2788,11 @@ _PrintRecord(
gcmkPRINT(" gcvHAL_COMMIT_DONE");
break;
case gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER:
gcmkPRINT(" gcvHAL_FREE_VIRTUAL_COMMAND_BUFFER logical=0x%08x",
record->info.u.FreeVirtualCommandBuffer.logical);
break;
default:
gcmkPRINT(" Illegal Event %d", record->info.command);
break;
......
......@@ -78,6 +78,25 @@ gcsSharedPageTable;
static gcsSharedPageTable_PTR sharedPageTable = gcvNULL;
#endif
#if gcdMIRROR_PAGETABLE
typedef struct _gcsMirrorPageTable * gcsMirrorPageTable_PTR;
typedef struct _gcsMirrorPageTable
{
/* gckMMU objects. */
gckMMU mmus[gcdMAX_GPU_COUNT];
/* Hardwares which use this shared pagetable. */
gckHARDWARE hardwares[gcdMAX_GPU_COUNT];
/* Number of cores use this shared pagetable. */
gctUINT32 reference;
}
gcsMirrorPageTable;
static gcsMirrorPageTable_PTR mirrorPageTable = gcvNULL;
static gctPOINTER mirrorPageTableMutex = gcvNULL;
#endif
static gceSTATUS
_FillPageTable(
IN gctUINT32_PTR PageTable,
......@@ -871,6 +890,47 @@ OnError:
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, sharedPageTable));
}
gcmkFOOTER();
return status;
#elif gcdMIRROR_PAGETABLE
gceSTATUS status;
gctPOINTER pointer;
gcmkHEADER_ARG("Kernel=0x%08x", Kernel);
if (mirrorPageTable == gcvNULL)
{
gcmkONERROR(
gckOS_Allocate(Kernel->os,
sizeof(struct _gcsMirrorPageTable),
&pointer));
mirrorPageTable = pointer;
gcmkONERROR(
gckOS_ZeroMemory(mirrorPageTable,
sizeof(struct _gcsMirrorPageTable)));
gcmkONERROR(
gckOS_CreateMutex(Kernel->os, &mirrorPageTableMutex));
}
gcmkONERROR(_Construct(Kernel, MmuSize, Mmu));
mirrorPageTable->mmus[mirrorPageTable->reference] = *Mmu;
mirrorPageTable->hardwares[mirrorPageTable->reference] = Kernel->hardware;
mirrorPageTable->reference++;
gcmkFOOTER_ARG("mirrorPageTable->reference=%lu", mirrorPageTable->reference);
return gcvSTATUS_OK;
OnError:
if (mirrorPageTable && mirrorPageTable->reference == 0)
{
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Kernel->os, mirrorPageTable));
}
gcmkFOOTER();
return status;
#else
......@@ -897,6 +957,16 @@ gckMMU_Destroy(
}
return gcvSTATUS_OK;
#elif gcdMIRROR_PAGETABLE
mirrorPageTable->reference--;
if (mirrorPageTable->reference == 0)
{
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTable));
gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Mmu->os, mirrorPageTableMutex));
}
return _Destroy(Mmu);
#else
return _Destroy(Mmu);
#endif
......@@ -926,7 +996,7 @@ gckMMU_Destroy(
** Pointer to a variable that receives the hardware specific address.
*/
gceSTATUS
gckMMU_AllocatePages(
_AllocatePages(
IN gckMMU Mmu,
IN gctSIZE_T PageCount,
OUT gctPOINTER * PageTable,
......@@ -949,6 +1019,9 @@ gckMMU_AllocatePages(
if (PageCount > Mmu->pageTableEntries)
{
gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
__FUNCTION__, __LINE__);
/* Not enough pages avaiable. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
......@@ -1010,6 +1083,9 @@ gckMMU_AllocatePages(
}
else
{
gcmkPRINT("[galcore]: %s(%d): Run out of free page entry.",
__FUNCTION__, __LINE__);
/* Out of resources. */
gcmkONERROR(gcvSTATUS_OUT_OF_RESOURCES);
}
......@@ -1122,7 +1198,7 @@ OnError:
** Nothing.
*/
gceSTATUS
gckMMU_FreePages(
_FreePages(
IN gckMMU Mmu,
IN gctPOINTER PageTable,
IN gctSIZE_T PageCount
......@@ -1190,6 +1266,90 @@ OnError:
return status;
}
gceSTATUS
gckMMU_AllocatePages(
IN gckMMU Mmu,
IN gctSIZE_T PageCount,
OUT gctPOINTER * PageTable,
OUT gctUINT32 * Address
)
{
#if gcdMIRROR_PAGETABLE
gceSTATUS status;
gctPOINTER pageTable;
gctUINT32 address;
gctINT i;
gckMMU mmu;