/****************************************************************************
*
*    The MIT License (MIT)
*
*    Copyright (c) 2014 - 2018 Vivante Corporation
*
*    Permission is hereby granted, free of charge, to any person obtaining a
*    copy of this software and associated documentation files (the "Software"),
*    to deal in the Software without restriction, including without limitation
*    the rights to use, copy, modify, merge, publish, distribute, sublicense,
*    and/or sell copies of the Software, and to permit persons to whom the
*    Software is furnished to do so, subject to the following conditions:
*
*    The above copyright notice and this permission notice shall be included in
*    all copies or substantial portions of the Software.
*
*    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
*    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
*    DEALINGS IN THE SOFTWARE.
*
*****************************************************************************
*
*    The GPL License (GPL)
*
*    Copyright (C) 2014 - 2018 Vivante Corporation
*
*    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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*****************************************************************************
*
*    Note: This software is released under dual MIT and GPL licenses. A
*    recipient may use this file under the terms of either the MIT license or
*    GPL License. If you wish to use only one license not the other, you can
*    indicate your decision by deleting one of the above license notices in your
*    version of this file.
*
*****************************************************************************/


#include "gc_hal_types.h"
#include "gc_hal_base.h"
#include "gc_hal_security_interface.h"
#include "gc_hal_ta.h"
#include "gc_hal_ta_hardware.h"
#include "gc_hal.h"
#include "gc_feature_database.h"


#define _GC_OBJ_ZONE     1
#define SRC_MAX          8
#define RECT_ADDR_OFFSET 3

#define INVALID_ADDRESS  ~0U

/******************************************************************************\
********************************* Support Code *********************************
\******************************************************************************/
static gceSTATUS
_IdentifyHardwareByDatabase(
    IN gcTA_HARDWARE Hardware
    )
{
    gceSTATUS status;
    gctUINT32 chipIdentity;
    gcsFEATURE_DATABASE *database;
    gctaOS os = Hardware->os;

    gcmkHEADER();

    /***************************************************************************
    ** Get chip ID and revision.
    */

    /* Read chip identity register. */
    gcmkONERROR(gctaOS_ReadRegister(os, Hardware->ta->core, 0x00018, &chipIdentity));

    /* Special case for older graphic cores. */
    if (((((gctUINT32) (chipIdentity)) >> (0 ?
 31:24) & ((gctUINT32) ((((1 ?
 31:24) - (0 ?
 31:24) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 31:24) - (0 ?
 31:24) + 1)))))) == (0x01 & ((gctUINT32) ((((1 ?
 31:24) - (0 ?
 31:24) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 31:24) - (0 ? 31:24) + 1))))))))
    {
        Hardware->chipModel    = gcv500;
        Hardware->chipRevision = (((((gctUINT32) (chipIdentity)) >> (0 ? 15:12)) & ((gctUINT32) ((((1 ? 15:12) - (0 ? 15:12) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 15:12) - (0 ? 15:12) + 1)))))) );
    }

    else
    {
        /* Read chip identity register. */
        gcmkONERROR(
            gctaOS_ReadRegister(os, Hardware->ta->core,
                                 0x00020,
                                 (gctUINT32_PTR) &Hardware->chipModel));

        if (((Hardware->chipModel & 0xFF00) == 0x0400)
          && (Hardware->chipModel != 0x0420)
          && (Hardware->chipModel != 0x0428))
        {
            Hardware->chipModel = (gceCHIPMODEL) (Hardware->chipModel & 0x0400);
        }

        /* Read CHIP_REV register. */
        gcmkONERROR(
            gctaOS_ReadRegister(os, Hardware->ta->core,
                                 0x00024,
                                 &Hardware->chipRevision));

        if ((Hardware->chipModel    == gcv300)
        &&  (Hardware->chipRevision == 0x2201)
        )
        {
            gctUINT32 chipDate;
            gctUINT32 chipTime;

            /* Read date and time registers. */
            gcmkONERROR(
                gctaOS_ReadRegister(os, Hardware->ta->core,
                                     0x00028,
                                     &chipDate));

            gcmkONERROR(
                gctaOS_ReadRegister(os, Hardware->ta->core,
                                     0x0002C,
                                     &chipTime));

            if ((chipDate == 0x20080814) && (chipTime == 0x12051100))
            {
                /* This IP has an ECO; put the correct revision in it. */
                Hardware->chipRevision = 0x1051;
            }
        }

        gcmkONERROR(
            gctaOS_ReadRegister(os, Hardware->ta->core,
                                 0x000A8,
                                 &Hardware->productID));
    }

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        os, Hardware->ta->core,
        0x000E8
,
        &Hardware->ecoID
        ));

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        os, Hardware->ta->core,
        0x00030
,
        &Hardware->customerID
        ));

    /***************************************************************************
    ** Get chip features.
    */

    database =
    Hardware->featureDatabase =
    gcQueryFeatureDB(
        Hardware->chipModel,
        Hardware->chipRevision,
        Hardware->productID,
        Hardware->ecoID,
        Hardware->customerID
        );

    if (database == gcvNULL)
    {
        gcmkPRINT("[galcore]: Feature database is not found,"
                  "chipModel=0x%0x, chipRevision=0x%x, productID=0x%x, ecoID=0x%x, customerID=0x%x",
                  Hardware->chipModel,
                  Hardware->chipRevision,
                  Hardware->productID,
                  Hardware->ecoID,
                  Hardware->customerID);
        gcmkONERROR(gcvSTATUS_NOT_FOUND);
    }

    /* Success. */
    gcmkFOOTER();
    return gcvSTATUS_OK;

OnError:
    /* Return the status. */
    gcmkFOOTER();
    return status;
}


gceSTATUS
gctaHARDWARE_SetMMUStates(
    IN gcTA_HARDWARE Hardware,
    IN gctPOINTER MtlbAddress,
    IN gceMMU_MODE Mode,
    IN gctPOINTER SafeAddress,
    IN gctPOINTER Logical,
    IN OUT gctUINT32 * Bytes
    )
{
    gceSTATUS status;
    gctUINT32 config;
    gctUINT32 extMtlb;
    gctPHYS_ADDR_T physical;
    gctUINT32_PTR buffer;
    gctUINT32 reserveBytes = 2 * 4;
    gcsMMU_TABLE_ARRAY_ENTRY * entry;

    gcmkHEADER_ARG("Hardware=0x%x", Hardware);

    entry = (gcsMMU_TABLE_ARRAY_ENTRY *) Hardware->pagetableArray.logical;

    /* Convert logical address into physical address. */
    gcmkONERROR(
        gctaOS_GetPhysicalAddress(Hardware->os, MtlbAddress, &physical));

    config  = (gctUINT32)(physical & 0xFFFFFFFF);
    extMtlb = (gctUINT32)(physical >> 32);
    /* more than 40bit physical address */
    if (extMtlb & 0xFFFFFF00)
    {
        gcmkONERROR(gcvSTATUS_NOT_SUPPORTED);
    }

    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) ?
 ~0U : (~(~0U << ((1 ?
 0:0) - (0 ?
 0:0) + 1))))))) << (0 ?
 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((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) ?
 ~0U : (~(~0U << ((1 ?
 0:0) - (0 ?
 0:0) + 1))))))) << (0 ?
 0:0))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)));

        break;

    default:
        gcmkONERROR(gcvSTATUS_INVALID_ARGUMENT);
    }

    if (Logical != gcvNULL)
    {
        buffer = Logical;

        /* Setup page table array entry. */
        entry->low = config;
        entry->high = extMtlb;

        /* Setup command buffer to load index 0 of page table array. */
        *buffer++
            = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 31:27) - (0 ?
 31:27) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 31:27) - (0 ?
 31:27) + 1))))))) << (0 ?
 31:27))) | (((gctUINT32) (0x01 & ((gctUINT32) ((((1 ?
 31:27) - (0 ?
 31:27) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)))
            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 15:0) - (0 ?
 15:0) + 1))))))) << (0 ?
 15:0))) | (((gctUINT32) ((gctUINT32) (0x006B) & ((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)))
            | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 25:16) - (0 ?
 25:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 25:16) - (0 ?
 25:16) + 1))))))) << (0 ?
 25:16))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
 25:16) - (0 ?
 25:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 25:16) - (0 ? 25:16) + 1))))))) << (0 ? 25:16)));

        *buffer++
            = (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 15:0) - (0 ?
 15:0) + 1))))))) << (0 ?
 15:0))) | (((gctUINT32) ((gctUINT32) (0) & ((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 15:0) - (0 ?
 15:0) + 1))))))) << (0 ?
 15:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 16:16) - (0 ?
 16:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 16:16) - (0 ?
 16:16) + 1))))))) << (0 ?
 16:16))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
 16:16) - (0 ?
 16:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16))));
    }

    if (Bytes != gcvNULL)
    {
        *Bytes = reserveBytes;
    }

    /* Return the status. */
    gcmkFOOTER_NO();
    return status;

OnError:
    /* Return the status. */
    gcmkFOOTER();
    return status;
}

gceSTATUS
gctaHARDWARE_End(
    IN gcTA_HARDWARE Hardware,
    IN gctPOINTER Logical,
    IN OUT gctUINT32 * 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_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) ?
 ~0U : (~(~0U << ((1 ?
 31:27) - (0 ?
 31:27) + 1))))))) << (0 ?
 31:27))) | (((gctUINT32) (0x02 & ((gctUINT32) ((((1 ?
 31:27) - (0 ?
 31:27) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 31:27) - (0 ? 31:27) + 1))))))) << (0 ? 31:27)));

        /* Record the count of execution which is finised by this END. */
        logical[1] =
            0;

        gcmkTRACE_ZONE(gcvLEVEL_INFO, gcvZONE_HARDWARE, "0x%x: END", 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;
}


gceSTATUS
gctaHARDWARE_Construct(
    IN gcTA TA,
    OUT gcTA_HARDWARE * Hardware
    )
{
    gceSTATUS status;
    gcTA_HARDWARE hardware = gcvNULL;

    gctaOS os = TA->os;

    gcmkONERROR(gctaOS_Allocate(
        gcmSIZEOF(gcsTA_HARDWARE),
        (gctPOINTER *)&hardware
        ));

    gctaOS_ZeroMemory((gctUINT8_PTR)hardware, gcmSIZEOF(gcsTA_HARDWARE));

    hardware->ta = TA;
    hardware->os = os;

    hardware->pagetableArray.size = 4096;

    hardware->functionBytes = 4096;

    /* Power on GPU. */
    gctaOS_SetGPUPower(os, TA->core, gcvTRUE, gcvTRUE);

    /*************************************/
    /********  Get chip information ******/
    /*************************************/
    gctaOS_WriteRegister(
        hardware->ta->os, hardware->ta->core,
        0x00000,
        0x00000900
        );

    gcmkONERROR(_IdentifyHardwareByDatabase(hardware));

    *Hardware = hardware;

    return gcvSTATUS_OK;

OnError:
    if (hardware)
    {
        gctaOS_Free(hardware);
    }

    return status;
}

gceSTATUS
gctaHARDWARE_Destroy(
    IN gcTA_HARDWARE Hardware
    )
{
    if (Hardware->pagetableArray.logical)
    {
        gctaOS_FreeSecurityMemory(
            Hardware->ta->os,
            Hardware->pagetableArray.size,
            Hardware->pagetableArray.logical,
            (gctUINT32_PTR)Hardware->pagetableArray.physical
            );
    }

    if (Hardware->functionLogical)
    {
        gctaOS_FreeSecurityMemory(
            Hardware->ta->os,
            Hardware->functionBytes,
            Hardware->functionLogical,
            (gctUINT32_PTR)Hardware->functionPhysical
            );
    }

    gctaOS_Free(Hardware);

    return gcvSTATUS_OK;
}

gceSTATUS
gctaHARDWARE_Execute(
    IN gcTA TA,
    IN gctUINT32 Address,
    IN gctUINT32 Bytes
    )
{
    gceSTATUS status;
    gctUINT32 address = Address, control;

    gcmkHEADER_ARG("Address=0x%x Bytes=%lu",
        Address, Bytes);

    /* Enable all events. */
    gcmkONERROR(
        gctaOS_WriteRegister(TA->os, TA->core, 0x00014, ~0U));

    /* Write address register. */
    gcmkONERROR(
        gctaOS_WriteRegister(TA->os, TA->core, 0x00654, address));

    /* Build control register. */
    control = ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 16:16) - (0 ?
 16:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 16:16) - (0 ?
 16:16) + 1))))))) << (0 ?
 16:16))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
 16:16) - (0 ?
 16:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 16:16) - (0 ? 16:16) + 1))))))) << (0 ? 16:16)))
        | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 15:0) - (0 ?
 15:0) + 1))))))) << (0 ?
 15:0))) | (((gctUINT32) ((gctUINT32) ((Bytes + 7) >> 3) & ((gctUINT32) ((((1 ?
 15:0) - (0 ?
 15:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 15:0) - (0 ? 15:0) + 1))))))) << (0 ? 15:0)));

    /* Write control register. */
    gcmkONERROR(
        gctaOS_WriteRegister(TA->os, TA->core, 0x003A4, 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;
}

gceSTATUS
gctaHARDWARE_MmuEnable(
    IN gcTA_HARDWARE Hardware
    )
{
    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x0018C,
        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 0:0) - (0 ?
 0:0) + 1))))))) << (0 ?
 0:0))) | (((gctUINT32) ((gctUINT32) (1 ) & ((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0))));

    return gcvSTATUS_OK;
}

/*
* In trust zone, we prepare page table array table and configure base address of
* it to hardware.
*/
gceSTATUS
gctaHARDWARE_SetMMU(
    IN gcTA_HARDWARE Hardware,
    IN gctPOINTER Logical
    )
{
    gcsMMU_TABLE_ARRAY_ENTRY *entry;
    gcsHARDWARE_FUNCTION *function = &Hardware->functions[0];
    gctUINT32 delay = 1;
    gctUINT32 timer = 0;
    gctUINT32 idle;
    gctPHYS_ADDR_T mtlbPhysical;
    gctPHYS_ADDR_T secureSafeAddress;
    gctPHYS_ADDR_T nonSecureSafeAddress;

    gctaOS_GetPhysicalAddress(Hardware->ta->os, Logical, &mtlbPhysical);

    gctaOS_GetPhysicalAddress(Hardware->ta->os, Hardware->ta->mmu->safePageLogical, &secureSafeAddress);

    gctaOS_GetPhysicalAddress(Hardware->ta->os, Hardware->ta->mmu->nonSecureSafePageLogical, &nonSecureSafeAddress);

    /* not support more than 40bit physical address */
    if ((secureSafeAddress & 0xFFFFFF0000000000ULL) ||
        (nonSecureSafeAddress & 0xFFFFFF0000000000ULL))
    {
        return (gcvSTATUS_NOT_SUPPORTED);
    }

    /* Fill entry 0 of page table array. */
    entry = (gcsMMU_TABLE_ARRAY_ENTRY *)Hardware->pagetableArray.logical;

    entry->low  = (gctUINT32)(mtlbPhysical & 0xFFFFFFFF);

    entry->high = (gctUINT32)(mtlbPhysical >> 32)
                | ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 8:8) - (0 ?
 8:8) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 8:8) - (0 ?
 8:8) + 1))))))) << (0 ?
 8:8))) | (((gctUINT32) ((gctUINT32) (1) & ((gctUINT32) ((((1 ?
 8:8) - (0 ?
 8:8) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 8:8) - (0 ? 8:8) + 1))))))) << (0 ? 8:8)))
                ;

    /* Set page table base. */
    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x0038C,
        (gctUINT32)(Hardware->pagetableArray.address & 0xFFFFFFFF)
        );

    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x00390,
        (gctUINT32)((Hardware->pagetableArray.address >> 32) & 0xFFFFFFFF)
        );

    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x00394
,
        1
        );

    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x0039C,
        (gctUINT32)(secureSafeAddress & 0xFFFFFFFF)
        );

    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x00398,
        (gctUINT32)(nonSecureSafeAddress & 0xFFFFFFFF)
        );

    gctaOS_WriteRegister(
        Hardware->ta->os, Hardware->ta->core,
        0x003A0,
        (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 23:16) - (0 ?
 23:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 23:16) - (0 ?
 23:16) + 1))))))) << (0 ?
 23:16))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((secureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
 23:16) - (0 ?
 23:16) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 23:16) - (0 ?
 23:16) + 1))))))) << (0 ?
 23:16))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 31:31) - (0 ?
 31:31) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 31:31) - (0 ?
 31:31) + 1))))))) << (0 ?
 31:31))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
 31:31) - (0 ?
 31:31) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 31:31) - (0 ? 31:31) + 1))))))) << (0 ? 31:31))))
      | (((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 7:0) - (0 ?
 7:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 7:0) - (0 ?
 7:0) + 1))))))) << (0 ?
 7:0))) | (((gctUINT32) ((gctUINT32) ((gctUINT32)((nonSecureSafeAddress >> 32) & 0xFFFFFFFF)) & ((gctUINT32) ((((1 ?
 7:0) - (0 ?
 7:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 7:0) - (0 ?
 7:0) + 1))))))) << (0 ?
 7:0))) &((((gctUINT32) (~0U)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 15:15) - (0 ?
 15:15) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 15:15) - (0 ?
 15:15) + 1))))))) << (0 ?
 15:15))) | (((gctUINT32) (0x0 & ((gctUINT32) ((((1 ?
 15:15) - (0 ?
 15:15) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 15:15) - (0 ? 15:15) + 1))))))) << (0 ? 15:15))))
        );

    /* Execute prepared command sequence. */
    gctaHARDWARE_Execute(
        Hardware->ta,
        function->address,
        function->bytes
        );

    /* Wait until MMU configure finishes. */
    do
    {
        gctaOS_Delay(Hardware->os, delay);

        gctaOS_ReadRegister(
            Hardware->ta->os, Hardware->ta->core,
            0x00004,
            &idle);

        timer += delay;
        delay *= 2;
    }
    while (!(((((gctUINT32) (idle)) >> (0 ? 0:0)) & ((gctUINT32) ((((1 ? 0:0) - (0 ? 0:0) + 1) == 32) ? ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1)))))) ));

    /* Enable MMU. */
    gctaOS_WriteRegister(
        Hardware->os, Hardware->ta->core,
        0x00388,
        ((((gctUINT32) (0)) & ~(((gctUINT32) (((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ?
 0:0) - (0 ?
 0:0) + 1))))))) << (0 ?
 0:0))) | (((gctUINT32) (0x1 & ((gctUINT32) ((((1 ?
 0:0) - (0 ?
 0:0) + 1) == 32) ?
 ~0U : (~(~0U << ((1 ? 0:0) - (0 ? 0:0) + 1))))))) << (0 ? 0:0)))
        );

    return gcvSTATUS_OK;
}

gceSTATUS
gctaHARDWARE_PrepareFunctions(
    IN gcTA_HARDWARE Hardware
    )
{
    gceSTATUS status;
    gcsHARDWARE_FUNCTION * function;
    gctUINT32 mmuBytes;
    gctUINT32 endBytes = 8;
    gctUINT8_PTR logical;
    gctPHYS_ADDR_T physical;

    gcmkHEADER();

    /* Allocate page table array. */
    gcmkONERROR(gctaOS_AllocateSecurityMemory(
        Hardware->ta->os,
        &Hardware->pagetableArray.size,
        &Hardware->pagetableArray.logical,
        &Hardware->pagetableArray.physical
        ));

    gcmkONERROR(gctaOS_GetPhysicalAddress(
        Hardware->ta->os,
        Hardware->pagetableArray.logical,
        &Hardware->pagetableArray.address
        ));

    /* Allocate GPU functions. */
    gcmkONERROR(gctaOS_AllocateSecurityMemory(
        Hardware->ta->os,
        &Hardware->functionBytes,
        &Hardware->functionLogical,
        &Hardware->functionPhysical
        ));

    gcmkONERROR(gctaOS_GetPhysicalAddress(
        Hardware->ta->os,
        Hardware->functionLogical,
        &physical
        ));

    gcmkSAFECASTPHYSADDRT(Hardware->functionAddress, physical);

    function = &Hardware->functions[0];

    function->logical = Hardware->functionLogical;

    function->address = Hardware->functionAddress;

    logical = function->logical;

    gcmkONERROR(gctaHARDWARE_SetMMUStates(
        Hardware,
        Hardware->ta->mmu->mtlbLogical,
        gcvMMU_MODE_4K,
        Hardware->ta->mmu->safePageLogical,
        logical,
        &mmuBytes
        ));

    logical += 8;

    gcmkONERROR(gctaHARDWARE_End(
        Hardware,
        logical,
        &endBytes
        ));

    function->bytes = mmuBytes + endBytes;

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;

OnError:
    gcmkFOOTER();
    return status;
}

gceSTATUS
gctaHARDWARE_IsFeatureAvailable(
    IN gcTA_HARDWARE Hardware,
    IN gceFEATURE Feature
    )
{
    gctBOOL available;
    gcsFEATURE_DATABASE *database = Hardware->featureDatabase;

    switch (Feature)
    {
    case gcvFEATURE_SECURITY:
        available = database->SECURITY;
        break;
    default:
        gcmkFATAL("Invalid feature has been requested.");
        available = gcvFALSE;
    }

    return available;
}

gceSTATUS
gctaHARDWARE_DumpMMUException(
    IN gcTA_HARDWARE Hardware
    )
{
    gctUINT32 mmu       = 0;
    gctUINT32 mmuStatus = 0;
    gctUINT32 address   = 0;
    gctUINT32 i         = 0;

    gctUINT32 mmuStatusRegAddress;
    gctUINT32 mmuExceptionAddress;

    gcmkHEADER_ARG("Hardware=0x%x", Hardware);

    mmuStatusRegAddress = 0x00384;
    mmuExceptionAddress = 0x00380;

    /* Verify the arguments. */
    gcmkVERIFY_OBJECT(Hardware, gcvOBJ_HARDWARE);

    gcmkPRINT("ChipModel=0x%x ChipRevision=0x%x:\n",
              Hardware->chipModel,
              Hardware->chipRevision);

    gcmkPRINT("**************************\n");
    gcmkPRINT("***   MMU ERROR DUMP   ***\n");
    gcmkPRINT("**************************\n");

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        Hardware->os, Hardware->ta->core,
        mmuStatusRegAddress
,
        &mmuStatus
        ));

    gcmkPRINT("  MMU status = 0x%08X\n", mmuStatus);

    for (i = 0; i < 4; i += 1)
    {
        mmu = mmuStatus & 0xF;
        mmuStatus >>= 4;

        if (mmu == 0)
        {
            continue;
        }

        switch (mmu)
        {
        case 1:
              gcmkPRINT("  MMU%d: slave not present\n", i);
              break;

        case 2:
              gcmkPRINT("  MMU%d: page not present\n", i);
              break;

        case 3:
              gcmkPRINT("  MMU%d: write violation\n", i);
              break;

        case 4:
              gcmkPRINT("  MMU%d: out of bound", i);
              break;

        case 5:
              gcmkPRINT("  MMU%d: read security violation", i);
              break;

        case 6:
              gcmkPRINT("  MMU%d: write security violation", i);
              break;

        default:
              gcmkPRINT("  MMU%d: unknown state\n", i);
        }

        gcmkVERIFY_OK(gctaOS_ReadRegister(
            Hardware->os, Hardware->ta->core,
            mmuExceptionAddress + i * 4
,
            &address
            ));

        gcmkPRINT("  MMU%d: exception address = 0x%08X\n", i, address);

        gctaMMU_DumpPagetableEntry(Hardware->ta->mmu, address);
    }

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

gceSTATUS
gctaHARDWARE_ReadMMUException(
    IN gcTA_HARDWARE Hardware,
    OUT gctUINT32_PTR MMUStatus,
    OUT gctUINT32_PTR MMUException
    )
{
    gctUINT32 mmuStatusRegAddress;
    gctUINT32 mmuExceptionAddress;

    gcmkHEADER_ARG("Hardware=0x%x", Hardware);

    mmuStatusRegAddress = 0x00384;
    mmuExceptionAddress = 0x00380;

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        Hardware->os, Hardware->ta->core,
        mmuStatusRegAddress
,
        MMUStatus
        ));

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        Hardware->os, Hardware->ta->core,
        mmuExceptionAddress
,
        MMUException
        ));

    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

gceSTATUS
gctaHARDWARE_HandleMMUException(
    IN gcTA_HARDWARE Hardware,
    IN gctUINT32 MMUStatus,
    IN gctPHYS_ADDR_T Physical,
    IN gctUINT32 GPUAddress
    )
{
    gctUINT32 mmu       = 0;
    gctUINT32 mmuStatus = 0;
    gctUINT32 mtlbEntry = 0;
    gctUINT32_PTR stlbEntry;
    gctBOOL secure;

    gctUINT32 mmuStatusRegAddress;
    gctUINT32 mmuExceptionAddress;

    gcmkHEADER_ARG("Hardware=0x%x", Hardware);

    mmuStatusRegAddress = 0x00384;
    mmuExceptionAddress = 0x00380;

    gcmkVERIFY_OK(gctaOS_ReadRegister(
        Hardware->os, Hardware->ta->core,
        mmuStatusRegAddress
,
        &mmuStatus
        ));

    mmu = mmuStatus & 0xF;

    /* Setup page table. */

    gctaMMU_GetPageEntry(
        Hardware->ta->mmu,
        GPUAddress,
        &mtlbEntry,
        &stlbEntry,
        &secure
        );

    gctaMMU_SetPage(
        Hardware->ta->mmu,
        (gctUINT32)Physical,
        stlbEntry
        );

    switch (mmu)
    {
    case 1:
        gcmkASSERT(mtlbEntry != 0);
        gctaOS_WriteRegister(
            Hardware->os, Hardware->ta->core,
            mmuExceptionAddress
,
            mtlbEntry
            );

        break;

    case 2:
         gctaOS_WriteRegister(
            Hardware->os, Hardware->ta->core,
            mmuExceptionAddress
,
            *stlbEntry
            );
        break;

    default:
        gcmkASSERT(0);
    }


    gcmkFOOTER_NO();
    return gcvSTATUS_OK;
}

