From a3167bcfc5ec779e66f2ad7a3a535dccb7eff5ab Mon Sep 17 00:00:00 2001 From: Richard Zhao Date: Thu, 15 Sep 2011 16:42:04 +0800 Subject: ENGR00156850 gpu-viv: add gpu-viv driver source It's vivante driver 4.5.0 (Sep 5, 2011) with freescale changes. Signed-off-by: Richard Zhao Acked-by: Lily Zhang --- .../arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c | 5300 ++++++++++++++++++++ 1 file changed, 5300 insertions(+) create mode 100644 drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c (limited to 'drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c') diff --git a/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c new file mode 100644 index 000000000000..8ca8dfeaad84 --- /dev/null +++ b/drivers/mxc/gpu-viv/arch/XAQ2/hal/kernel/gc_hal_kernel_hardware.c @@ -0,0 +1,5300 @@ +/**************************************************************************** +* +* Copyright (C) 2005 - 2011 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. +* +*****************************************************************************/ + + + + +#include "gc_hal.h" +#include "gc_hal_kernel.h" + +#define _GC_OBJ_ZONE gcvZONE_HARDWARE + +/******************************************************************************\ +********************************* Support Code ********************************* +\******************************************************************************/ +static gceSTATUS +_ResetGPU( + IN gckOS Os, + IN gceCORE Core + ); + +static gceSTATUS +_IdentifyHardware( + IN gckOS Os, + IN gceCORE Core, + OUT gceCHIPMODEL * ChipModel, + OUT gctUINT32_PTR ChipRevision, + OUT gctUINT32_PTR ChipFeatures, + OUT gctUINT32_PTR ChipMinorFeatures0, + OUT gctUINT32_PTR ChipMinorFeatures1, + OUT gctUINT32_PTR ChipMinorFeatures2, + OUT gctUINT32_PTR ChipMinorFeatures3 + ) +{ + gceSTATUS status; + gctUINT32 chipIdentity; + gctUINT32 chipDate = 0xCCDDCCDD; + gctUINT32 chipTime = 0xCCDDCCDD; + + gcmkHEADER_ARG("Os=0x%x", Os); + + /* Read chip identity register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, 0x00018, &chipIdentity)); + + /* Special case for older graphic cores. */ + if (((((gctUINT32) (chipIdentity)) >> (0 ? 31:24) & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:24) - (0 ? 31:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:24) - (0 ? 31:24) + 1)))))))) + { + *ChipModel = gcv500; + *ChipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) ); + } + + else + { + /* Read date and time registers. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, 0x00028, &chipDate)); + + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, 0x0002C, &chipTime)); + + /* Read chip identity register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x00020, + (gctUINT32_PTR) ChipModel)); + + /* !!!! HACK ALERT !!!! */ + /* Because people change device IDs without letting software know + ** about it - here is the hack to make it all look the same. Only + ** for GC400 family. Next time - TELL ME!!! */ + if ((*ChipModel & 0xFF00) == 0x0400) + { + *ChipModel &= 0x0400; + } + + /* Read CHIP_REV register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, 0x00024, ChipRevision)); + + if ((*ChipModel == gcv300) + && (*ChipRevision == 0x2201) + ) + { + if ((chipDate == 0x20080814) && (chipTime == 0x12051100)) + { + /* This IP has an ECO; put the correct revision in it. */ + *ChipRevision = 0x1051; + } + } + } + + /* Read chip feature register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, Core, 0x0001C, ChipFeatures)); + +#ifndef VIVANTE_NO_3D + /* Disable fast clear on GC700. */ + if (*ChipModel == gcv700) + { + *ChipFeatures = ((((gctUINT32) (*ChipFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + } +#endif + + if (((*ChipModel == gcv500) && (*ChipRevision < 2)) + || ((*ChipModel == gcv300) && (*ChipRevision < 0x2000)) + ) + { + /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */ + *ChipMinorFeatures0 = 0; + *ChipMinorFeatures1 = 0; + *ChipMinorFeatures2 = 0; + *ChipMinorFeatures3 = 0; + } + else + { + /* Read chip minor feature register #0. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x00034, + ChipMinorFeatures0)); + + if (((((gctUINT32) (*ChipMinorFeatures0)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1))))))) + ) + { + /* Read chip minor featuress register #1. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x00074, + ChipMinorFeatures1)); + + /* Disabling texture hAlignment until it's fully tested. */ + *ChipMinorFeatures1 = *ChipMinorFeatures1 & ~(1 << 20); + + /* Read chip minor featuress register #2. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x00084, + ChipMinorFeatures2)); + + /* Read chip minor featuress register #1. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Os, + Core, + 0x00088, + ChipMinorFeatures3)); + } + else + { + /* Chip doesn't has minor features register #1 or 2 or 3. */ + *ChipMinorFeatures1 = 0; + *ChipMinorFeatures2 = 0; + *ChipMinorFeatures3 = 0; + } + } + + /* Disable HIERARCHICAL_Z. */ + *ChipMinorFeatures0 = ((((gctUINT32) (*ChipMinorFeatures0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))); + + /* Success. */ + gcmkFOOTER_ARG("*ChipModel=%x *ChipRevision=%x *ChipFeatures=0x%08x " + "*ChipMinorFeatures0=0x%08X *ChipMinorFeatures1=0x%08x " + "*ChipMinorFeatures2=0x%08x *ChipMinorFeatures3=0x%08x", + *ChipModel, *ChipRevision, *ChipFeatures, + *ChipMinorFeatures0, *ChipMinorFeatures1, + *ChipMinorFeatures2, *ChipMinorFeatures3); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +static gceSTATUS +_GetChipSpecs( + IN gckHARDWARE Hardware + ) +{ + gctUINT32 streamCount = 0; + gctUINT32 registerMax = 0; + gctUINT32 threadCount = 0; + gctUINT32 shaderCoreCount = 0; + gctUINT32 vertexCacheSize = 0; + gctUINT32 vertexOutputBufferSize = 0; + gctUINT32 pixelPipes = 0; + gctUINT32 instructionCount = 0; + gctUINT32 numConstants = 0; + gctUINT32 bufferSize = 0; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + if (((((gctUINT32) (Hardware->chipMinorFeatures0)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))) + { + gctUINT32 specs, specs2; + + /* Read gcChipSpecs register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00048, &specs)); + + /* Handy macro to improve reading. */ +#define gcmSPEC_FIELD(field) \ + (((((gctUINT32) (specs)) >> (0 ? GC_CHIP_SPECS_field)) & ((gctUINT32) ((((1 ? GC_CHIP_SPECS_field) - (0 ? GC_CHIP_SPECS_field) + 1) == 32) ? ~0 : (~(~0 << ((1 ? GC_CHIP_SPECS_field) - (0 ? GC_CHIP_SPECS_field) + 1)))))) ) + + /* Extract the fields. */ + streamCount = (((((gctUINT32) (specs)) >> (0 ? 3:0)) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1)))))) ); + registerMax = (((((gctUINT32) (specs)) >> (0 ? 7:4)) & ((gctUINT32) ((((1 ? 7:4) - (0 ? 7:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:4) - (0 ? 7:4) + 1)))))) ); + threadCount = (((((gctUINT32) (specs)) >> (0 ? 11:8)) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1)))))) ); + shaderCoreCount = (((((gctUINT32) (specs)) >> (0 ? 24:20)) & ((gctUINT32) ((((1 ? 24:20) - (0 ? 24:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:20) - (0 ? 24:20) + 1)))))) ); + vertexCacheSize = (((((gctUINT32) (specs)) >> (0 ? 16:12)) & ((gctUINT32) ((((1 ? 16:12) - (0 ? 16:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:12) - (0 ? 16:12) + 1)))))) ); + vertexOutputBufferSize = (((((gctUINT32) (specs)) >> (0 ? 31:28)) & ((gctUINT32) ((((1 ? 31:28) - (0 ? 31:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:28) - (0 ? 31:28) + 1)))))) ); + pixelPipes = (((((gctUINT32) (specs)) >> (0 ? 27:25)) & ((gctUINT32) ((((1 ? 27:25) - (0 ? 27:25) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:25) - (0 ? 27:25) + 1)))))) ); + + /* Read gcChipSpecs2 register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00080, &specs2)); + + /* Handy macro to improve reading. */ +#define gcmSPEC2_FIELD(field) \ + (((((gctUINT32) (specs2)) >> (0 ? GC_CHIP_SPECS2_field)) & ((gctUINT32) ((((1 ? GC_CHIP_SPECS2_field) - (0 ? GC_CHIP_SPECS2_field) + 1) == 32) ? ~0 : (~(~0 << ((1 ? GC_CHIP_SPECS2_field) - (0 ? GC_CHIP_SPECS2_field) + 1)))))) ) + + instructionCount = (((((gctUINT32) (specs2)) >> (0 ? 15:8)) & ((gctUINT32) ((((1 ? 15:8) - (0 ? 15:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:8) - (0 ? 15:8) + 1)))))) ); + numConstants = (((((gctUINT32) (specs2)) >> (0 ? 31:16)) & ((gctUINT32) ((((1 ? 31:16) - (0 ? 31:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:16) - (0 ? 31:16) + 1)))))) ); + bufferSize = (((((gctUINT32) (specs2)) >> (0 ? 7:0)) & ((gctUINT32) ((((1 ? 7:0) - (0 ? 7:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:0) - (0 ? 7:0) + 1)))))) ); + } + + /* Get the number of pixel pipes. */ + Hardware->pixelPipes = gcmMAX(pixelPipes, 1); + + /* Get the stream count. */ + Hardware->streamCount = (streamCount != 0) + ? streamCount + : (Hardware->chipModel >= gcv1000) ? 4 : 1; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: streamCount=%u%s", + Hardware->streamCount, + (streamCount == 0) ? " (default)" : ""); + + /* Get the vertex output buffer size. */ + Hardware->vertexOutputBufferSize = (vertexOutputBufferSize != 0) + ? 1 << vertexOutputBufferSize + : (Hardware->chipModel == gcv400) + ? (Hardware->chipRevision < 0x4000) ? 512 + : (Hardware->chipRevision < 0x4200) ? 256 + : 128 + : (Hardware->chipModel == gcv530) + ? (Hardware->chipRevision < 0x4200) ? 512 + : 128 + : 512; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: vertexOutputBufferSize=%u%s", + Hardware->vertexOutputBufferSize, + (vertexOutputBufferSize == 0) ? " (default)" : ""); + + /* Get the maximum number of threads. */ + Hardware->threadCount = (threadCount != 0) + ? 1 << threadCount + : (Hardware->chipModel == gcv400) ? 64 + : (Hardware->chipModel == gcv500) ? 128 + : (Hardware->chipModel == gcv530) ? 128 + : 256; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: threadCount=%u%s", + Hardware->threadCount, + (threadCount == 0) ? " (default)" : ""); + + /* Get the number of shader cores. */ + Hardware->shaderCoreCount = (shaderCoreCount != 0) + ? shaderCoreCount + : (Hardware->chipModel >= gcv1000) ? 2 + : 1; + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: shaderCoreCount=%u%s", + Hardware->shaderCoreCount, + (shaderCoreCount == 0) ? " (default)" : ""); + + /* Get the vertex cache size. */ + Hardware->vertexCacheSize = (vertexCacheSize != 0) + ? vertexCacheSize + : 8; + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: vertexCacheSize=%u%s", + Hardware->vertexCacheSize, + (vertexCacheSize == 0) ? " (default)" : ""); + + /* Get the maximum number of temporary registers. */ + Hardware->registerMax = (registerMax != 0) + /* Maximum of registerMax/4 registers are accessible to 1 shader */ + ? 1 << registerMax + : (Hardware->chipModel == gcv400) ? 32 + : 64; + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: registerMax=%u%s", + Hardware->registerMax, + (registerMax == 0) ? " (default)" : ""); + + /* Get the instruction count. */ + Hardware->instructionCount = (instructionCount == 0) ? 256 + : (instructionCount == 1) ? 1024 + : (instructionCount == 2) ? 2048 + : 256; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: instructionCount=%u%s", + Hardware->instructionCount, + (instructionCount == 0) ? " (default)" : ""); + + /* Get the number of constants. */ + Hardware->numConstants = numConstants; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: numConstants=%u%s", + Hardware->numConstants, + (numConstants == 0) ? " (default)" : ""); + + /* Get the buffer size. */ + Hardware->bufferSize = bufferSize; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Specs: bufferSize=%u%s", + Hardware->bufferSize, + (bufferSize == 0) ? " (default)" : ""); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************\ +****************************** gckHARDWARE API code ***************************** +\******************************************************************************/ + +/******************************************************************************* +** +** gckHARDWARE_Construct +** +** Construct a new gckHARDWARE object. +** +** INPUT: +** +** gckOS Os +** Pointer to an initialized gckOS object. +** +** gceCORE Core +** Specified core. +** +** OUTPUT: +** +** gckHARDWARE * Hardware +** Pointer to a variable that will hold the pointer to the gckHARDWARE +** object. +*/ +gceSTATUS +gckHARDWARE_Construct( + IN gckOS Os, + IN gceCORE Core, + OUT gckHARDWARE * Hardware + ) +{ + gckHARDWARE hardware = gcvNULL; + gceSTATUS status; + gceCHIPMODEL chipModel = gcv300; + gctUINT32 chipRevision = 0; + gctUINT32 chipFeatures = 0; + gctUINT32 chipMinorFeatures0 = 0; + gctUINT32 chipMinorFeatures1 = 0; + gctUINT32 chipMinorFeatures2 = 0; + gctUINT32 chipMinorFeatures3 = 0; + gctUINT16 data = 0xff00; + gctPOINTER pointer = gcvNULL; + + gcmkHEADER_ARG("Os=0x%x", Os); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Os, gcvOBJ_OS); + gcmkVERIFY_ARGUMENT(Hardware != gcvNULL); + + /* Enable the GPU. */ + gcmkONERROR(gckOS_SetGPUPower(Os, gcvTRUE, gcvTRUE)); + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00000, 0)); + + status = _ResetGPU(Os, Core); + + if (status != gcvSTATUS_OK) + { + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "_ResetGPU failed: status=%d\n", status); + } + + /* Identify the hardware. */ + gcmkONERROR(_IdentifyHardware(Os, + Core, + &chipModel, + &chipRevision, + &chipFeatures, + &chipMinorFeatures0, + &chipMinorFeatures1, + &chipMinorFeatures2, + &chipMinorFeatures3)); + + /* Allocate the gckHARDWARE object. */ + gcmkONERROR(gckOS_Allocate(Os, + gcmSIZEOF(struct _gckHARDWARE), + &pointer)); + + hardware = pointer; + + /* Initialize the gckHARDWARE object. */ + hardware->object.type = gcvOBJ_HARDWARE; + hardware->os = Os; + + hardware->core = Core; + + /* Determine the hardware type */ + switch (chipModel) + { + case gcv350: + case gcv355: + hardware->type = gcvHARDWARE_VG; + break; + + case gcv300: + case gcv320: + hardware->type = gcvHARDWARE_2D; + break; + + default: + hardware->type = gcvHARDWARE_3D; + + if ((((((gctUINT32) (chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )) + { + hardware->type |= gcvHARDWARE_2D; + } + } + + /* Set chip identity. */ + hardware->chipModel = chipModel; + hardware->chipRevision = chipRevision; + hardware->chipFeatures = chipFeatures; + hardware->chipMinorFeatures0 = chipMinorFeatures0; + hardware->chipMinorFeatures1 = chipMinorFeatures1; + hardware->chipMinorFeatures2 = chipMinorFeatures2; + hardware->chipMinorFeatures3 = chipMinorFeatures3; + hardware->powerBaseAddress = ((chipModel == gcv300) + && (chipRevision < 0x2000) + ) ? 0x100 : 0x00; + hardware->powerMutex = gcvNULL; + + hardware->mmuVersion = + (((((gctUINT32) (hardware->chipMinorFeatures1)) >> (0 ? 28:28)) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) ); + + /* Get chip specs. */ + gcmkONERROR(_GetChipSpecs(hardware)); + + /* Determine whether bug fixes #1 are present. */ + hardware->extraEventStates = ((((gctUINT32) (chipMinorFeatures1)) >> (0 ? 3:3) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))); + + /* Check if big endian */ + hardware->bigEndian = (*(gctUINT8 *)&data == 0xff); + + /* Initialize the fast clear. */ + gcmkONERROR(gckHARDWARE_SetFastClear(hardware, -1, -1)); + +#if !gcdENABLE_128B_MERGE && 1 && 1 + + if (((((gctUINT32) (hardware->chipMinorFeatures2)) >> (0 ? 21:21) & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 21:21) - (0 ? 21:21) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:21) - (0 ? 21:21) + 1)))))))) + { + /* 128B merge is turned on by default. Disable it. */ + gcmkONERROR(gckOS_WriteRegisterEx(Os, Core, 0x00558, 0)); + } + +#endif + + /* Set power state to ON. */ + hardware->chipPowerState = gcvPOWER_ON; + hardware->clockState = gcvTRUE; + hardware->powerState = gcvTRUE; + hardware->lastWaitLink = ~0U; + hardware->globalSemaphore = gcvNULL; + + gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerMutex)); + gcmkONERROR(gckOS_CreateSemaphore(Os, &hardware->globalSemaphore)); + +#if gcdPOWEROFF_TIMEOUT + gcmkONERROR(gckOS_CreateMutex(Os, &hardware->powerOffSema)); + gcmkONERROR(gckOS_AcquireMutex(Os, hardware->powerOffSema, gcvINFINITE)); +#endif + + /* Return pointer to the gckHARDWARE object. */ + *Hardware = hardware; + + /* Success. */ + gcmkFOOTER_ARG("*Hardware=0x%x", *Hardware); + return gcvSTATUS_OK; + +OnError: + /* Roll back. */ + if (hardware != gcvNULL) + { + /* Turn off the power. */ + gcmkVERIFY_OK(gckOS_SetGPUPower(Os, gcvFALSE, gcvFALSE)); + + if (hardware->globalSemaphore != gcvNULL) + { + /* Destroy the global semaphore. */ + gcmkVERIFY_OK(gckOS_DestroySemaphore(Os, + hardware->globalSemaphore)); + } + + if (hardware->powerMutex != gcvNULL) + { + /* Destroy the power mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, hardware->powerMutex)); + } + +#if gcdPOWEROFF_TIMEOUT + if (hardware->powerOffSema != gcvNULL) + { + gcmkVERIFY_OK(gckOS_DeleteMutex(Os, &hardware->powerOffSema)); + } +#endif + + gcmkVERIFY_OK(gcmkOS_SAFE_FREE(Os, hardware)); + } + + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Destroy +** +** Destroy an gckHARDWARE object. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object that needs to be destroyed. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_Destroy( + IN gckHARDWARE Hardware + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Turn off the power. */ + gcmkVERIFY_OK(gckOS_SetGPUPower(Hardware->os, gcvFALSE, gcvFALSE)); + + /* Destroy the power semaphore. */ + gcmkVERIFY_OK(gckOS_DestroySemaphore(Hardware->os, + Hardware->globalSemaphore)); + + /* Destroy the power mutex. */ + gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerMutex)); + +#if gcdPOWEROFF_TIMEOUT + gcmkVERIFY_OK(gckOS_DeleteMutex(Hardware->os, Hardware->powerOffSema)); +#endif + + /* Mark the object as unknown. */ + Hardware->object.type = gcvOBJ_UNKNOWN; + + /* Free the object. */ + gcmkONERROR(gcmkOS_SAFE_FREE(Hardware->os, Hardware)); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_GetType +** +** Get the hardware type. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** OUTPUT: +** +** gceHARDWARE_TYPE * Type +** Pointer to a variable that receives the type of hardware object. +*/ +gceSTATUS +gckHARDWARE_GetType( + IN gckHARDWARE Hardware, + OUT gceHARDWARE_TYPE * Type + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + gcmkVERIFY_ARGUMENT(Type != gcvNULL); + + *Type = Hardware->type; + + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_InitializeHardware +** +** Initialize the hardware. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_InitializeHardware( + IN gckHARDWARE Hardware + ) +{ + gceSTATUS status; + gctUINT32 baseAddress; + gctUINT32 chipRev; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Read the chip revision register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00024, + &chipRev)); + + if (chipRev != Hardware->chipRevision) + { + /* Chip is not there! */ + gcmkONERROR(gcvSTATUS_CONTEXT_LOSSED); + } + + /* Disable isolate GPU bit. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + ((((gctUINT32) (0x00000100)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))))); + + /* Reset memory counters. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0003C, + ~0U)); + + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0003C, + 0)); + + /* Get the system's physical base address. */ + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, &baseAddress)); + + /* Program the base addesses. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0041C, + baseAddress)); + + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00418, + baseAddress)); + +#ifndef VIVANTE_NO_3D + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00420, + baseAddress)); + + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00428, + baseAddress)); + + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00424, + baseAddress)); +#endif + +#if !VIVANTE_PROFILER && 1 + { + gctUINT32 data; + + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + &data)); + + /* Enable clock gating. */ + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + if ((Hardware->chipRevision == 0x4301) + || (Hardware->chipRevision == 0x4302) + ) + { + /* Disable stall module level clock gating for 4.3.0.1 and 4.3.0.2 + ** revisions. */ + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))); + } + + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00100, + data)); + +#ifndef VIVANTE_NO_3D + /* Disable PE clock gating on revs < 5.0 when HZ is present without a + ** bug fix. */ + if ((Hardware->chipRevision < 0x5000) + && ((((gctUINT32) (Hardware->chipMinorFeatures1)) >> (0 ? 9:9) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) == (0x0 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) + && ((((gctUINT32) (Hardware->chipMinorFeatures0)) >> (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))))))) + ) + { + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + &data)); + + /* Disable PE clock gating. */ + data = ((((gctUINT32) (data)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); + + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + Hardware->powerBaseAddress + + 0x00104, + data)); + } +#endif + } +#endif + + /* Test if MMU is initialized. */ + if ((Hardware->kernel != gcvNULL) + && (Hardware->kernel->mmu != gcvNULL) + ) + { + /* Reset MMU. */ + gcmkONERROR( + gckHARDWARE_SetMMU(Hardware, + Hardware->kernel->mmu->pageTableLogical)); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the error. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_QueryMemory +** +** Query the amount of memory available on the hardware. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** OUTPUT: +** +** gctSIZE_T * InternalSize +** Pointer to a variable that will hold the size of the internal video +** memory in bytes. If 'InternalSize' is gcvNULL, no information of the +** internal memory will be returned. +** +** gctUINT32 * InternalBaseAddress +** Pointer to a variable that will hold the hardware's base address for +** the internal video memory. This pointer cannot be gcvNULL if +** 'InternalSize' is also non-gcvNULL. +** +** gctUINT32 * InternalAlignment +** Pointer to a variable that will hold the hardware's base address for +** the internal video memory. This pointer cannot be gcvNULL if +** 'InternalSize' is also non-gcvNULL. +** +** gctSIZE_T * ExternalSize +** Pointer to a variable that will hold the size of the external video +** memory in bytes. If 'ExternalSize' is gcvNULL, no information of the +** external memory will be returned. +** +** gctUINT32 * ExternalBaseAddress +** Pointer to a variable that will hold the hardware's base address for +** the external video memory. This pointer cannot be gcvNULL if +** 'ExternalSize' is also non-gcvNULL. +** +** gctUINT32 * ExternalAlignment +** Pointer to a variable that will hold the hardware's base address for +** the external video memory. This pointer cannot be gcvNULL if +** 'ExternalSize' is also non-gcvNULL. +** +** gctUINT32 * HorizontalTileSize +** Number of horizontal pixels per tile. If 'HorizontalTileSize' is +** gcvNULL, no horizontal pixel per tile will be returned. +** +** gctUINT32 * VerticalTileSize +** Number of vertical pixels per tile. If 'VerticalTileSize' is +** gcvNULL, no vertical pixel per tile will be returned. +*/ +gceSTATUS +gckHARDWARE_QueryMemory( + IN gckHARDWARE Hardware, + OUT gctSIZE_T * InternalSize, + OUT gctUINT32 * InternalBaseAddress, + OUT gctUINT32 * InternalAlignment, + OUT gctSIZE_T * ExternalSize, + OUT gctUINT32 * ExternalBaseAddress, + OUT gctUINT32 * ExternalAlignment, + OUT gctUINT32 * HorizontalTileSize, + OUT gctUINT32 * VerticalTileSize + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (InternalSize != gcvNULL) + { + /* No internal memory. */ + *InternalSize = 0; + } + + if (ExternalSize != gcvNULL) + { + /* No external memory. */ + *ExternalSize = 0; + } + + if (HorizontalTileSize != gcvNULL) + { + /* 4x4 tiles. */ + *HorizontalTileSize = 4; + } + + if (VerticalTileSize != gcvNULL) + { + /* 4x4 tiles. */ + *VerticalTileSize = 4; + } + + /* Success. */ + gcmkFOOTER_ARG("*InternalSize=%lu *InternalBaseAddress=0x%08x " + "*InternalAlignment=0x%08x *ExternalSize=%lu " + "*ExternalBaseAddress=0x%08x *ExtenalAlignment=0x%08x " + "*HorizontalTileSize=%u *VerticalTileSize=%u", + gcmOPT_VALUE(InternalSize), + gcmOPT_VALUE(InternalBaseAddress), + gcmOPT_VALUE(InternalAlignment), + gcmOPT_VALUE(ExternalSize), + gcmOPT_VALUE(ExternalBaseAddress), + gcmOPT_VALUE(ExternalAlignment), + gcmOPT_VALUE(HorizontalTileSize), + gcmOPT_VALUE(VerticalTileSize)); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_QueryChipIdentity +** +** Query the identity of the hardware. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** OUTPUT: +** +** gceCHIPMODEL * ChipModel +** If 'ChipModel' is not gcvNULL, the variable it points to will +** receive the model of the chip. +** +** gctUINT32 * ChipRevision +** If 'ChipRevision' is not gcvNULL, the variable it points to will +** receive the revision of the chip. +** +** gctUINT32 * ChipFeatures +** If 'ChipFeatures' is not gcvNULL, the variable it points to will +** receive the feature set of the chip. +** +** gctUINT32 * ChipMinorFeatures +** If 'ChipMinorFeatures' is not gcvNULL, the variable it points to +** will receive the minor feature set of the chip. +** +** gctUINT32 * ChipMinorFeatures1 +** If 'ChipMinorFeatures1' is not gcvNULL, the variable it points to +** will receive the minor feature set 1 of the chip. +** +** gctUINT32 * ChipMinorFeatures2 +** If 'ChipMinorFeatures2' is not gcvNULL, the variable it points to +** will receive the minor feature set 2 of the chip. +** +*/ +gceSTATUS +gckHARDWARE_QueryChipIdentity( + IN gckHARDWARE Hardware, + OUT gceCHIPMODEL * ChipModel, + OUT gctUINT32 * ChipRevision, + OUT gctUINT32* ChipFeatures, + OUT gctUINT32* ChipMinorFeatures, + OUT gctUINT32* ChipMinorFeatures1, + OUT gctUINT32* ChipMinorFeatures2, + OUT gctUINT32* ChipMinorFeatures3 + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Return chip model. */ + if (ChipModel != gcvNULL) + { + *ChipModel = Hardware->chipModel; + } + + /* Return revision number. */ + if (ChipRevision != gcvNULL) + { + *ChipRevision = Hardware->chipRevision; + } + + /* Return feature set. */ + if (ChipFeatures != gcvNULL) + { + gctUINT32 features = Hardware->chipFeatures; + + if ((((((gctUINT32) (features)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + /* Override fast clear by command line. */ + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Hardware->allowFastClear) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + } + + if ((((((gctUINT32) (features)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) )) + { + /* Override compression by command line. */ + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) ((gctUINT32) (Hardware->allowCompression) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); + } + + /* Mark 2D pipe as available for GC500.0 through GC500.2 and GC300, + ** since they did not have this bit. */ + if (((Hardware->chipModel == gcv500) + && (Hardware->chipRevision <= 2) + ) + || (Hardware->chipModel == gcv300) + ) + { + features = ((((gctUINT32) (features)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))); + } + + *ChipFeatures = features; + } + + /* Return minor feature set. */ + if (ChipMinorFeatures != gcvNULL) + { + *ChipMinorFeatures = Hardware->chipMinorFeatures0; + } + + /* Return minor feature set 1. */ + if (ChipMinorFeatures1 != gcvNULL) + { + *ChipMinorFeatures1 = Hardware->chipMinorFeatures1; + } + + /* Return minor feature set 2. */ + if (ChipMinorFeatures2 != gcvNULL) + { + *ChipMinorFeatures2 = Hardware->chipMinorFeatures2; + } + + /* Return minor feature set 3. */ + if (ChipMinorFeatures3 != gcvNULL) + { + *ChipMinorFeatures3 = Hardware->chipMinorFeatures3; + } + + /* Success. */ + gcmkFOOTER_ARG("*ChipModel=0x%x *ChipRevision=0x%x *ChipFeatures=0x%08x " + "*ChipMinorFeatures=0x%08x *ChipMinorFeatures1=0x%08x " + "*ChipMinorFeatures2=0x%08x *ChipMinorFeatures3=0x%08x", + gcmOPT_VALUE(ChipModel), + gcmOPT_VALUE(ChipRevision), + gcmOPT_VALUE(ChipFeatures), + gcmOPT_VALUE(ChipMinorFeatures), + gcmOPT_VALUE(ChipMinorFeatures1), + gcmOPT_VALUE(ChipMinorFeatures2), + gcmOPT_VALUE(ChipMinorFeatures3)); + + return gcvSTATUS_OK; +} + +gceSTATUS +gckHARDWARE_QueryChipSpecs( + IN gckHARDWARE Hardware, + OUT gctUINT32_PTR StreamCount, + OUT gctUINT32_PTR RegisterMax, + OUT gctUINT32_PTR ThreadCount, + OUT gctUINT32_PTR ShaderCoreCount, + OUT gctUINT32_PTR VertexCacheSize, + OUT gctUINT32_PTR VertexOutputBufferSize, + OUT gctUINT32_PTR PixelPipes, + OUT gctUINT32_PTR InstructionCount, + OUT gctUINT32_PTR NumConstants, + OUT gctUINT32_PTR BufferSize + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Return the number of streams. */ + if (StreamCount != gcvNULL) + { + *StreamCount = Hardware->streamCount; + } + + /* Return the number of temporary registers. */ + if (RegisterMax != gcvNULL) + { + *RegisterMax = Hardware->registerMax; + } + + /* Return the maximum number of thrteads. */ + if (ThreadCount != gcvNULL) + { + *ThreadCount = Hardware->threadCount; + } + + /* Return the number of shader cores. */ + if (ShaderCoreCount != gcvNULL) + { + *ShaderCoreCount = Hardware->shaderCoreCount; + } + + /* Return the number of entries in the vertex cache. */ + if (VertexCacheSize != gcvNULL) + { + *VertexCacheSize = Hardware->vertexCacheSize; + } + + /* Return the number of entries in the vertex output buffer. */ + if (VertexOutputBufferSize != gcvNULL) + { + *VertexOutputBufferSize = Hardware->vertexOutputBufferSize; + } + + /* Return the number of pixel pipes. */ + if (PixelPipes != gcvNULL) + { + *PixelPipes = Hardware->pixelPipes; + } + + /* Return the number of instructions. */ + if (InstructionCount != gcvNULL) + { + *InstructionCount = Hardware->instructionCount; + } + + /* Return the number of constants. */ + if (NumConstants != gcvNULL) + { + *NumConstants = Hardware->numConstants; + } + + /* Return the buffer size. */ + if (BufferSize != gcvNULL) + { + *BufferSize = Hardware->bufferSize; + } + + /* Success. */ + gcmkFOOTER_ARG("*StreamCount=%u *RegisterMax=%u *ThreadCount=%u " + "*ShaderCoreCount=%u *VertexCacheSize=%u " + "*VertexOutputBufferSize=%u *PixelPipes=%u", + "*InstructionCount=%u *NumConstants=%u *BufferSize=%u", + gcmOPT_VALUE(StreamCount), gcmOPT_VALUE(RegisterMax), + gcmOPT_VALUE(ThreadCount), gcmOPT_VALUE(ShaderCoreCount), + gcmOPT_VALUE(VertexCacheSize), + gcmOPT_VALUE(VertexOutputBufferSize), + gcmOPT_VALUE(PixelPipes), + gcmOPT_VALUE(InstructionCount), + gcmOPT_VALUE(NumConstants), + gcmOPT_VALUE(BufferSize)); + + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_ConvertFormat +** +** Convert an API format to hardware parameters. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** gceSURF_FORMAT Format +** API format to convert. +** +** OUTPUT: +** +** gctUINT32 * BitsPerPixel +** Pointer to a variable that will hold the number of bits per pixel. +** +** gctUINT32 * BytesPerTile +** Pointer to a variable that will hold the number of bytes per tile. +*/ +gceSTATUS +gckHARDWARE_ConvertFormat( + IN gckHARDWARE Hardware, + IN gceSURF_FORMAT Format, + OUT gctUINT32 * BitsPerPixel, + OUT gctUINT32 * BytesPerTile + ) +{ + gctUINT32 bitsPerPixel; + gctUINT32 bytesPerTile; + + gcmkHEADER_ARG("Hardware=0x%x Format=%d", Hardware, Format); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Dispatch on format. */ + switch (Format) + { + case gcvSURF_INDEX8: + case gcvSURF_A8: + case gcvSURF_L8: + /* 8-bpp format. */ + bitsPerPixel = 8; + bytesPerTile = (8 * 4 * 4) / 8; + break; + + case gcvSURF_YV12: + case gcvSURF_I420: + case gcvSURF_NV12: + case gcvSURF_NV21: + /* 12-bpp planar YUV formats. */ + bitsPerPixel = 12; + bytesPerTile = (12 * 4 * 4) / 8; + break; + + case gcvSURF_A8L8: + case gcvSURF_X4R4G4B4: + case gcvSURF_A4R4G4B4: + case gcvSURF_X1R5G5B5: + case gcvSURF_A1R5G5B5: + case gcvSURF_R5G5B5X1: + case gcvSURF_R4G4B4X4: + case gcvSURF_X4B4G4R4: + case gcvSURF_X1B5G5R5: + case gcvSURF_B4G4R4X4: + case gcvSURF_R5G6B5: + case gcvSURF_B5G5R5X1: + case gcvSURF_YUY2: + case gcvSURF_UYVY: + case gcvSURF_YVYU: + case gcvSURF_VYUY: + case gcvSURF_NV16: + case gcvSURF_NV61: + case gcvSURF_D16: + /* 16-bpp format. */ + bitsPerPixel = 16; + bytesPerTile = (16 * 4 * 4) / 8; + break; + + case gcvSURF_X8R8G8B8: + case gcvSURF_A8R8G8B8: + case gcvSURF_X8B8G8R8: + case gcvSURF_A8B8G8R8: + case gcvSURF_R8G8B8X8: + case gcvSURF_D32: + /* 32-bpp format. */ + bitsPerPixel = 32; + bytesPerTile = (32 * 4 * 4) / 8; + break; + + case gcvSURF_D24S8: + case gcvSURF_D24X8: + /* 24-bpp format. */ + bitsPerPixel = 32; + bytesPerTile = (32 * 4 * 4) / 8; + break; + + case gcvSURF_DXT1: + case gcvSURF_ETC1: + bitsPerPixel = 4; + bytesPerTile = (4 * 4 * 4) / 8; + break; + + case gcvSURF_DXT2: + case gcvSURF_DXT3: + case gcvSURF_DXT4: + case gcvSURF_DXT5: + bitsPerPixel = 8; + bytesPerTile = (8 * 4 * 4) / 8; + break; + + default: + /* Invalid format. */ + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); + return gcvSTATUS_INVALID_ARGUMENT; + } + + /* Set the result. */ + if (BitsPerPixel != gcvNULL) + { + * BitsPerPixel = bitsPerPixel; + } + + if (BytesPerTile != gcvNULL) + { + * BytesPerTile = bytesPerTile; + } + + /* Success. */ + gcmkFOOTER_ARG("*BitsPerPixel=%u *BytesPerTile=%u", + gcmOPT_VALUE(BitsPerPixel), gcmOPT_VALUE(BytesPerTile)); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_SplitMemory +** +** Split a hardware specific memory address into a pool and offset. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** gctUINT32 Address +** Address in hardware specific format. +** +** OUTPUT: +** +** gcePOOL * Pool +** Pointer to a variable that will hold the pool type for the address. +** +** gctUINT32 * Offset +** Pointer to a variable that will hold the offset for the address. +*/ +gceSTATUS +gckHARDWARE_SplitMemory( + IN gckHARDWARE Hardware, + IN gctUINT32 Address, + OUT gcePOOL * Pool, + OUT gctUINT32 * Offset + ) +{ + gcmkHEADER_ARG("Hardware=0x%x Addres=0x%08x", Hardware, Address); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Pool != gcvNULL); + gcmkVERIFY_ARGUMENT(Offset != gcvNULL); + + /* Dispatch on memory type. */ + switch ((((((gctUINT32) (Address)) >> (0 ? 31:31)) & ((gctUINT32) ((((1 ? 31:31) - (0 ? 31:31) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:31) - (0 ? 31:31) + 1)))))) )) + { + case 0x0: + /* System memory. */ + *Pool = gcvPOOL_SYSTEM; + break; + + case 0x1: + /* Virtual memory. */ + *Pool = gcvPOOL_VIRTUAL; + break; + + default: + /* Invalid memory type. */ + gcmkFOOTER_ARG("status=%d", gcvSTATUS_INVALID_ARGUMENT); + return gcvSTATUS_INVALID_ARGUMENT; + } + + /* Return offset of address. */ + *Offset = (((((gctUINT32) (Address)) >> (0 ? 30:0)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1)))))) ); + + /* Success. */ + gcmkFOOTER_ARG("*Pool=%d *Offset=0x%08x", *Pool, *Offset); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_Execute +** +** Kickstart the hardware's command processor with an initialized command +** buffer. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** gctPOINTER Logical +** Logical address of command buffer. +** +** gctSIZE_T Bytes +** Number of bytes for the prefetch unit (until after the first LINK). +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_Execute( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, +#ifdef __QNXNTO__ + IN gctPOINTER Physical, + IN gctBOOL PhysicalAddresses, +#endif + IN gctSIZE_T Bytes + ) +{ + gceSTATUS status; + gctUINT32 address = 0, control; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Bytes=%lu", + Hardware, Logical, Bytes); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + +#ifdef __QNXNTO__ + if (PhysicalAddresses) + { + /* Convert physical into hardware specific address. */ + gcmkONERROR( + gckHARDWARE_ConvertPhysical(Hardware, Physical, &address)); + } + else + { +#endif + /* Convert logical into hardware specific address. */ + gcmkONERROR( + gckHARDWARE_ConvertLogical(Hardware, Logical, &address)); +#ifdef __QNXNTO__ + } +#endif + + /* Enable all events. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00014, ~0U)); + + /* Write address register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00654, address)); + + /* Build control register. */ + control = ((((gctUINT32) (0)) & ~(((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))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + /* Set big endian */ + if (Hardware->bigEndian) + { + control |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20))) | (((gctUINT32) (0x2 & ((gctUINT32) ((((1 ? 21:20) - (0 ? 21:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 21:20) - (0 ? 21:20) + 1))))))) << (0 ? 21:20))); + } + + /* Write control register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00658, control)); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Started command buffer @ 0x%08x", + address); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_WaitLink +** +** Append a WAIT/LINK command sequence at the specified location in the command +** queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** WAIT/LINK command sequence at or gcvNULL just to query the size of the +** WAIT/LINK command sequence. +** +** gctUINT32 Offset +** Offset into command buffer required for alignment. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the WAIT/LINK command +** sequence. If 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** by the WAIT/LINK command sequence. If 'Bytes' is gcvNULL, nothing will +** be returned. +** +** gctUINT32 * WaitOffset +** Pointer to a variable that will receive the offset of the WAIT command +** from the specified logcial pointer. +** If 'WaitOffset' is gcvNULL nothing will be returned. +** +** gctSIZE_T * WaitSize +** Pointer to a variable that will receive the number of bytes used by +** the WAIT command. If 'LinkSize' is gcvNULL nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_WaitLink( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctUINT32 Offset, + IN OUT gctSIZE_T * Bytes, + OUT gctUINT32 * WaitOffset, + OUT gctSIZE_T * WaitSize + ) +{ + static const gctUINT waitCount = 200; + + gceSTATUS status; + gctUINT32 address; + gctUINT32_PTR logical; + gctSIZE_T bytes; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x *Bytes=%lu", + Hardware, Logical, Offset, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical != gcvNULL) || (Bytes != gcvNULL)); + + /* Compute number of bytes required. */ +#if gcd6000_SUPPORT + bytes = gcmALIGN(Offset + 96, 8) - Offset; +#else + bytes = gcmALIGN(Offset + 16, 8) - Offset; +#endif + + /* Cast the input pointer. */ + logical = (gctUINT32_PTR) Logical; + + if (logical != gcvNULL) + { + /* Not enough space? */ + if (*Bytes < bytes) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Convert logical into hardware specific address. */ + gcmkONERROR(gckHARDWARE_ConvertLogical(Hardware, logical, &address)); + + /* Store the WAIT/LINK address. */ + Hardware->lastWaitLink = address; + + /* Append WAIT(count). */ + logical[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (waitCount) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + +#if gcd6000_SUPPORT + /* Send FE-PE sempahore token. */ + logical[2] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[3] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* Send FE-PE stall token. */ + logical[4] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0F00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[5] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /*************************************************************/ + /* Enable chip ID 0. */ + logical[6] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | (1 << 0); + + /* Send semaphore from FE to ChipID 1. */ + logical[8] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[9] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + + /* Send semaphore from FE to ChipID 1. */ + logical[10] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + logical[11] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + + /*************************************************************/ + /* Enable chip ID 1. */ + logical[12] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | (1 << 1); + + /* Send semaphore from FE to ChipID 1. */ + logical[14] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[15] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + + /* Wait for semaphore from ChipID 0. */ + logical[16] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + logical[17] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x0F & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))); + + /*************************************************************/ + /* Enable all chips. */ + logical[18] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x0D & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | (0xFFFF); + + /* LoadState(AQFlush, 1), flush. */ + logical[20] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + logical[21] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? AQ_FLUSH_L2_CACHE) - (0 ? AQ_FLUSH_L2_CACHE) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_FLUSH_L2_CACHE) - (0 ? AQ_FLUSH_L2_CACHE) + 1))))))) << (0 ? AQ_FLUSH_L2_CACHE))) | (((gctUINT32) (AQ_FLUSH_L2_CACHE_ENABLE & ((gctUINT32) ((((1 ? AQ_FLUSH_L2_CACHE) - (0 ? AQ_FLUSH_L2_CACHE) + 1) == 32) ? ~0 : (~(~0 << ((1 ? AQ_FLUSH_L2_CACHE) - (0 ? AQ_FLUSH_L2_CACHE) + 1))))))) << (0 ? AQ_FLUSH_L2_CACHE))); + + /* Append LINK(2, address). */ + logical[22] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[23] = address; +#else + /* Append LINK(2, address). */ + logical[2] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[3] = address; + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: WAIT %u", address, waitCount + ); + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: LINK 0x%08x, #%lu", + address + 8, address, bytes + ); +#endif + + if (WaitOffset != gcvNULL) + { + /* Return the offset pointer to WAIT command. */ + *WaitOffset = 0; + } + + if (WaitSize != gcvNULL) + { + /* Return number of bytes used by the WAIT command. */ + *WaitSize = 8; + } + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the WAIT/LINK command + ** sequence. */ + *Bytes = bytes; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu *WaitOffset=0x%x *WaitSize=%lu", + gcmOPT_VALUE(Bytes), gcmOPT_VALUE(WaitOffset), + gcmOPT_VALUE(WaitSize)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_End +** +** Append an END command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** END command at or gcvNULL just to query the size of the END command. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the END command. If +** 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the END command. If 'Bytes' is gcvNULL, nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_End( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN OUT gctSIZE_T * Bytes + ) +{ + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", + Hardware, Logical, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + + if (Logical != gcvNULL) + { + if (*Bytes < 8) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Append END. */ + logical[0] = + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", Logical); + + /* Make sure the CPU writes out the data to memory. */ + gcmkONERROR( + gckOS_MemoryBarrier(Hardware->os, Logical)); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the END command. */ + *Bytes = 8; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Nop +** +** Append a NOP command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** NOP command at or gcvNULL just to query the size of the NOP command. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the NOP command. If +** 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_Nop( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN OUT gctSIZE_T * Bytes + ) +{ + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x *Bytes=%lu", + Hardware, Logical, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + + if (Logical != gcvNULL) + { + if (*Bytes < 8) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Append NOP. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x03 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: NOP", Logical); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the NOP command. */ + *Bytes = 8; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Wait +** +** Append a WAIT command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** WAIT command at or gcvNULL just to query the size of the WAIT command. +** +** gctUINT32 Count +** Number of cycles to wait. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the WAIT command. If +** 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the NOP command. If 'Bytes' is gcvNULL, nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_Wait( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctUINT32 Count, + IN OUT gctSIZE_T * Bytes + ) +{ + gceSTATUS status; + gctUINT32_PTR logical; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Count=%u *Bytes=%lu", + Hardware, Logical, Count, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + + /* Cast the input pointer. */ + logical = (gctUINT32_PTR) Logical; + + if (Logical != gcvNULL) + { + if (*Bytes < 8) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Append WAIT. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (Count) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + +#if gcmIS_DEBUG(gcdDEBUG_TRACE) + { + gctUINT32 address; + + /* Convert logical into hardware specific address. */ + gcmkONERROR(gckHARDWARE_ConvertLogical( + Hardware, logical, &address + )); + + gcmkTRACE_ZONE( + gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: WAIT %u", address, Count + ); + } +#endif + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the WAIT command. */ + *Bytes = 8; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Event +** +** Append an EVENT command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** the EVENT command at or gcvNULL just to query the size of the EVENT +** command. +** +** gctUINT8 Event +** Event ID to program. +** +** gceKERNEL_WHERE FromWhere +** Location of the pipe to send the event. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the EVENT command. If +** 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the EVENT command. If 'Bytes' is gcvNULL, nothing will be +** returned. +*/ +gceSTATUS +gckHARDWARE_Event( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctUINT8 Event, + IN gceKERNEL_WHERE FromWhere, + IN OUT gctSIZE_T * Bytes + ) +{ + gctUINT size; + gctUINT32 destination = 0; + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Event=%u FromWhere=%d *Bytes=%lu", + Hardware, Logical, Event, FromWhere, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + gcmkVERIFY_ARGUMENT(Event < 32); + + /* Determine the size of the command. */ + size = (Hardware->extraEventStates && (FromWhere == gcvKERNEL_PIXEL)) + ? gcmALIGN(8 + (1 + 5) * 4, 8) /* EVENT + 5 STATES */ + : 8; + + if (Logical != gcvNULL) + { + if (*Bytes < size) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + switch (FromWhere) + { + case gcvKERNEL_COMMAND: + /* From command processor. */ + destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1))))))) << (0 ? 5:5))); + break; + + case gcvKERNEL_PIXEL: + /* From pixel engine. */ + destination = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1))))))) << (0 ? 6:6))); + break; + + default: + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + /* Append EVENT(Event, destiantion). */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E01) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + logical[1] = ((((gctUINT32) (destination)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) ((gctUINT32) (Event) & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))); + + /* Make sure the event ID gets written out before GPU can access it. */ + gcmkONERROR( + gckOS_MemoryBarrier(Hardware->os, logical + 1)); + +#if gcmIS_DEBUG(gcdDEBUG_TRACE) + { + gctUINT32 phys; + gckOS_GetPhysicalAddress(Hardware->os, Logical, &phys); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%08x: EVENT %d", phys, Event); + } +#endif + + /* Append the extra states. These are needed for the chips that do not + ** support back-to-back events due to the async interface. The extra + ** states add the necessary delay to ensure that event IDs do not + ** collide. */ + if (size > 8) + { + logical[2] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0100) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + logical[3] = 0; + logical[4] = 0; + logical[5] = 0; + logical[6] = 0; + logical[7] = 0; + } + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the EVENT command. */ + *Bytes = size; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_PipeSelect +** +** Append a PIPESELECT command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** the PIPESELECT command at or gcvNULL just to query the size of the +** PIPESELECT command. +** +** gcePIPE_SELECT Pipe +** Pipe value to select. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the PIPESELECT command. +** If 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the PIPESELECT command. If 'Bytes' is gcvNULL, nothing will be +** returned. +*/ +gceSTATUS +gckHARDWARE_PipeSelect( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gcePIPE_SELECT Pipe, + IN OUT gctSIZE_T * Bytes + ) +{ + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Pipe=%d *Bytes=%lu", + Hardware, Logical, Pipe, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + + /* Append a PipeSelect. */ + if (Logical != gcvNULL) + { + gctUINT32 flush, stall; + + if (*Bytes < 32) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + flush = (Pipe == gcvPIPE_2D) + ? ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + : ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))); + + stall = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 4:0) - (0 ? 4:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:0) - (0 ? 4:0) + 1))))))) << (0 ? 4:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))) | (((gctUINT32) (0x07 & ((gctUINT32) ((((1 ? 12:8) - (0 ? 12:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:8) - (0 ? 12:8) + 1))))))) << (0 ? 12:8))); + + /* LoadState(AQFlush, 1), flush. */ + logical[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + logical[1] + = flush; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: FLUSH 0x%x", logical, flush); + + /* LoadState(AQSempahore, 1), stall. */ + logical[2] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E02) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + logical[3] + = stall; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: SEMAPHORE 0x%x", logical + 2, stall); + + /* Stall, stall. */ + logical[4] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x09 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))); + logical[5] = stall; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: STALL 0x%x", logical + 4, stall); + + /* LoadState(AQPipeSelect, 1), pipe. */ + logical[6] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E00) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + logical[7] = (Pipe == gcvPIPE_2D) + ? 0x1 + : 0x0; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: PIPE %d", logical + 6, Pipe); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the PIPESELECT command. */ + *Bytes = 32; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Link +** +** Append a LINK command at the specified location in the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Pointer to the current location inside the command queue to append +** the LINK command at or gcvNULL just to query the size of the LINK +** command. +** +** gctPOINTER FetchAddress +** Logical address of destination of LINK. +** +** gctSIZE_T FetchSize +** Number of bytes in destination of LINK. +** +** gctSIZE_T * Bytes +** Pointer to the number of bytes available for the LINK command. If +** 'Logical' is gcvNULL, this argument will be ignored. +** +** OUTPUT: +** +** gctSIZE_T * Bytes +** Pointer to a variable that will receive the number of bytes required +** for the LINK command. If 'Bytes' is gcvNULL, nothing will be returned. +*/ +gceSTATUS +gckHARDWARE_Link( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctPOINTER FetchAddress, + IN gctSIZE_T FetchSize, + IN OUT gctSIZE_T * Bytes + ) +{ + gceSTATUS status; + gctSIZE_T bytes; + gctUINT32 address; + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x FetchAddress=0x%x FetchSize=%lu " + "*Bytes=%lu", + Hardware, Logical, FetchAddress, FetchSize, + gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Logical == gcvNULL) || (Bytes != gcvNULL)); + + if (Logical != gcvNULL) + { + if (*Bytes < 8) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Convert logical address to hardware address. */ + gcmkONERROR( + gckHARDWARE_ConvertLogical(Hardware, FetchAddress, &address)); + + logical[1] = address; + + /* Make sure the address got written before the LINK command. */ + gcmkONERROR( + gckOS_MemoryBarrier(Hardware->os, logical + 1)); + + /* Compute number of 64-byte aligned bytes to fetch. */ + bytes = gcmALIGN(address + FetchSize, 64) - address; + + /* Append LINK(bytes / 8), FetchAddress. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x08 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (bytes >> 3) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))); + + /* Memory barrier. */ + gcmkONERROR( + gckOS_MemoryBarrier(Hardware->os, logical)); + } + + if (Bytes != gcvNULL) + { + /* Return number of bytes required by the LINK command. */ + *Bytes = 8; + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_AlignToTile +** +** Align the specified width and height to tile boundaries. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gceSURF_TYPE Type +** Type of alignment. +** +** gctUINT32 * Width +** Pointer to the width to be aligned. If 'Width' is gcvNULL, no width +** will be aligned. +** +** gctUINT32 * Height +** Pointer to the height to be aligned. If 'Height' is gcvNULL, no height +** will be aligned. +** +** OUTPUT: +** +** gctUINT32 * Width +** Pointer to a variable that will receive the aligned width. +** +** gctUINT32 * Height +** Pointer to a variable that will receive the aligned height. +** +** gctBOOL_PTR SuperTiled +** Pointer to a variable that receives the super-tiling flag for the +** surface. +*/ +gceSTATUS +gckHARDWARE_AlignToTile( + IN gckHARDWARE Hardware, + IN gceSURF_TYPE Type, + IN OUT gctUINT32_PTR Width, + IN OUT gctUINT32_PTR Height, + OUT gctBOOL_PTR SuperTiled + ) +{ + gctBOOL superTiled = gcvFALSE; + gctUINT32 xAlignment, yAlignment; + gctBOOL hAlignmentAvailable = gcvFALSE; + + gcmkHEADER_ARG("Hardware=0x%x Type=%d *Width=%u *Height=%u", + Hardware, Type, gcmOPT_VALUE(Width), gcmOPT_VALUE(Height)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Super tiling can be enabled for render targets and depth buffers. */ + superTiled = + ((Type == gcvSURF_RENDER_TARGET) + || (Type == gcvSURF_DEPTH) + ) + && + /* Of course, hardware needs to support super tiles. */ + ((((gctUINT32) (Hardware->chipMinorFeatures0)) >> (0 ? 12:12) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))); + + /* Textures can be better aligned. */ + hAlignmentAvailable = ((((gctUINT32) (Hardware->chipMinorFeatures1)) >> (0 ? 20:20) & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 20:20) - (0 ? 20:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:20) - (0 ? 20:20) + 1))))))); + + /* Compute alignment factors. */ + xAlignment = superTiled ? 64 + : ((Type == gcvSURF_TEXTURE) && !hAlignmentAvailable) ? 4 + : 16; + yAlignment = superTiled ? (64 * Hardware->pixelPipes) + : (4 * Hardware->pixelPipes); + + if (Width != gcvNULL) + { + /* Align the width. */ + *Width = gcmALIGN(*Width, xAlignment); + } + + if (Height != gcvNULL) + { + /* Align the height. */ + *Height = gcmALIGN(*Height, yAlignment); + } + + if (SuperTiled != gcvNULL) + { + /* Copy the super tiling. */ + *SuperTiled = superTiled; + } + + /* Success. */ + gcmkFOOTER_ARG("*Width=%u *Height=%u *SuperTiled=%d", + gcmOPT_VALUE(Width), gcmOPT_VALUE(Height), + gcmOPT_VALUE(SuperTiled)); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_UpdateQueueTail +** +** Update the tail of the command queue. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Logical address of the start of the command queue. +** +** gctUINT32 Offset +** Offset into the command queue of the tail (last command). +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_UpdateQueueTail( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + IN gctUINT32 Offset + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x Offset=0x%08x", + Hardware, Logical, Offset); + + /* Verify the hardware. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Force a barrier. */ + gcmkONERROR( + gckOS_MemoryBarrier(Hardware->os, Logical)); + + /* Notify gckKERNEL object of change. */ + gcmkONERROR( + gckKERNEL_Notify(Hardware->kernel, + gcvNOTIFY_COMMAND_QUEUE, + gcvFALSE)); + + if (status == gcvSTATUS_CHIP_NOT_READY) + { + gcmkONERROR(gcvSTATUS_GPU_NOT_RESPONDING); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_ConvertLogical +** +** Convert a logical system address into a hardware specific address. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Logical address to convert. +** +** gctUINT32* Address +** Return hardware specific address. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_ConvertLogical( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical, + OUT gctUINT32 * Address + ) +{ + gctUINT32 address; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + /* Convert logical address into a physical address. */ + gcmkONERROR( + gckOS_GetPhysicalAddress(Hardware->os, Logical, &address)); + + /* Return hardware specific address. */ + *Address = ((((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))); + + /* Success. */ + gcmkFOOTER_ARG("*Address=0x%08x", *Address); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_ConvertPhysical +** +** Convert a physical address into a hardware specific address. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctPHYS_ADDR Physical +** Physical address to convert. +** +** gctUINT32* Address +** Return hardware specific address. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_ConvertPhysical( + IN gckHARDWARE Hardware, + IN gctPHYS_ADDR Physical, + OUT gctUINT32 * Address + ) +{ + gctUINT32 address; + + gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x", Hardware, Physical); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Physical != gcvNULL); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + address = gcmPTR2INT(Physical); + + /* Return hardware specific address. */ + *Address = ((((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))); + + /* Return the status. */ + gcmkFOOTER_ARG("*Address=0x%08x", *Address); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_Interrupt +** +** Process an interrupt. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gctBOOL InterruptValid +** If gcvTRUE, this function will read the interrupt acknowledge +** register, stores the data, and return whether or not the interrupt +** is ours or not. If gcvFALSE, this functions will read the interrupt +** acknowledge register and combine it with any stored value to handle +** the event notifications. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_Interrupt( + IN gckHARDWARE Hardware, + IN gctBOOL InterruptValid + ) +{ + gckEVENT eventObj; + gctUINT32 data; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x InterruptValid=%d", Hardware, InterruptValid); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Extract gckEVENT object. */ + eventObj = Hardware->kernel->eventObj; + gcmkVERIFY_OBJECT(eventObj, gcvOBJ_EVENT); + + if (InterruptValid) + { + /* Read AQIntrAcknowledge register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00010, + &data)); + + if (data & 0x80000000) + { + gcmkONERROR(gckOS_Broadcast(Hardware->os, + Hardware, + gcvBROADCAST_AXI_BUS_ERROR)); + } + + if (data == 0) + { + /* Not our interrupt. */ + status = gcvSTATUS_NOT_OUR_INTERRUPT; + } + else + { + /* Inform gckEVENT of the interrupt. */ + status = gckEVENT_Interrupt(eventObj, data & 0x7FFFFFFF); + } + } + else + { + /* Handle events. */ + status = gckEVENT_Notify(eventObj, 0); + } + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_QueryCommandBuffer +** +** Query the command buffer alignment and number of reserved bytes. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** OUTPUT: +** +** gctSIZE_T * Alignment +** Pointer to a variable receiving the alignment for each command. +** +** gctSIZE_T * ReservedHead +** Pointer to a variable receiving the number of reserved bytes at the +** head of each command buffer. +** +** gctSIZE_T * ReservedTail +** Pointer to a variable receiving the number of bytes reserved at the +** tail of each command buffer. +*/ +gceSTATUS +gckHARDWARE_QueryCommandBuffer( + IN gckHARDWARE Hardware, + OUT gctSIZE_T * Alignment, + OUT gctSIZE_T * ReservedHead, + OUT gctSIZE_T * ReservedTail + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (Alignment != gcvNULL) + { + /* Align every 8 bytes. */ + *Alignment = 8; + } + + if (ReservedHead != gcvNULL) + { + /* Reserve space for SelectPipe(). */ + *ReservedHead = 32; + } + + if (ReservedTail != gcvNULL) + { + /* Reserve space for Link(). */ + *ReservedTail = 8; + } + + /* Success. */ + gcmkFOOTER_ARG("*Alignment=%lu *ReservedHead=%lu *ReservedTail=%lu", + gcmOPT_VALUE(Alignment), gcmOPT_VALUE(ReservedHead), + gcmOPT_VALUE(ReservedTail)); + return gcvSTATUS_OK; +} + +/******************************************************************************* +** +** gckHARDWARE_QuerySystemMemory +** +** Query the command buffer alignment and number of reserved bytes. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** OUTPUT: +** +** gctSIZE_T * SystemSize +** Pointer to a variable that receives the maximum size of the system +** memory. +** +** gctUINT32 * SystemBaseAddress +** Poinetr to a variable that receives the base address for system +** memory. +*/ +gceSTATUS +gckHARDWARE_QuerySystemMemory( + IN gckHARDWARE Hardware, + OUT gctSIZE_T * SystemSize, + OUT gctUINT32 * SystemBaseAddress + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (SystemSize != gcvNULL) + { + /* Maximum system memory can be 2GB. */ + *SystemSize = 1U << 31; + } + + if (SystemBaseAddress != gcvNULL) + { + /* Set system memory base address. */ + *SystemBaseAddress = ((((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))); + } + + /* Success. */ + gcmkFOOTER_ARG("*SystemSize=%lu *SystemBaseAddress=%lu", + gcmOPT_VALUE(SystemSize), gcmOPT_VALUE(SystemBaseAddress)); + return gcvSTATUS_OK; +} + +#if !defined(VIVANTE_NO_3D) +/******************************************************************************* +** +** gckHARDWARE_QueryShaderCaps +** +** Query the shader capabilities. +** +** INPUT: +** +** Nothing. +** +** OUTPUT: +** +** gctUINT * VertexUniforms +** Pointer to a variable receiving the number of uniforms in the vertex +** shader. +** +** gctUINT * FragmentUniforms +** Pointer to a variable receiving the number of uniforms in the +** fragment shader. +** +** gctUINT * Varyings +** Pointer to a variable receiving the maimum number of varyings. +*/ +gceSTATUS +gckHARDWARE_QueryShaderCaps( + IN gckHARDWARE Hardware, + OUT gctUINT * VertexUniforms, + OUT gctUINT * FragmentUniforms, + OUT gctUINT * Varyings + ) +{ + gcmkHEADER_ARG("Hardware=0x%x VertexUniforms=0x%x " + "FragmentUniforms=0x%x Varyings=0x%x", + Hardware, VertexUniforms, + FragmentUniforms, Varyings); + + if (VertexUniforms != gcvNULL) + { + /* Return the vs shader const count. */ + if (Hardware->chipModel < gcv4000) + { + *VertexUniforms = 168; + } + else + { + *VertexUniforms = 256; + } + } + + if (FragmentUniforms != gcvNULL) + { + /* Return the ps shader const count. */ + if (Hardware->chipModel < gcv4000) + { + *FragmentUniforms = 64; + } + else + { + *FragmentUniforms = 256; + } + } + + if (Varyings != gcvNULL) + { + /* Return the shader varyings count. */ + if (((((gctUINT32) (Hardware->chipMinorFeatures1)) >> (0 ? 23:23) & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 23:23) - (0 ? 23:23) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:23) - (0 ? 23:23) + 1)))))))) + { + *Varyings = 12; + } + else + { + *Varyings = 8; + } + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; +} +#endif + +/******************************************************************************* +** +** gckHARDWARE_SetMMU +** +** Set the page table base address. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** gctPOINTER Logical +** Logical address of the page table. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_SetMMU( + IN gckHARDWARE Hardware, + IN gctPOINTER Logical + ) +{ + gceSTATUS status; + gctUINT32 address = 0; + gctUINT32 baseAddress; + + gcmkHEADER_ARG("Hardware=0x%x Logical=0x%x", Hardware, Logical); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + + /* Convert the logical address into an hardware address. */ + gcmkONERROR( + gckHARDWARE_ConvertLogical(Hardware, Logical, &address)); + + /* Also get the base address - we need a real physical address. */ + gcmkONERROR( + gckOS_GetBaseAddress(Hardware->os, &baseAddress)); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Setting page table to 0x%08X", + address + baseAddress); + + /* Write the AQMemoryFePageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00400, + address + baseAddress)); + + /* Write the AQMemoryRaPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00410, + address + baseAddress)); + +#ifndef VIVANTE_NO_3D + /* Write the AQMemoryTxPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00404, + address + baseAddress)); +#endif + + /* Write the AQMemoryPePageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00408, + address + baseAddress)); + +#ifndef VIVANTE_NO_3D + /* Write the AQMemoryPezPageTable register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0040C, + address + baseAddress)); +#endif + + /* Return the status. */ + gcmkFOOTER_NO(); + return status; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_FlushMMU +** +** Flush the page table. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_FlushMMU( + IN gckHARDWARE Hardware + ) +{ + gceSTATUS status; + gckCOMMAND command; + gctUINT32 reg, flush; + gctUINT32_PTR buffer; + gctSIZE_T bufferSize; + gctBOOL commitEntered = gcvFALSE; + gctPOINTER pointer = gcvNULL; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Flush the memory controller. */ + if (Hardware->mmuVersion == 0) + { + reg = 0x0E04; + + flush = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))); + } + else + { + reg = 0x0061; + + flush = (((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1))))))) << (0 ? 4:4))) & ((((gctUINT32) (~0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1))))))) << (0 ? 7:7))) ); + } + + /* Verify the gckCOMMAND object pointer. */ + command = Hardware->kernel->command; + + /* Acquire the command queue. */ + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); + commitEntered = gcvTRUE; + + gcmkONERROR(gckCOMMAND_Reserve( + command, 8, &pointer, &bufferSize + )); + + buffer = pointer; + + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (reg) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + buffer[1] = flush; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: FLUSH MMU(loadstate reg 0x%04x with 0x%08x)", buffer, reg, flush); + + gcmkONERROR(gckCOMMAND_Execute(command, 8)); + + /* Release the command queue. */ + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); + commitEntered = gcvFALSE; + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (commitEntered) + { + /* Release the command queue mutex. */ + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command, + gcvFALSE)); + } + + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_SetMMUv2 +** +** Set the page table base address. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_SetMMUv2( + IN gckHARDWARE Hardware, + IN gctBOOL Enable, + IN gctPOINTER MtlbAddress, + IN gceMMU_MODE Mode, + IN gctPOINTER SafeAddress + ) +{ + gceSTATUS status; + gctUINT32 config, address; + gckCOMMAND command; + gctUINT32_PTR buffer; + gctSIZE_T bufferSize; + gctBOOL commitEntered = gcvFALSE; + gctPOINTER pointer = gcvNULL; + + gcmkHEADER_ARG("Hardware=0x%x Enable=%d", Hardware, Enable); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Convert logical address into physical address. */ + gcmkONERROR( + gckOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &config)); + + gcmkONERROR( + gckOS_GetPhysicalAddress(Hardware->os, SafeAddress, &address)); + + if (address & 0x3F) + { + gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + } + + switch (Mode) + { + case gcvMMU_MODE_1K: + if (config & 0x3FF) + { + gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + } + + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + break; + + case gcvMMU_MODE_4K: + if (config & 0xFFF) + { + gcmkONERROR(gcvSTATUS_NOT_ALIGNED); + } + + config |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + + break; + + default: + gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT); + } + + /* Verify the gckCOMMAND object pointer. */ + command = Hardware->kernel->command; + + /* Acquire the command queue. */ + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvFALSE)); + commitEntered = gcvTRUE; + + gcmkONERROR(gckCOMMAND_Reserve( + command, 16, &pointer, &bufferSize + )); + + buffer = pointer; + + buffer[0] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0061) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + buffer[1] = config; + + buffer[2] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0060) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + buffer[3] = address; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Setup MMU: config=%08x, Safe Address=%08x\n.", config, address); + + gcmkONERROR(gckCOMMAND_Execute(command, 16)); + + /* Release the command queue. */ + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvFALSE)); + commitEntered = gcvFALSE; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "call gckCOMMAND_Stall to make sure the config is done.\n "); + + gcmkONERROR(gckCOMMAND_Stall(command, gcvFALSE)); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Enable MMU through GCREG_MMU_CONTROL."); + + /* Enable MMU. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0018C, + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (Enable) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))))); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "call gckCOMMAND_Stall to check MMU available.\n"); + + gcmkONERROR(gckCOMMAND_Stall(command, gcvFALSE)); + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "The MMU is available.\n"); + + /* Return the status. */ + gcmkFOOTER_NO(); + return status; + +OnError: + if (commitEntered) + { + /* Release the command queue mutex. */ + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(Hardware->kernel->command, + gcvFALSE)); + } + + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_BuildVirtualAddress +** +** Build a virtual address. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** gctUINT32 Index +** Index into page table. +** +** gctUINT32 Offset +** Offset into page. +** +** OUTPUT: +** +** gctUINT32 * Address +** Pointer to a variable receiving te hardware address. +*/ +gceSTATUS +gckHARDWARE_BuildVirtualAddress( + IN gckHARDWARE Hardware, + IN gctUINT32 Index, + IN gctUINT32 Offset, + OUT gctUINT32 * Address + ) +{ + gcmkHEADER_ARG("Hardware=0x%x Index=%u Offset=%u", Hardware, Index, Offset); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Address != gcvNULL); + + /* Build virtual address. */ + *Address = ((((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) (0x1 & ((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) (Offset | (Index << 12)) & ((gctUINT32) ((((1 ? 30:0) - (0 ? 30:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 30:0) - (0 ? 30:0) + 1))))))) << (0 ? 30:0))); + + /* Success. */ + gcmkFOOTER_ARG("*Address=0x%08x", *Address); + return gcvSTATUS_OK; +} + +gceSTATUS +gckHARDWARE_GetIdle( + IN gckHARDWARE Hardware, + IN gctBOOL Wait, + OUT gctUINT32 * Data + ) +{ + gceSTATUS status; + gctUINT32 idle = 0; + gctINT retry, poll, pollCount; + + gcmkHEADER_ARG("Hardware=0x%x Wait=%d", Hardware, Wait); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(Data != gcvNULL); + + + /* If we have to wait, try 100 polls per millisecond. */ + pollCount = Wait ? 100 : 1; + + /* At most, try for 1 second. */ + for (retry = 0; retry < 1000; ++retry) + { + /* If we have to wait, try 100 polls per millisecond. */ + for (poll = pollCount; poll > 0; --poll) + { + /* Read register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle)); + + /* See if we have to wait for FE idle. */ + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + /* FE is idle. */ + break; + } + } + + /* Check if we need to wait for FE and FE is busy. */ + if (Wait && !(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + /* Wait a little. */ + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "%s: Waiting for idle: 0x%08X", + __FUNCTION__, idle); + + gcmkVERIFY_OK(gckOS_Delay(Hardware->os, 1)); + } + else + { + break; + } + } + + /* Return idle to caller. */ + *Data = idle; + + /* Success. */ + gcmkFOOTER_ARG("*Data=0x%08x", *Data); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/* Flush the caches. */ +gceSTATUS +gckHARDWARE_Flush( + IN gckHARDWARE Hardware, + IN gceKERNEL_FLUSH Flush, + IN gctPOINTER Logical, + IN OUT gctSIZE_T * Bytes + ) +{ + gctUINT32 pipe; + gctUINT32 flush = 0; + gctUINT32_PTR logical = (gctUINT32_PTR) Logical; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Flush=0x%x Logical=0x%x *Bytes=%lu", + Hardware, Flush, Logical, gcmOPT_VALUE(Bytes)); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Get current pipe. */ + pipe = Hardware->kernel->command->pipeSelect; + + /* Flush 3D color cache. */ + if ((Flush & gcvFLUSH_COLOR) && (pipe == 0x0)) + { + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))); + } + + /* Flush 3D depth cache. */ + if ((Flush & gcvFLUSH_DEPTH) && (pipe == 0x0)) + { + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))); + } + + /* Flush 3D texture cache. */ + if ((Flush & gcvFLUSH_TEXTURE) && (pipe == 0x0)) + { + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1))))))) << (0 ? 2:2))); + } + + /* Flush 2D cache. */ + if ((Flush & gcvFLUSH_2D) && (pipe == 0x1)) + { + flush |= ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1))))))) << (0 ? 3:3))); + } + + /* See if there is a valid flush. */ + if (flush == 0) + { + if (Bytes != gcvNULL) + { + /* No bytes required. */ + *Bytes = 0; + } + } + + else + { + /* Copy to command queue. */ + if (Logical != gcvNULL) + { + if (*Bytes < 8) + { + /* Command queue too small. */ + gcmkONERROR(gcvSTATUS_BUFFER_TOO_SMALL); + } + + /* Append LOAD_STATE to AQFlush. */ + logical[0] = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) | (((gctUINT32) ((gctUINT32) (0x0E03) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 25:16) - (0 ? 25:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16))); + + logical[1] = flush; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "0x%x: FLUSH 0x%x", logical, flush); + } + + if (Bytes != gcvNULL) + { + /* 8 bytes required. */ + *Bytes = 8; + } + } + + /* Success. */ + gcmkFOOTER_ARG("*Bytes=%lu", gcmOPT_VALUE(Bytes)); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckHARDWARE_SetFastClear( + IN gckHARDWARE Hardware, + IN gctINT Enable, + IN gctINT Compression + ) +{ +#ifndef VIVANTE_NO_3D + gctUINT32 debug; + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x Enable=%d Compression=%d", + Hardware, Enable, Compression); + + /* Only process if fast clear is available. */ + if ((((((gctUINT32) (Hardware->chipFeatures)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) )) + { + if (Enable == -1) + { + /* Determine automatic value for fast clear. */ + Enable = ((Hardware->chipModel != gcv500) + || (Hardware->chipRevision >= 3) + ) ? 1 : 0; + } + + if (Compression == -1) + { + /* Determine automatic value for compression. */ + Compression = Enable + & (((((gctUINT32) (Hardware->chipFeatures)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ); + } + + /* Read AQMemoryDebug register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00414, &debug)); + + /* 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))); + + /* Write back AQMemoryDebug register. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00414, + debug)); + + /* Store fast clear and comprersison flags. */ + Hardware->allowFastClear = Enable; + Hardware->allowCompression = Compression; + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "FastClear=%d Compression=%d", Enable, Compression); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +#else + return gcvSTATUS_OK; +#endif +} + +typedef enum +{ + gcvPOWER_FLAG_INITIALIZE = 1 << 0, + gcvPOWER_FLAG_STALL = 1 << 1, + gcvPOWER_FLAG_STOP = 1 << 2, + gcvPOWER_FLAG_START = 1 << 3, + gcvPOWER_FLAG_RELEASE = 1 << 4, + gcvPOWER_FLAG_DELAY = 1 << 5, + gcvPOWER_FLAG_SAVE = 1 << 6, + gcvPOWER_FLAG_ACQUIRE = 1 << 7, + gcvPOWER_FLAG_POWER_OFF = 1 << 8, + gcvPOWER_FLAG_CLOCK_OFF = 1 << 9, + gcvPOWER_FLAG_CLOCK_ON = 1 << 10, +} +gcePOWER_FLAGS; + +#if gcmIS_DEBUG(gcdDEBUG_TRACE) && gcdPOWER_MANAGEMENT +static gctCONST_STRING +_PowerEnum(gceCHIPPOWERSTATE State) +{ + const gctCONST_STRING states[] = + { + gcmSTRING(gcvPOWER_ON), + gcmSTRING(gcvPOWER_OFF), + gcmSTRING(gcvPOWER_IDLE), + gcmSTRING(gcvPOWER_SUSPEND), + gcmSTRING(gcvPOWER_SUSPEND_ATPOWERON), + gcmSTRING(gcvPOWER_OFF_ATPOWERON), + gcmSTRING(gcvPOWER_IDLE_BROADCAST), + gcmSTRING(gcvPOWER_SUSPEND_BROADCAST), + gcmSTRING(gcvPOWER_OFF_BROADCAST), + gcmSTRING(gcvPOWER_OFF_RECOVERY), + gcmSTRING(gcvPOWER_ON_AUTO) + }; + + if ((State >= gcvPOWER_ON) && (State <= gcvPOWER_ON_AUTO)) + { + return states[State - gcvPOWER_ON]; + } + + return "unknown"; +} +#endif + +/******************************************************************************* +** +** gckHARDWARE_SetPowerManagementState +** +** Set GPU to a specified power state. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** gceCHIPPOWERSTATE State +** Power State. +** +*/ +gceSTATUS +gckHARDWARE_SetPowerManagementState( + IN gckHARDWARE Hardware, + IN gceCHIPPOWERSTATE State + ) +{ +#if gcdPOWER_MANAGEMENT + gceSTATUS status; + gckCOMMAND command = gcvNULL; + gckOS os; + gctUINT flag, clock; + gctPOINTER buffer; + gctSIZE_T bytes, requested; + gctBOOL acquired = gcvFALSE; + gctBOOL mutexAcquired = gcvFALSE; + gctBOOL stall = gcvTRUE; + gctBOOL broadcast = gcvFALSE; +#if gcdPOWEROFF_TIMEOUT + gctBOOL timeout = gcvFALSE; + gctBOOL isAfter = gcvFALSE; + gctUINT32 currentTime; +#endif + gctUINT32 process, thread; + gctBOOL commitEntered = gcvFALSE; +#if gcdENABLE_PROFILING + gctUINT64 time, freq, mutexTime, onTime, stallTime, stopTime, delayTime, + initTime, offTime, startTime, totalTime; +#endif + gctBOOL global = gcvFALSE; + gctBOOL globalAcquired = gcvFALSE; + + /* State transition flags. */ + static const gctUINT flags[4][4] = + { + /* gcvPOWER_ON */ + { /* ON */ 0, + /* OFF */ gcvPOWER_FLAG_ACQUIRE | + gcvPOWER_FLAG_STALL | + gcvPOWER_FLAG_STOP | + gcvPOWER_FLAG_POWER_OFF | + gcvPOWER_FLAG_CLOCK_OFF, + /* IDLE */ gcvPOWER_FLAG_ACQUIRE | + gcvPOWER_FLAG_STALL, + /* SUSPEND */ gcvPOWER_FLAG_ACQUIRE | + gcvPOWER_FLAG_STALL | + gcvPOWER_FLAG_STOP | + gcvPOWER_FLAG_CLOCK_OFF, + }, + + /* gcvPOWER_OFF */ + { /* ON */ gcvPOWER_FLAG_INITIALIZE | + gcvPOWER_FLAG_START | + gcvPOWER_FLAG_RELEASE | + gcvPOWER_FLAG_DELAY, + /* OFF */ 0, + /* IDLE */ gcvPOWER_FLAG_INITIALIZE | + gcvPOWER_FLAG_START | + gcvPOWER_FLAG_DELAY, + /* SUSPEND */ gcvPOWER_FLAG_INITIALIZE | + gcvPOWER_FLAG_CLOCK_OFF, + }, + + /* gcvPOWER_IDLE */ + { /* ON */ gcvPOWER_FLAG_RELEASE, + /* OFF */ gcvPOWER_FLAG_STOP | + gcvPOWER_FLAG_POWER_OFF | + gcvPOWER_FLAG_CLOCK_OFF, + /* IDLE */ 0, + /* SUSPEND */ gcvPOWER_FLAG_STOP | + gcvPOWER_FLAG_CLOCK_OFF, + }, + + /* gcvPOWER_SUSPEND */ + { /* ON */ gcvPOWER_FLAG_START | + gcvPOWER_FLAG_RELEASE | + gcvPOWER_FLAG_DELAY | + gcvPOWER_FLAG_CLOCK_ON, + /* OFF */ gcvPOWER_FLAG_SAVE | + gcvPOWER_FLAG_POWER_OFF | + gcvPOWER_FLAG_CLOCK_OFF, + /* IDLE */ gcvPOWER_FLAG_START | + gcvPOWER_FLAG_DELAY | + gcvPOWER_FLAG_CLOCK_ON, + /* SUSPEND */ 0, + }, + }; + + /* Clocks. */ + static const gctUINT clocks[4] = + { + /* gcvPOWER_ON */ + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (64) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))), + + /* gcvPOWER_OFF */ + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))), + + /* gcvPOWER_IDLE */ + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))), + + /* gcvPOWER_SUSPEND */ + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1))))))) << (0 ? 1:1))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:2) - (0 ? 8:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:2) - (0 ? 8:2) + 1))))))) << (0 ? 8:2))) | + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))), + }; + + gcmkHEADER_ARG("Hardware=0x%x State=%d", Hardware, State); +#if gcmIS_DEBUG(gcdDEBUG_TRACE) + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Switching to power state %d(%s)", + State, _PowerEnum(State)); +#endif + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Get the gckOS object pointer. */ + os = Hardware->os; + gcmkVERIFY_OBJECT(os, gcvOBJ_OS); + + /* Get the gckCOMMAND object pointer. */ + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL); + command = Hardware->kernel->command; + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); + + /* Start profiler. */ + gcmkPROFILE_INIT(freq, time); + + /* Convert the broadcast power state. */ + switch (State) + { + case gcvPOWER_SUSPEND_ATPOWERON: + /* Convert to SUSPEND and don't wait for STALL. */ + State = gcvPOWER_SUSPEND; + stall = gcvFALSE; + break; + + case gcvPOWER_OFF_ATPOWERON: + /* Convert to OFF and don't wait for STALL. */ + State = gcvPOWER_OFF; + stall = gcvFALSE; + break; + + case gcvPOWER_IDLE_BROADCAST: + /* Convert to IDLE and note we are inside broadcast. */ + State = gcvPOWER_IDLE; + broadcast = gcvTRUE; + break; + + case gcvPOWER_SUSPEND_BROADCAST: + /* Convert to SUSPEND and note we are inside broadcast. */ + State = gcvPOWER_SUSPEND; + broadcast = gcvTRUE; + break; + + case gcvPOWER_OFF_BROADCAST: + /* Convert to OFF and note we are inside broadcast. */ + State = gcvPOWER_OFF; + broadcast = gcvTRUE; + break; + + case gcvPOWER_OFF_RECOVERY: + /* Convert to OFF and note we are inside recovery. */ + State = gcvPOWER_OFF; + stall = gcvFALSE; + broadcast = gcvTRUE; + break; + + case gcvPOWER_ON_AUTO: + /* Convert to ON and note we are inside recovery. */ + State = gcvPOWER_ON; + break; + + case gcvPOWER_ON: + case gcvPOWER_IDLE: + case gcvPOWER_SUSPEND: + case gcvPOWER_OFF: + /* Mark as global power management. */ + global = gcvTRUE; + break; + +#if gcdPOWEROFF_TIMEOUT + case gcvPOWER_OFF_TIMEOUT: + /* Convert to OFF and note we are inside broadcast. */ + State = gcvPOWER_OFF; + broadcast = gcvTRUE; + /* Check time out */ + timeout = gcvTRUE; + break; +#endif + + default: + break; + } + + /* Get current process and thread IDs. */ + gcmkONERROR(gckOS_GetProcessID(&process)); + gcmkONERROR(gckOS_GetThreadID(&thread)); + + if (broadcast) + { + /* Try to acquire the power mutex. */ + status = gckOS_AcquireMutex(os, Hardware->powerMutex, 0); + + if (status == gcvSTATUS_TIMEOUT) + { + /* Check if we already own this mutex. */ + if ((Hardware->powerProcess == process) + && (Hardware->powerThread == thread) + ) + { + /* Bail out on recursive power management. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + else if (State == gcvPOWER_IDLE) + { + /* gcvPOWER_IDLE_BROADCAST is from IST, + ** so waiting here will cause deadlock, + ** if lock holder call gckCOMMAND_Stall() */ + gcmkONERROR(gcvSTATUS_INVALID_REQUEST); + } + else + { + /* Acquire the power mutex. */ + gcmkONERROR(gckOS_AcquireMutex(os, + Hardware->powerMutex, + gcvINFINITE)); + } + } + } + else + { + /* Acquire the power mutex. */ + gcmkONERROR(gckOS_AcquireMutex(os, Hardware->powerMutex, gcvINFINITE)); + } + + /* Get time until mtuex acquired. */ + gcmkPROFILE_QUERY(time, mutexTime); + + Hardware->powerProcess = process; + Hardware->powerThread = thread; + mutexAcquired = gcvTRUE; + + /* Grab control flags and clock. */ + flag = flags[Hardware->chipPowerState][State]; + clock = clocks[State]; + +#if gcdPOWEROFF_TIMEOUT + if (timeout) + { + gcmkONERROR(gckOS_GetTicks(¤tTime)); + + gcmkONERROR( + gckOS_TicksAfter(Hardware->powerOffTime, currentTime, &isAfter)); + + if (isAfter || Hardware->chipPowerState != gcvPOWER_IDLE) + { + /* Release the power mutex. */ + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); + + /* No need to do anything. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Power Off GPU at %i [supposed to be at %i]", + currentTime, Hardware->powerOffTime); + } +#endif + + if (flag == 0) + { + /* Release the power mutex. */ + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); + + /* No need to do anything. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + } + + /* If this is an internal power management, we have to check if we can grab + ** the global power semaphore. If we cannot, we have to wait until the + ** external world changes power management. */ + if (!global) + { + /* Try to acquire the global semaphore. */ + status = gckOS_TryAcquireSemaphore(os, Hardware->globalSemaphore); + if (status == gcvSTATUS_TIMEOUT) + { + /* Release the power mutex. */ + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Releasing the power mutex."); + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); + mutexAcquired = gcvFALSE; + + /* Wait for the semaphore. */ + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Waiting for global semaphore."); + gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore)); + globalAcquired = gcvTRUE; + + /* Acquire the power mutex. */ + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "Reacquiring the power mutex."); + gcmkONERROR(gckOS_AcquireMutex(os, + Hardware->powerMutex, + gcvINFINITE)); + mutexAcquired = gcvTRUE; + } + else + { + /* Error. */ + gcmkONERROR(status); + } + + /* Release the global semaphore again. */ + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore)); + globalAcquired = gcvFALSE; + } + + if (flag & (gcvPOWER_FLAG_INITIALIZE | gcvPOWER_FLAG_CLOCK_ON)) + { + /* Turn on the power. */ + gcmkONERROR(gckOS_SetGPUPower(os, gcvTRUE, gcvTRUE)); + + /* Mark clock and power as enabled. */ + Hardware->clockState = gcvTRUE; + Hardware->powerState = gcvTRUE; + } + + /* Get time until powered on. */ + gcmkPROFILE_QUERY(time, onTime); + + if ((flag & gcvPOWER_FLAG_STALL) && stall) + { + gctBOOL idle; + gctINT32 atomValue; + + /* Check commit atom. */ + gcmkONERROR(gckOS_AtomGet(os, command->atomCommit, &atomValue)); + + if (atomValue > 0) + { + /* Commits are pending - abort power management. */ + status = broadcast ? gcvSTATUS_CHIP_NOT_READY + : gcvSTATUS_MORE_DATA; + goto OnError; + } + + if (broadcast) + { + /* Check for idle. */ + gcmkONERROR(gckHARDWARE_QueryIdle(Hardware, &idle)); + + if (!idle) + { + status = gcvSTATUS_CHIP_NOT_READY; + goto OnError; + } + } + + else + { + /* Acquire the command queue. */ + gcmkONERROR(gckCOMMAND_EnterCommit(command, gcvTRUE)); + commitEntered = gcvTRUE; + + /* Get the size of the flush command. */ + gcmkONERROR(gckHARDWARE_Flush(Hardware, + gcvFLUSH_ALL, + gcvNULL, + &requested)); + + /* Reserve space in the command queue. */ + gcmkONERROR(gckCOMMAND_Reserve(command, + requested, + &buffer, + &bytes)); + + /* Append a flush. */ + gcmkONERROR(gckHARDWARE_Flush( + Hardware, gcvFLUSH_ALL, buffer, &bytes + )); + + /* Execute the command queue. */ + gcmkONERROR(gckCOMMAND_Execute(command, requested)); + + /* Release the command queue. */ + gcmkONERROR(gckCOMMAND_ExitCommit(command, gcvTRUE)); + commitEntered = gcvFALSE; + + /* Wait to finish all commands. */ + gcmkONERROR(gckCOMMAND_Stall(command, gcvTRUE)); + } + } + + /* Get time until stalled. */ + gcmkPROFILE_QUERY(time, stallTime); + + if (flag & gcvPOWER_FLAG_ACQUIRE) + { + /* Acquire the power management semaphore. */ + gcmkONERROR(gckOS_AcquireSemaphore(os, command->powerSemaphore)); + acquired = gcvTRUE; + + if (global) + { + /* Acquire the global semaphore. */ + gcmkONERROR(gckOS_AcquireSemaphore(os, Hardware->globalSemaphore)); + globalAcquired = gcvTRUE; + } + } + + if (flag & gcvPOWER_FLAG_STOP) + { + /* Stop the command parser. */ + gcmkONERROR(gckCOMMAND_Stop(command)); + + /* Stop the Isr. */ + gcmkONERROR(Hardware->stopIsr(Hardware->isrContext)); + } + + /* Get time until stopped. */ + gcmkPROFILE_QUERY(time, stopTime); + + /* Only process this when hardware is enabled. */ + if (Hardware->clockState && Hardware->powerState) + { + /* Write the clock control register. */ + gcmkONERROR(gckOS_WriteRegisterEx(os, + Hardware->core, + 0x00000, + clock)); + + /* Done loading the frequency scaler. */ + gcmkONERROR(gckOS_WriteRegisterEx(os, + Hardware->core, + 0x00000, + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1))))))) << (0 ? 9:9))))); + } + + if (flag & gcvPOWER_FLAG_DELAY) + { + /* Wait for the specified amount of time to settle coming back from + ** power-off or suspend state. */ + gcmkONERROR(gckOS_Delay(os, gcdPOWER_CONTROL_DELAY)); + } + + /* Get time until delayed. */ + gcmkPROFILE_QUERY(time, delayTime); + + if (flag & gcvPOWER_FLAG_INITIALIZE) + { + /* Initialize hardware. */ + gcmkONERROR(gckHARDWARE_InitializeHardware(Hardware)); + + gcmkONERROR(gckHARDWARE_SetFastClear(Hardware, + Hardware->allowFastClear, + Hardware->allowCompression)); + + /* Force the command queue to reload the next context. */ + command->currContext = gcvNULL; + } + + /* Get time until initialized. */ + gcmkPROFILE_QUERY(time, initTime); + + if (flag & (gcvPOWER_FLAG_POWER_OFF | gcvPOWER_FLAG_CLOCK_OFF)) + { + /* Turn off the GPU power. */ + gcmkONERROR( + gckOS_SetGPUPower(os, + (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE + : gcvTRUE, + (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE + : gcvTRUE)); + + /* Save current hardware power and clock states. */ + Hardware->clockState = (flag & gcvPOWER_FLAG_CLOCK_OFF) ? gcvFALSE + : gcvTRUE; + Hardware->powerState = (flag & gcvPOWER_FLAG_POWER_OFF) ? gcvFALSE + : gcvTRUE; + } + + /* Get time until off. */ + gcmkPROFILE_QUERY(time, offTime); + + if (flag & gcvPOWER_FLAG_START) + { + /* Start the command processor. */ + gcmkONERROR(gckCOMMAND_Start(command)); + + /* Start the Isr. */ + gcmkONERROR(Hardware->startIsr(Hardware->isrContext)); + } + + /* Get time until started. */ + gcmkPROFILE_QUERY(time, startTime); + + if (flag & gcvPOWER_FLAG_RELEASE) + { + /* Release the power management semaphore. */ + gcmkONERROR(gckOS_ReleaseSemaphore(os, command->powerSemaphore)); + acquired = gcvFALSE; + + if (global) + { + /* Release the global semaphore. */ + gcmkONERROR(gckOS_ReleaseSemaphore(os, Hardware->globalSemaphore)); + globalAcquired = gcvFALSE; + } + } + + /* Save the new power state. */ + Hardware->chipPowerState = State; + +#if gcdPOWEROFF_TIMEOUT + /* Reset power off time */ + gcmkONERROR(gckOS_GetTicks(¤tTime)); + + Hardware->powerOffTime = currentTime + gcdPOWEROFF_TIMEOUT; + + if (State == gcvPOWER_IDLE) + { + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerOffSema)); + } +#endif + + /* Release the power mutex. */ + gcmkONERROR(gckOS_ReleaseMutex(os, Hardware->powerMutex)); + + /* Get total time. */ + gcmkPROFILE_QUERY(time, totalTime); +#if gcdENABLE_PROFILING + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + "PROF(%llu): mutex:%llu on:%llu stall:%llu stop:%llu", + freq, mutexTime, onTime, stallTime, stopTime); + gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, + " delay:%llu init:%llu off:%llu start:%llu total:%llu", + delayTime, initTime, offTime, startTime, totalTime); +#endif + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (commitEntered) + { + /* Release the command queue mutex. */ + gcmkVERIFY_OK(gckCOMMAND_ExitCommit(command, gcvTRUE)); + } + + if (acquired) + { + /* Release semaphore. */ + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os, + command->powerSemaphore)); + } + + if (globalAcquired) + { + gcmkVERIFY_OK(gckOS_ReleaseSemaphore(Hardware->os, + Hardware->globalSemaphore)); + } + + if (mutexAcquired) + { + gcmkVERIFY_OK(gckOS_ReleaseMutex(Hardware->os, Hardware->powerMutex)); + } + + /* Return the status. */ + gcmkFOOTER(); + return status; +#else /* gcdPOWER_MANAGEMENT */ + /* Do nothing */ + return gcvSTATUS_OK; +#endif +} + +/******************************************************************************* +** +** gckHARDWARE_QueryPowerManagementState +** +** Get GPU power state. +** +** INPUT: +** +** gckHARDWARE Harwdare +** Pointer to an gckHARDWARE object. +** +** gceCHIPPOWERSTATE* State +** Power State. +** +*/ +gceSTATUS +gckHARDWARE_QueryPowerManagementState( + IN gckHARDWARE Hardware, + OUT gceCHIPPOWERSTATE* State + ) +{ + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(State != gcvNULL); + + /* Return the statue. */ + *State = Hardware->chipPowerState; + + /* Success. */ + gcmkFOOTER_ARG("*State=%d", *State); + return gcvSTATUS_OK; +} + +gceSTATUS +gckHARDWARE_QueryIdle( + IN gckHARDWARE Hardware, + OUT gctBOOL_PTR IsIdle + ) +{ + gceSTATUS status; + gctUINT32 idle, address; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(IsIdle != gcvNULL); + + /* We are idle when the power is not ON. */ + if (Hardware->chipPowerState != gcvPOWER_ON) + { + *IsIdle = gcvTRUE; + } + + else + { + /* Read idle register. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00004, &idle)); + + /* Pipe must be idle. */ + if (((((((gctUINT32) (idle)) >> (0 ? 1:1)) & ((gctUINT32) ((((1 ? 1:1) - (0 ? 1:1) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:1) - (0 ? 1:1) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 3:3)) & ((gctUINT32) ((((1 ? 3:3) - (0 ? 3:3) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:3) - (0 ? 3:3) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 4:4)) & ((gctUINT32) ((((1 ? 4:4) - (0 ? 4:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 4:4) - (0 ? 4:4) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 5:5)) & ((gctUINT32) ((((1 ? 5:5) - (0 ? 5:5) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:5) - (0 ? 5:5) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 6:6)) & ((gctUINT32) ((((1 ? 6:6) - (0 ? 6:6) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 6:6) - (0 ? 6:6) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 7:7)) & ((gctUINT32) ((((1 ? 7:7) - (0 ? 7:7) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 7:7) - (0 ? 7:7) + 1)))))) ) != 1) + || ((((((gctUINT32) (idle)) >> (0 ? 2:2)) & ((gctUINT32) ((((1 ? 2:2) - (0 ? 2:2) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 2:2) - (0 ? 2:2) + 1)))))) ) != 1) + ) + { + /* Something is busy. */ + *IsIdle = gcvFALSE; + } + + else + { + /* Read the current FE address. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00664, + &address)); + + /* Test if address is inside the last WAIT/LINK sequence. */ + if ((address >= Hardware->lastWaitLink) + && (address <= Hardware->lastWaitLink + 16) + ) + { + /* FE is in last WAIT/LINK and the pipe is idle. */ + *IsIdle = gcvTRUE; + } + else + { + /* FE is not in WAIT/LINK yet. */ + *IsIdle = gcvFALSE; + } + } + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +/******************************************************************************* +** Handy macros that will help in reading those debug registers. +*/ + +#define gcmkREAD_DEBUG_REGISTER(control, block, index, data) \ + gcmkONERROR(\ + gckOS_WriteRegisterEx(Hardware->os, \ + Hardware->core, \ + GC_DEBUG_CONTROL##control##_Address, \ + gcmSETFIELD(0, \ + GC_DEBUG_CONTROL##control, \ + block, \ + index))); \ + gcmkONERROR(\ + gckOS_ReadRegisterEx(Hardware->os, \ + Hardware->core, \ + GC_DEBUG_SIGNALS_##block##_Address, \ + &profiler->data)) + +#define gcmkRESET_DEBUG_REGISTER(control, block) \ + gcmkONERROR(\ + gckOS_WriteRegisterEx(Hardware->os, \ + Hardware->core, \ + GC_DEBUG_CONTROL##control##_Address, \ + gcmSETFIELD(0, \ + GC_DEBUG_CONTROL##control, \ + block, \ + 15))); \ + gcmkONERROR(\ + gckOS_WriteRegisterEx(Hardware->os, \ + Hardware->core, \ + GC_DEBUG_CONTROL##control##_Address, \ + gcmSETFIELD(0, \ + GC_DEBUG_CONTROL##control, \ + block, \ + 0))) + +/******************************************************************************* +** +** gckHARDWARE_ProfileEngine2D +** +** Read the profile registers available in the 2D engine and sets them in the +** profile. The function will also reset the pixelsRendered counter every time. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** OPTIONAL gcs2D_PROFILE_PTR Profile +** Pointer to a gcs2D_Profile structure. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_ProfileEngine2D( + IN gckHARDWARE Hardware, + OPTIONAL gcs2D_PROFILE_PTR Profile + ) +{ + gceSTATUS status; + gcs2D_PROFILE_PTR profiler = Profile; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (Profile != gcvNULL) + { + /* Read the cycle count. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00438, + &Profile->cycleCount)); + + /* Read pixels rendered by 2D engine. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pixelsRendered)); + + /* Reset counter. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) +))); + } + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +#if VIVANTE_PROFILER +gceSTATUS +gckHARDWARE_QueryProfileRegisters( + IN gckHARDWARE Hardware, + OUT gcsPROFILER_COUNTERS * Counters + ) +{ + gceSTATUS status; + gcsPROFILER_COUNTERS * profiler = Counters; + + gcmkHEADER_ARG("Hardware=0x%x Counters=0x%x", Hardware, Counters); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Read the counters. */ + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00040, + &profiler->gpuTotalRead64BytesPerFrame)); + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00044, + &profiler->gpuTotalWrite64BytesPerFrame)); + gcmkONERROR( + gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00438, + &profiler->gpuCyclesCounter)); + + /* Reset counters. */ + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 1)); + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x0003C, 0)); + gcmkONERROR( + gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00438, 0)); + + /* PE */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_killed_by_color_pipe)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_killed_by_depth_pipe)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_drawn_by_color_pipe)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00454, &profiler->pe_pixel_count_drawn_by_depth_pipe)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) +))); + + /* SH */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->ps_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_pixel_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vs_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->rendered_vertice_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (11) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_branch_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (12) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->vtx_texld_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (13) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_branch_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (14) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0045C, &profiler->pxl_texld_inst_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00470, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) +))); + + /* PA */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_vtx_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (4) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_input_prim_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_output_prim_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_depth_clipped_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_trivial_rejected_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00460, &profiler->pa_culled_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) +))); + + /* SE */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_triangle_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00464, &profiler->se_culled_lines_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) +))); + + /* RA */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_pixel_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_quad_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_valid_quad_count_after_early_z)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_total_primitive_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_pipe_cache_miss_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (10) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00448, &profiler->ra_prefetch_cache_miss_counter)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:16) - (0 ? 19:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:16) - (0 ? 19:16) + 1))))))) << (0 ? 19:16))) +))); + + /* TX */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_bilinear_requests)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_trilinear_requests)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_discarded_texture_requests)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_total_texture_requests)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (5) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (6) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_mem_read_in_8B_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (7) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (8) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_hit_texel_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (9) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0044C, &profiler->tx_cache_miss_texel_count)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00474, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 27:24) - (0 ? 27:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:24) - (0 ? 27:24) + 1))))))) << (0 ? 27:24))) +))); + + /* MC */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_pipeline)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_read_req_8B_from_IP)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (3) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x00468, &profiler->mc_total_write_req_8B_from_pipeline)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 3:0) - (0 ? 3:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 3:0) - (0 ? 3:0) + 1))))))) << (0 ? 3:0))) +))); + + /* HI */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_read_request_stalled)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_request_stalled)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (2) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, Hardware->core, 0x0046C, &profiler->hi_axi_cycles_write_data_stalled)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (15) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) ))); +gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, 0x00478, (((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 11:8) - (0 ? 11:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 11:8) - (0 ? 11:8) + 1))))))) << (0 ? 11:8))) +))); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} +#endif + +static gceSTATUS +_ResetGPU( + IN gckOS Os, + IN gceCORE Core + ) +{ + gctUINT32 control, idle; + gceSTATUS status; + + /* Read register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Os, + Core, + 0x00000, + &control)); + + for (;;) + { + /* Isolate the GPU. */ + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))); + + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x00000, + control)); + + /* Set soft reset. */ + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x00000, + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))))); + + /* Wait for reset. */ + gcmkONERROR(gckOS_Delay(Os, 1)); + + /* Reset soft reset bit. */ + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x00000, + ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))))); + + /* Reset GPU isolation. */ + control = ((((gctUINT32) (control)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ? 19:19) - (0 ? 19:19) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 19:19) - (0 ? 19:19) + 1))))))) << (0 ? 19:19))); + + gcmkONERROR(gckOS_WriteRegisterEx(Os, + Core, + 0x00000, + control)); + + /* Read idle register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Os, + Core, + 0x00004, + &idle)); + + if ((((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ) == 0) + { + continue; + } + + /* Read reset register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Os, + Core, + 0x00000, + &control)); + + if (((((((gctUINT32) (control)) >> (0 ? 16:16)) & ((gctUINT32) ((((1 ? 16:16) - (0 ? 16:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 16:16) - (0 ? 16:16) + 1)))))) ) == 0) + || ((((((gctUINT32) (control)) >> (0 ? 17:17)) & ((gctUINT32) ((((1 ? 17:17) - (0 ? 17:17) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 17:17) - (0 ? 17:17) + 1)))))) ) == 0) + ) + { + continue; + } + + /* GPU is idle. */ + break; + } + + /* Success. */ + return gcvSTATUS_OK; + +OnError: + + /* Return the error. */ + return status; +} + +gceSTATUS +gckHARDWARE_Reset( + IN gckHARDWARE Hardware + ) +{ + gceSTATUS status; + gckCOMMAND command; + gctBOOL acquired = gcvFALSE; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_OBJECT(Hardware->kernel, gcvOBJ_KERNEL); + command = Hardware->kernel->command; + gcmkVERIFY_OBJECT(command, gcvOBJ_COMMAND); + + if (Hardware->chipRevision < 0x4600) + { + /* Not supported - we need the isolation bit. */ + gcmkONERROR(gcvSTATUS_NOT_SUPPORTED); + } + + if (Hardware->chipPowerState == gcvPOWER_ON) + { + /* Acquire the power management semaphore. */ + gcmkONERROR( + gckOS_AcquireSemaphore(Hardware->os, command->powerSemaphore)); + acquired = gcvTRUE; + } + + if ((Hardware->chipPowerState == gcvPOWER_ON) + || (Hardware->chipPowerState == gcvPOWER_IDLE) + ) + { + /* Stop the command processor. */ + gcmkONERROR(gckCOMMAND_Stop(command)); + } + + gcmkONERROR(_ResetGPU(Hardware->os, Hardware->core)); + + /* Force an OFF to ON power switch. */ + Hardware->chipPowerState = gcvPOWER_OFF; + gcmkONERROR(gckHARDWARE_SetPowerManagementState(Hardware, gcvPOWER_ON)); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + if (acquired) + { + /* Release the power management semaphore. */ + gcmkVERIFY_OK( + gckOS_ReleaseSemaphore(Hardware->os, command->powerSemaphore)); + } + + /* Return the error. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckHARDWARE_GetBaseAddress( + IN gckHARDWARE Hardware, + OUT gctUINT32_PTR BaseAddress + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(BaseAddress != gcvNULL); + + /* Test if we have a new Memory Controller. */ + if (((((gctUINT32) (Hardware->chipMinorFeatures0)) >> (0 ? 22:22) & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))) == (0x1 & ((gctUINT32) ((((1 ? 22:22) - (0 ? 22:22) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 22:22) - (0 ? 22:22) + 1)))))))) + { + /* No base address required. */ + *BaseAddress = 0; + } + else + { + /* Get the base address from the OS. */ + gcmkONERROR(gckOS_GetBaseAddress(Hardware->os, BaseAddress)); + } + + /* Success. */ + gcmkFOOTER_ARG("*BaseAddress=0x%08x", *BaseAddress); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckHARDWARE_NeedBaseAddress( + IN gckHARDWARE Hardware, + IN gctUINT32 State, + OUT gctBOOL_PTR NeedBase + ) +{ + gctBOOL need = gcvFALSE; + + gcmkHEADER_ARG("Hardware=0x%x State=0x%08x", Hardware, State); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT(NeedBase != gcvNULL); + + /* Make sure this is a load state. */ + if (((((gctUINT32) (State)) >> (0 ? 31:27) & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ? 31:27) - (0 ? 31:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 31:27) - (0 ? 31:27) + 1)))))))) + { +#ifndef VIVANTE_NO_3D + /* Get the state address. */ + switch ((((((gctUINT32) (State)) >> (0 ? 15:0)) & ((gctUINT32) ((((1 ? 15:0) - (0 ? 15:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 15:0) - (0 ? 15:0) + 1)))))) )) + { + case 0x0596: + case 0x0597: + case 0x0599: + case 0x059A: + case 0x05A9: + /* These states need a TRUE physical address. */ + need = gcvTRUE; + break; + } +#else + /* 2D addresses don't need a base address. */ +#endif + } + + /* Return the flag. */ + *NeedBase = need; + + /* Success. */ + gcmkFOOTER_ARG("*NeedBase=%d", *NeedBase); + return gcvSTATUS_OK; +} + +gceSTATUS +gckHARDWARE_SetIsrManager( + IN gckHARDWARE Hardware, + IN gctISRMANAGERFUNC StartIsr, + IN gctISRMANAGERFUNC StopIsr, + IN gctPOINTER Context + ) +{ + gceSTATUS status = gcvSTATUS_OK; + + gcmkHEADER_ARG("Hardware=0x%x, StartIsr=0x%x, StopIsr=0x%x, Context=0x%x", + Hardware, StartIsr, StopIsr, Context); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + if (StartIsr == gcvNULL || + StopIsr == gcvNULL || + Context == gcvNULL) + { + status = gcvSTATUS_INVALID_ARGUMENT; + + gcmkFOOTER(); + return status; + } + + Hardware->startIsr = StartIsr; + Hardware->stopIsr = StopIsr; + Hardware->isrContext = Context; + + /* Success. */ + gcmkFOOTER(); + + return status; +} + +/******************************************************************************* +** +** gckHARDWARE_Compose +** +** Start a composition. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to the gckHARDWARE object. +** +** OUTPUT: +** +** Nothing. +*/ +gceSTATUS +gckHARDWARE_Compose( + IN gckHARDWARE Hardware, + IN gctUINT32 ProcessID, + IN gctSIZE_T Size, + IN gctPHYS_ADDR Physical, + IN gctPOINTER Logical, + IN gctUINT8 EventID + ) +{ +#ifndef VIVANTE_NO_3D + gceSTATUS status; + gctUINT32_PTR sizeState; + gctUINT32_PTR triggerState; + gctUINT32_PTR dummyState; + gctSIZE_T size; + + gcmkHEADER_ARG("Hardware=0x%x Size=%d Physical=0x%x" + " Logical=0x%x EventID=%d", + Hardware, Size, Physical, Logical, EventID); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + gcmkVERIFY_ARGUMENT((Size & 7) == 0); + gcmkVERIFY_ARGUMENT(Logical != gcvNULL); + + /* Make total state buffer size 64B aligned. */ + size = gcmALIGN(Size + 16, 64) - 8; + + /* Program the size of the state buffer. */ + sizeState = (gctUINT32_PTR) Logical; + sizeState[0] = 0xFFFFFFFF; + sizeState[1] = size >> 3; + + /* Program the trigger state. */ + triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Size); + triggerState[0] = 0x0C03; + triggerState[1] + = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 5:4) - (0 ? 5:4) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 5:4) - (0 ? 5:4) + 1))))))) << (0 ? 5:4))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 8:8) - (0 ? 8:8) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 24:24) - (0 ? 24:24) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 24:24) - (0 ? 24:24) + 1))))))) << (0 ? 24:24))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ? 12:12) - (0 ? 12:12) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 12:12) - (0 ? 12:12) + 1))))))) << (0 ? 12:12))) + | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))) | (((gctUINT32) ((gctUINT32) (EventID) & ((gctUINT32) ((((1 ? 20:16) - (0 ? 20:16) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 20:16) - (0 ? 20:16) + 1))))))) << (0 ? 20:16))) + ; + + /* Dummy state padding. */ + dummyState = triggerState + 2; + + while (Size < size) + { + dummyState[0] = 0xFFFFFFFF; + dummyState[1] = 0x00000000; + + dummyState += 2; + Size += 8; + } + +#if gcdNONPAGED_MEMORY_CACHEABLE + /* Flush the cache for the wait/link. */ + gcmkONERROR(gckOS_CacheClean( + Hardware->os, ProcessID, gcvNULL, Physical, Logical, size + )); +#endif + + /* Start composition. */ + gcmkONERROR(gckOS_WriteRegisterEx( + Hardware->os, Hardware->core, 0x00554, + ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) | (((gctUINT32) (0x3 & ((gctUINT32) ((((1 ? 1:0) - (0 ? 1:0) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 1:0) - (0 ? 1:0) + 1))))))) << (0 ? 1:0))) + )); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +#else + /* Return the status. */ + return gcvSTATUS_NOT_SUPPORTED; +#endif +} + +/******************************************************************************* +** +** gckHARDWARE_IsFeatureAvailable +** +** Verifies whether the specified feature is available in hardware. +** +** INPUT: +** +** gckHARDWARE Hardware +** Pointer to an gckHARDWARE object. +** +** gceFEATURE Feature +** Feature to be verified. +*/ +gceSTATUS +gckHARDWARE_IsFeatureAvailable( + IN gckHARDWARE Hardware, + IN gceFEATURE Feature + ) +{ + gctBOOL available; + + gcmkHEADER_ARG("Hardware=0x%x Feature=%d", Hardware, Feature); + + /* Verify the arguments. */ + gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); + + /* Only features needed by common kernel logic added here. */ + switch (Feature) + { + case gcvFEATURE_END_EVENT: + /*available = gcmVERIFYFIELDVALUE(Hardware->chipMinorFeatures2, + GC_MINOR_FEATURES2, END_EVENT, AVAILABLE + );*/ + available = gcvFALSE; + break; + + default: + gcmkFATAL("Invalid feature has been requested."); + available = gcvFALSE; + } + + /* Return result. */ + gcmkFOOTER_ARG("%d", available ? gcvSTATUS_TRUE : gcvSTATUS_OK); + return available ? gcvSTATUS_TRUE : gcvSTATUS_OK; +} + +#if gcdFRAME_DB +static gceSTATUS +gckHARDWARE_ReadPerformanceRegister( + IN gckHARDWARE Hardware, + IN gctUINT PerformanceAddress, + IN gctUINT IndexAddress, + IN gctUINT IndexShift, + IN gctUINT Index, + OUT gctUINT32_PTR Value + ) +{ + gceSTATUS status; + + gcmkHEADER_ARG("Hardware=0x%x PerformanceAddress=0x%x IndexAddress=0x%x " + "IndexShift=%u Index=%u", + Hardware, PerformanceAddress, IndexAddress, IndexShift, + Index); + + /* Write the index. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + IndexAddress, + Index << IndexShift)); + + /* Read the register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + PerformanceAddress, + Value)); + + /* Test for reset. */ + if (Index == 15) + { + /* Index another register to get out of reset. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, Hardware->core, IndexAddress, 0)); + } + + /* Success. */ + gcmkFOOTER_ARG("*Value=0x%x", *Value); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} + +gceSTATUS +gckHARDWARE_GetFrameInfo( + IN gckHARDWARE Hardware, + OUT gcsHAL_FRAME_INFO * FrameInfo + ) +{ + gceSTATUS status; + gctUINT i, clock; + gcsHAL_FRAME_INFO info; +#if gcdFRAME_DB_RESET + gctUINT reset; +#endif + + gcmkHEADER_ARG("Hardware=0x%x", Hardware); + + /* Get profile tick. */ + gcmkONERROR(gckOS_GetProfileTick(&info.ticks)); + + /* Read SH counters and reset them. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 4, + &info.shaderCycles)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 9, + &info.vsInstructionCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 12, + &info.vsTextureCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 7, + &info.psInstructionCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 14, + &info.psTextureCount)); +#if gcdFRAME_DB_RESET + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0045C, + 0x00470, + 24, + 15, + &reset)); +#endif + + /* Read PA counters and reset them. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 3, + &info.vertexCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 4, + &info.primitiveCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 7, + &info.rejectedPrimitives)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 8, + &info.culledPrimitives)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 6, + &info.clippedPrimitives)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 5, + &info.outPrimitives)); +#if gcdFRAME_DB_RESET + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00460, + 0x00474, + 0, + 15, + &reset)); +#endif + + /* Read RA counters and reset them. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 3, + &info.inPrimitives)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 11, + &info.culledQuadCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 1, + &info.totalQuadCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 2, + &info.quadCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 0, + &info.totalPixelCount)); +#if gcdFRAME_DB_RESET + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00448, + 0x00474, + 16, + 15, + &reset)); +#endif + + /* Read TX counters and reset them. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 0, + &info.bilinearRequests)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 1, + &info.trilinearRequests)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 8, + &info.txHitCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 9, + &info.txMissCount)); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 6, + &info.txBytes8)); +#if gcdFRAME_DB_RESET + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x0044C, + 0x00474, + 24, + 15, + &reset)); +#endif + + /* Read clock control register. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + &clock)); + + /* Walk through all avaiable pixel pipes. */ + for (i = 0; i < Hardware->pixelPipes; ++i) + { + /* Select proper pipe. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + ((((gctUINT32) (clock)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))) | (((gctUINT32) ((gctUINT32) (i) & ((gctUINT32) ((((1 ? 23:20) - (0 ? 23:20) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 23:20) - (0 ? 23:20) + 1))))))) << (0 ? 23:20))))); + + /* Read cycle registers. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00078, + &info.cycles[i])); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x0007C, + &info.idleCycles[i])); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00438, + &info.mcCycles[i])); + + /* Read bandwidth registers. */ + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x0005C, + &info.readRequests[i])); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00040, + &info.readBytes8[i])); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00050, + &info.writeRequests[i])); + gcmkONERROR(gckOS_ReadRegisterEx(Hardware->os, + Hardware->core, + 0x00044, + &info.writeBytes8[i])); + + /* Read PE counters. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00454, + 0x00470, + 16, + 0, + &info.colorKilled[i])); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00454, + 0x00470, + 16, + 2, + &info.colorDrawn[i])); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00454, + 0x00470, + 16, + 1, + &info.depthKilled[i])); + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00454, + 0x00470, + 16, + 3, + &info.depthDrawn[i])); + } + + /* Zero out remaning reserved counters. */ + for (; i < 8; ++i) + { + info.readBytes8[i] = 0; + info.writeBytes8[i] = 0; + info.cycles[i] = 0; + info.idleCycles[i] = 0; + info.mcCycles[i] = 0; + info.readRequests[i] = 0; + info.writeRequests[i] = 0; + info.colorKilled[i] = 0; + info.colorDrawn[i] = 0; + info.depthKilled[i] = 0; + info.depthDrawn[i] = 0; + } + + /* Reset clock control register. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00000, + clock)); + + /* Reset cycle and bandwidth counters. */ + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0003C, + 1)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x0003C, + 0)); + gcmkONERROR(gckOS_WriteRegisterEx(Hardware->os, + Hardware->core, + 0x00078, + 0)); + +#if gcdFRAME_DB_RESET + /* Reset PE counters. */ + gcmkONERROR(gckHARDWARE_ReadPerformanceRegister( + Hardware, + 0x00454, + 0x00470, + 16, + 15, + &reset)); +#endif + + /* Copy to user. */ + gcmkONERROR(gckOS_CopyToUserData(Hardware->os, + &info, + FrameInfo, + gcmSIZEOF(info))); + + /* Success. */ + gcmkFOOTER_NO(); + return gcvSTATUS_OK; + +OnError: + /* Return the status. */ + gcmkFOOTER(); + return status; +} +#endif + -- cgit v1.2.3