/**************************************************************************** * * 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 gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity ) { gceSTATUS status; gctUINT32 chipIdentity; 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; gcmkHEADER_ARG("Os=0x%x", Os); /*************************************************************************** ** Get chip ID and revision. */ /* 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)))))))) { Identity->chipModel = gcv500; Identity->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 chip identity register. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00020, (gctUINT32_PTR) &Identity->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 ((Identity->chipModel & 0xFF00) == 0x0400) { Identity->chipModel = (gceCHIPMODEL) (Identity->chipModel & 0x0400); } /* Read CHIP_REV register. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00024, &Identity->chipRevision)); if ((Identity->chipModel == gcv300) && (Identity->chipRevision == 0x2201) ) { gctUINT32 chipDate; gctUINT32 chipTime; /* Read date and time registers. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00028, &chipDate)); gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x0002C, &chipTime)); if ((chipDate == 0x20080814) && (chipTime == 0x12051100)) { /* This IP has an ECO; put the correct revision in it. */ Identity->chipRevision = 0x1051; } } } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipModel=%X", Identity->chipModel); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipRevision=%X", Identity->chipRevision); /*************************************************************************** ** Get chip features. */ /* Read chip feature register. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x0001C, &Identity->chipFeatures)); #ifndef VIVANTE_NO_3D /* Disable fast clear on GC700. */ if (Identity->chipModel == gcv700) { Identity->chipFeatures = ((((gctUINT32) (Identity->chipFeatures)) & ~(((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))); } #endif if (((Identity->chipModel == gcv500) && (Identity->chipRevision < 2)) || ((Identity->chipModel == gcv300) && (Identity->chipRevision < 0x2000)) ) { /* GC500 rev 1.x and GC300 rev < 2.0 doesn't have these registers. */ Identity->chipMinorFeatures = 0; Identity->chipMinorFeatures1 = 0; Identity->chipMinorFeatures2 = 0; Identity->chipMinorFeatures3 = 0; } else { /* Read chip minor feature register #0. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00034, &Identity->chipMinorFeatures)); if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (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, &Identity->chipMinorFeatures1)); /* Read chip minor featuress register #2. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00084, &Identity->chipMinorFeatures2)); /* Read chip minor featuress register #1. */ gcmkONERROR( gckOS_ReadRegisterEx(Os, Core, 0x00088, &Identity->chipMinorFeatures3)); } else { /* Chip doesn't has minor features register #1 or 2 or 3. */ Identity->chipMinorFeatures1 = 0; Identity->chipMinorFeatures2 = 0; Identity->chipMinorFeatures3 = 0; } } /* Disable HIERARCHICAL_Z. */ Identity->chipMinorFeatures = ((((gctUINT32) (Identity->chipMinorFeatures)) & ~(((gctUINT32) (((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ? 27:27) - (0 ? 27:27) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 27:27) - (0 ? 27:27) + 1))))))) << (0 ? 27:27))); #if gcdSUPPORT_SWAP_RECTANGLE Identity->chipMinorFeatures = Identity->chipMinorFeatures & (~(1 << 12)); #endif gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipFeatures=0x%08X", Identity->chipFeatures); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipMinorFeatures=0x%08X", Identity->chipMinorFeatures); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipMinorFeatures1=0x%08X", Identity->chipMinorFeatures1); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipMinorFeatures2=0x%08X", Identity->chipMinorFeatures2); gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Identity: chipMinorFeatures3=0x%08X", Identity->chipMinorFeatures3); /*************************************************************************** ** Get chip specs. */ if (((((gctUINT32) (Identity->chipMinorFeatures)) >> (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(Os, Core, 0x00048, &specs)); /* 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(Os, Core, 0x00080, &specs2)); 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. */ Identity->pixelPipes = gcmMAX(pixelPipes, 1); /* Get the stream count. */ Identity->streamCount = (streamCount != 0) ? streamCount : (Identity->chipModel >= gcv1000) ? 4 : 1; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: streamCount=%u%s", Identity->streamCount, (streamCount == 0) ? " (default)" : ""); /* Get the vertex output buffer size. */ Identity->vertexOutputBufferSize = (vertexOutputBufferSize != 0) ? 1 << vertexOutputBufferSize : (Identity->chipModel == gcv400) ? (Identity->chipRevision < 0x4000) ? 512 : (Identity->chipRevision < 0x4200) ? 256 : 128 : (Identity->chipModel == gcv530) ? (Identity->chipRevision < 0x4200) ? 512 : 128 : 512; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: vertexOutputBufferSize=%u%s", Identity->vertexOutputBufferSize, (vertexOutputBufferSize == 0) ? " (default)" : ""); /* Get the maximum number of threads. */ Identity->threadCount = (threadCount != 0) ? 1 << threadCount : (Identity->chipModel == gcv400) ? 64 : (Identity->chipModel == gcv500) ? 128 : (Identity->chipModel == gcv530) ? 128 : 256; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: threadCount=%u%s", Identity->threadCount, (threadCount == 0) ? " (default)" : ""); /* Get the number of shader cores. */ Identity->shaderCoreCount = (shaderCoreCount != 0) ? shaderCoreCount : (Identity->chipModel >= gcv1000) ? 2 : 1; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: shaderCoreCount=%u%s", Identity->shaderCoreCount, (shaderCoreCount == 0) ? " (default)" : ""); /* Get the vertex cache size. */ Identity->vertexCacheSize = (vertexCacheSize != 0) ? vertexCacheSize : 8; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: vertexCacheSize=%u%s", Identity->vertexCacheSize, (vertexCacheSize == 0) ? " (default)" : ""); /* Get the maximum number of temporary registers. */ Identity->registerMax = (registerMax != 0) /* Maximum of registerMax/4 registers are accessible to 1 shader */ ? 1 << registerMax : (Identity->chipModel == gcv400) ? 32 : 64; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: registerMax=%u%s", Identity->registerMax, (registerMax == 0) ? " (default)" : ""); /* Get the instruction count. */ Identity->instructionCount = (instructionCount == 0) ? 256 : (instructionCount == 1) ? 1024 : (instructionCount == 2) ? 2048 : 256; if (Identity->chipModel == gcv2000 && Identity->chipRevision == 0x5108) { Identity->instructionCount = 512; } gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: instructionCount=%u%s", Identity->instructionCount, (instructionCount == 0) ? " (default)" : ""); /* Get the number of constants. */ Identity->numConstants = numConstants; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: numConstants=%u%s", Identity->numConstants, (numConstants == 0) ? " (default)" : ""); /* Get the buffer size. */ Identity->bufferSize = bufferSize; gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "Specs: bufferSize=%u%s", Identity->bufferSize, (bufferSize == 0) ? " (default)" : ""); /* Success. */ gcmkFOOTER(); 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 ) { gceSTATUS status; gckHARDWARE hardware = gcvNULL; 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); } /* Allocate the gckHARDWARE object. */ gcmkONERROR(gckOS_Allocate(Os, gcmSIZEOF(struct _gckHARDWARE), &pointer)); hardware = (gckHARDWARE) pointer; /* Initialize the gckHARDWARE object. */ hardware->object.type = gcvOBJ_HARDWARE; hardware->os = Os; hardware->core = Core; /* Identify the hardware. */ gcmkONERROR(_IdentifyHardware(Os, Core, &hardware->identity)); /* Determine the hardware type */ switch (hardware->identity.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) (hardware->identity.chipFeatures)) >> (0 ? 9:9)) & ((gctUINT32) ((((1 ? 9:9) - (0 ? 9:9) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 9:9) - (0 ? 9:9) + 1)))))) )) { hardware->type = (gceHARDWARE_TYPE) (hardware->type | gcvHARDWARE_2D); } } hardware->powerBaseAddress = ((hardware->identity.chipModel == gcv300) && (hardware->identity.chipRevision < 0x2000)) ? 0x0100 : 0x0000; hardware->powerMutex = gcvNULL; hardware->mmuVersion = (((((gctUINT32) (hardware->identity.chipMinorFeatures1)) >> (0 ? 28:28)) & ((gctUINT32) ((((1 ? 28:28) - (0 ? 28:28) + 1) == 32) ? ~0 : (~(~0 << ((1 ? 28:28) - (0 ? 28:28) + 1)))))) ); /* Determine whether bug fixes #1 are present. */ hardware->extraEventStates = ((((gctUINT32) (hardware->identity.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->identity.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_CreateSignal(Os, gcvFALSE, &hardware->powerOffSignal)); hardware->powerOffTimeout = gcdPOWEROFF_TIMEOUT; #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->powerOffSignal != gcvNULL) { gcmkVERIFY_OK(gckOS_DestroySignal(Os, hardware->powerOffSignal)); } #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_DestroySignal(Hardware->os, Hardware->powerOffSignal)); #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->identity.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->identity.chipRevision == 0x4301) || (Hardware->identity.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->identity.chipRevision < 0x5000) && ((((gctUINT32) (Hardware->identity.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->identity.chipMinorFeatures)) >> (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: ** ** gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity ** Pointer to the identity structure. ** */ gceSTATUS gckHARDWARE_QueryChipIdentity( IN gckHARDWARE Hardware, OUT gcsHAL_QUERY_CHIP_IDENTITY_PTR Identity ) { gctUINT32 features; gcmkHEADER_ARG("Hardware=0x%x", Hardware); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_ARGUMENT(Identity != gcvNULL); /* Return chip model and revision. */ Identity->chipModel = Hardware->identity.chipModel; Identity->chipRevision = Hardware->identity.chipRevision; /* Return feature set. */ features = Hardware->identity.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->identity.chipModel == gcv500) && (Hardware->identity.chipRevision <= 2)) || (Hardware->identity.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))); } Identity->chipFeatures = features; /* Return minor features. */ Identity->chipMinorFeatures = Hardware->identity.chipMinorFeatures; Identity->chipMinorFeatures1 = Hardware->identity.chipMinorFeatures1; Identity->chipMinorFeatures2 = Hardware->identity.chipMinorFeatures2; Identity->chipMinorFeatures3 = Hardware->identity.chipMinorFeatures3; /* Return chip specs. */ Identity->streamCount = Hardware->identity.streamCount; Identity->registerMax = Hardware->identity.registerMax; Identity->threadCount = Hardware->identity.threadCount; Identity->shaderCoreCount = Hardware->identity.shaderCoreCount; Identity->vertexCacheSize = Hardware->identity.vertexCacheSize; Identity->vertexOutputBufferSize = Hardware->identity.vertexOutputBufferSize; Identity->pixelPipes = Hardware->identity.pixelPipes; Identity->instructionCount = Hardware->identity.instructionCount; Identity->numConstants = Hardware->identity.numConstants; Identity->bufferSize = Hardware->identity.bufferSize; /* Success. */ gcmkFOOTER_NO(); 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 ? 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))); /* 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->identity.chipMinorFeatures)) >> (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->identity.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->identity.pixelPipes) : (4 * Hardware->identity.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) { gcmkTRACE_ZONE(gcvLEVEL_ERROR, gcvZONE_HARDWARE, "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->identity.chipModel < gcv4000) { *VertexUniforms = 168; } else { *VertexUniforms = 256; } } if (FragmentUniforms != gcvNULL) { /* Return the ps shader const count. */ if (Hardware->identity.chipModel < gcv4000) { *FragmentUniforms = 64; } else { *FragmentUniforms = 256; } } if (Varyings != gcvNULL) { /* Return the shader varyings count. */ if (((((gctUINT32) (Hardware->identity.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->identity.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->identity.chipModel != gcv500) || (Hardware->identity.chipRevision >= 3) ) ? 1 : 0; } if (Compression == -1) { /* Determine automatic value for compression. */ Compression = Enable & (((((gctUINT32) (Hardware->identity.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 + Hardware->powerOffTimeout; if (State == gcvPOWER_IDLE) { gcmkONERROR(gckOS_Signal(os, Hardware->powerOffSignal, gcvTRUE)); } #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; } #if gcdPOWEROFF_TIMEOUT gceSTATUS gckHARDWARE_SetPowerOffTimeout( IN gckHARDWARE Hardware, IN gctUINT32 Timeout ) { gcmkHEADER_ARG("Hardware=0x%x Timeout=%d", Hardware, Timeout); Hardware->powerOffTimeout = Timeout; gcmkFOOTER_NO(); return gcvSTATUS_OK; } gceSTATUS gckHARDWARE_QueryPowerOffTimeout( IN gckHARDWARE Hardware, OUT gctUINT32* Timeout ) { gcmkHEADER_ARG("Hardware=0x%x", Hardware); *Timeout = Hardware->powerOffTimeout; gcmkFOOTER_ARG("*Timeout=%d", *Timeout); return gcvSTATUS_OK; } #endif 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->identity.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->identity.chipMinorFeatures)) >> (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 gctPHYS_ADDR Physical, IN gctPOINTER Logical, IN gctSIZE_T Offset, IN gctSIZE_T Size, IN gctUINT8 EventID ) { #ifndef VIVANTE_NO_3D gceSTATUS status; gctUINT32_PTR triggerState; gcmkHEADER_ARG("Hardware=0x%x Physical=0x%x Logical=0x%x" " Offset=%d Size=%d EventID=%d", Hardware, Physical, Logical, Offset, Size, EventID); /* Verify the arguments. */ gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE); gcmkVERIFY_ARGUMENT(((Size + 8) & 63) == 0); gcmkVERIFY_ARGUMENT(Logical != gcvNULL); /* Program the trigger state. */ triggerState = (gctUINT32_PTR) ((gctUINT8_PTR) Logical + Offset + 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))) ; #if gcdNONPAGED_MEMORY_CACHEABLE /* Flush the cache for the wait/link. */ gcmkONERROR(gckOS_CacheClean( Hardware->os, ProcessID, gcvNULL, Physical, Logical, Offset + 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->identity.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->identity.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