/*==============================================================================
Copyright(c) 2019 Intel 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.

Description: Contains functions of internal classes 
             (ie PageTablePool, PageTable, Table), that support
             user mode page table management

============================================================================*/

#include "Internal/Common/GmmLibInc.h"
#include "../TranslationTable/GmmUmdTranslationTable.h"
#include "Internal/Common/Texture/GmmTextureCalc.h"

#if !defined(__GMM_KMD)

#if defined(__linux__) || defined(__Fuchsia__)
#include "Internal/Linux/GmmResourceInfoLinInt.h"

#define _aligned_free(ptr) free(ptr)

#endif

//=============================================================================
//
// Function: AllocateL3Table
//
// Desc: Allocates (always resident SVM) memory for AUXTT\L3 Table, and updates AUXTT object
//
// Parameters:
//      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
//
// Returns:
//      GMM_SUCCESS on success,
//      GMM_INVALIDPARAM on invalid parameter(s)
//      GMM_OUT_OF_MEMORY on memory allocation failure, failure to make resident
//-----------------------------------------------------------------------------
GMM_STATUS GmmLib::PageTable::AllocateL3Table(uint32_t L3TableSize, uint32_t L3AddrAlignment)
{
    GMM_STATUS       Status = GMM_SUCCESS;
    GMM_DEVICE_ALLOC Alloc  = {0};

    __GMM_ASSERTPTR(PageTableMgr, GMM_INVALIDPARAM);

    EnterCriticalSection(&TTLock);

    Alloc.Size      = L3TableSize;
    Alloc.Alignment = L3AddrAlignment;
    Alloc.hCsr      = PageTableMgr->hCsr;

    Status = __GmmDeviceAlloc(pClientContext, &PageTableMgr->DeviceCbInt, &Alloc);
    if(Status != GMM_SUCCESS)
    {
        LeaveCriticalSection(&TTLock);
        return Status;
    }

    TTL3.GfxAddress         = GMM_GFX_ADDRESS_CANONIZE(Alloc.GfxVA);
    TTL3.CPUAddress         = Alloc.CPUVA;
    TTL3.NeedRegisterUpdate = true;
    TTL3.L3Handle           = (HANDLE)(uintptr_t)Alloc.Handle;
    TTL3.pGmmResInfo        = (GMM_RESOURCE_INFO *)Alloc.Priv;

    // Invalidate L3e's
    for(int i = 0; i < (GMM_L3_SIZE(TTType)); i++)
    {
        //initialize L3e ie mark all entries with Null tile/invalid value
        ((GMM_AUXTTL3e *)TTL3.CPUAddress)[i].Value = 0;

    }

    LeaveCriticalSection(&TTLock);
    return Status;
}

//=============================================================================
//
// Function: __IsUnusedTRTTPoolOverLimit
//
// Desc: Checks if unused TRTTPools have reached residency limit and must be freed.
//
// Parameters:
//      pTRTT_Obj: per-device TT object. Contains TT node info
//      OverLimitSize: Size in bytes that can be freed
//
// Returns:
//      True, if unused TTPool reached max. residency limit
//      False, otherwise
//-----------------------------------------------------------------------------
bool GmmLib::GmmPageTablePool::__IsUnusedTRTTPoolOverLimit(GMM_GFX_SIZE_T *OverLimitSize)
{
    GMM_GFX_SIZE_T             UnusedTrTTPoolSize = 0;
    GmmLib::GMM_PAGETABLEPool *Pool               = NULL;

    Pool = this;

    while(Pool)
    {
        if(Pool->NumFreeNodes == PAGETABLE_POOL_MAX_NODES)
        {
            UnusedTrTTPoolSize += PAGETABLE_POOL_SIZE;
        }
        Pool = Pool->NextPool;
    }

    *OverLimitSize = (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? (UnusedTrTTPoolSize - PAGETABLE_POOL_MAX_UNUSED_SIZE) : 0;
    return (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? true : false;
}

//=============================================================================
//
// Function: AllocateL1L2Table
//
// Desc: Assigns pages from AUXTTPool for L1/L2Table for translation of given TRVA
//
// Parameters:
//      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
//      TileAddr: Tiled Resource Virtual address
//
// Returns:
//     L2Table/L1Table Address
//-----------------------------------------------------------------------------
void GmmLib::PageTable::AllocateL1L2Table(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
{
    GMM_GFX_ADDRESS         L3TableAdr = GMM_NO_TABLE;
    uint32_t                L3eIdx     = static_cast<uint32_t>(GMM_L3_ENTRY_IDX(TTType, TileAddr));
    uint32_t                L2eIdx     = static_cast<uint32_t>(GMM_L2_ENTRY_IDX(TTType, TileAddr));
    GmmLib::LastLevelTable *pL1Tbl     = NULL;

    *L2TableAdr = GMM_NO_TABLE;
    *L1TableAdr = GMM_NO_TABLE;

    if(TTL3.L3Handle)
    {
        L3TableAdr = TTL3.GfxAddress;
    }
    else
    {
        //Should never hit -- L3Table is allocated during device creation
        __GMM_ASSERT(false);
    }

    if(pTTL2[L3eIdx].GetPool())
    {
        GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
        PoolElem                            = pTTL2[L3eIdx].GetPool();
        *L2TableAdr                         = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pTTL2[L3eIdx].GetNodeIdx()) : GMM_NO_TABLE;
    }
    else
    {
        uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
        GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
        POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL2;
        PoolElem                               = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
        if(PoolElem)
        {
            pTTL2[L3eIdx] = MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
            *L2TableAdr   = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx must be multiple of 8 (Aux L2) and multiple of 2 (Aux L1)
            ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
        }
    }

    pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
    if(pL1Tbl)
    {
        GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
        PoolElem                            = pL1Tbl->GetPool();
        *L1TableAdr                         = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pL1Tbl->GetNodeIdx()) : GMM_NO_TABLE;
    }
    else
    {
        //Allocate L1 Table
        uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
        GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
        POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL1;

        PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
        if(PoolElem)
        {
            pL1Tbl = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, pGmmGlobalContext), L2eIdx); //use Aux L1_Size_DWORD

            if(pL1Tbl)
            {
                *L1TableAdr = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx should reflect 1 node per Tr-table and 2 nodes per AUX L1 TABLE
                if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
                {
                    uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
                    ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
                }
                pTTL2[L3eIdx].InsertInList(pL1Tbl);
            }
        }
    }
}

//=============================================================================
//
// Function: AllocateDummyTables
//
// Desc: Assigns pages from AUXTTPool for Dummy L1/L2Table
//
// Parameters:
//     L2Table - Ptr to initiatize dummy L2Table
//     L1Table - Ptr to initiatize dummy L1Table
//
// Returns:
//     L2Table/L1Tables
//-----------------------------------------------------------------------------
void GmmLib::PageTable::AllocateDummyTables(GmmLib::Table **L2Table, GmmLib::Table **L1Table)
{
    GMM_GFX_ADDRESS         L3TableAdr = GMM_NO_TABLE;
    GmmLib::LastLevelTable *pL1Tbl     = NULL;

    if(TTL3.L3Handle)
    {
        L3TableAdr = TTL3.GfxAddress;
    }
    else
    {
        //Should never hit -- L3Table is allocated during device creation
        __GMM_ASSERT(false);
    }

    //Allocate dummy L2Table
    {
        uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
        GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
        POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL2;
        PoolElem                               = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
        if(PoolElem)
        {
            *L2Table = new GmmLib::MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
            ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
        }
    }

    //Allocate dummy L1Table
    {
        uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
        GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
        POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL1;

        PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
        if(PoolElem)
        {
            *L1Table = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, pGmmGlobalContext), 0); //use Aux L1_Size_DWORD

            if(*L1Table)
            {
                if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
                {
                    uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
                    ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
                }
            }
        }
    }
}

//=============================================================================
//
// Function: GetL1L2TableAddr
//
// Desc: For given tile address, returns L1/L2 Table address if the table exists
//
// Parameters:
//      pAUXTT_Obj: per-device AUX-TT object. Contains AXUTT node info
//      TileAddr: Tiled Resource Virtual address
//
// Returns:
//     L2Table/L1Table Address
//-----------------------------------------------------------------------------
void GmmLib::PageTable::GetL1L2TableAddr(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
{
    GMM_GFX_SIZE_T  L3eIdx, L2eIdx, L1eIdx;
    GMM_GFX_ADDRESS L3TableAdr = GMM_NO_TABLE;
    *L2TableAdr                = GMM_NO_TABLE;
    *L1TableAdr                = GMM_NO_TABLE;

    L3eIdx = GMM_L3_ENTRY_IDX(TTType, TileAddr);
    L2eIdx = GMM_L2_ENTRY_IDX(TTType, TileAddr);
    L1eIdx = GMM_L1_ENTRY_IDX(TTType, TileAddr, pGmmGlobalContext);

    __GMM_ASSERT(TTL3.L3Handle);
    L3TableAdr = TTL3.GfxAddress;
    if(pTTL2[L3eIdx].GetPool())
    {
        GmmLib::GMM_PAGETABLEPool *Pool   = NULL;
        GmmLib::LastLevelTable *   pL1Tbl = NULL;
        Pool                              = pTTL2[L3eIdx].GetPool();

        if(Pool)
        {
            __GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
            __GMM_ASSERT(pTTL2[L3eIdx].GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
            __GMM_ASSERT(Pool->GetNodeUsageAtIndex(pTTL2[L3eIdx].GetNodeIdx() / (32 * NodesPerTable)) != 0);

            *L2TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pTTL2[L3eIdx].GetNodeIdx());
        }

        pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
        if(pL1Tbl && pL1Tbl->GetPool())
        {
            Pool = NULL;
            Pool = pL1Tbl->GetPool();
            if(Pool)
            {
                uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES : 1;
                __GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
                __GMM_ASSERT(pL1Tbl->GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
                __GMM_ASSERT(Pool->GetNodeUsageAtIndex(pL1Tbl->GetNodeIdx() / (32 * PerTableNodes)) != 0);

                *L1TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pL1Tbl->GetNodeIdx());
            }
        }
    }
}

//=============================================================================
//
// Function: GetMappingType
//
// Desc: For given gfx address and size, returns MappingType (null/non-null or
//       Valid/Invalid) of GfxVA and first gfx address have reverse mapping
//
/// @param[in] GfxVA: Gfx Address whose mapping type is being queried
/// @param[in] Size:  Size of interested Gfx address range
/// @param[out] LastAddr : 1st Gfx Address having reverse mapping type
//
/// @return    1/0 : for non-null/valid vs null/invalid mapping
//-----------------------------------------------------------------------------
uint8_t GmmLib::PageTable::GetMappingType(GMM_GFX_ADDRESS GfxVA, GMM_GFX_SIZE_T Size, GMM_GFX_ADDRESS &LastAddr)
{
    GMM_GFX_SIZE_T  L3eIdx, L2eIdx, L1eIdx, L1EntrySize;
    uint8_t         MapType      = 0; //true for non-null, false for null mapped
    bool            bFoundLastVA = false, bTerminate = false;
    GMM_GFX_ADDRESS TileAddr = GfxVA;

    L3eIdx      = GMM_L3_ENTRY_IDX(TTType, GfxVA);
    L2eIdx      = GMM_L2_ENTRY_IDX(TTType, GfxVA);
    L1eIdx      = GMM_L1_ENTRY_IDX(TTType, GfxVA, pGmmGlobalContext);
    L1EntrySize = !WA16K ? GMM_KBYTE(64) : GMM_KBYTE(16);

    EnterCriticalSection(&TTLock);
    __GMM_ASSERT(TTL3.L3Handle);

#define GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx) \
    {                                            \
        L1eIdx = 0;                              \
        L2eIdx++;                                \
        if(L2eIdx == (GMM_L2_SIZE(TTType)))      \
        {                                        \
            L2eIdx = 0;                          \
            L3eIdx++;                            \
            if(L3eIdx == (GMM_L3_SIZE(TTType)))  \
            {                                    \
                bTerminate = true;               \
            }                                    \
        }                                        \
    }

#define GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx) \
    {                                            \
        L1eIdx = L2eIdx = 0;                     \
        L3eIdx++;                                \
        if(L3eIdx == (GMM_L3_SIZE(TTType)))      \
        {                                        \
            bTerminate = true;                   \
        }                                        \
    }

    while(!(bFoundLastVA || bTerminate) && (TileAddr < GfxVA + Size))
    {
        if(pTTL2[L3eIdx].GetPool())
        {
            GmmLib::LastLevelTable *pL1Tbl = NULL;
            pL1Tbl                         = pTTL2[L3eIdx].GetL1Table(L2eIdx);
            if(pL1Tbl && pL1Tbl->GetPool())
            {
                uint32_t LastBit = 0;
                uint32_t i       = static_cast<uint32_t>(L1eIdx) / 32;

                while(!bFoundLastVA && i < (uint32_t)(GMM_L1_SIZE_DWORD(TTType, pGmmGlobalContext)))
                {
                    uint32_t UsageDW = pL1Tbl->GetUsedEntries()[i++];
                    uint32_t BitNum  = 31;
                    if(GfxVA == TileAddr)
                    {
                        BitNum  = L1eIdx % 32;
                        MapType = ((UsageDW & __BIT(BitNum)) ? 0x1 : 0x0); //true for non-null, false for null mapped
                        UsageDW = (!MapType) ? UsageDW : ~UsageDW;
                        UsageDW = ((uint64_t)UsageDW >> (BitNum + 1)) << (BitNum + 1); // clear lsb <= BitNum
                    }
                    else
                    {
                        UsageDW = (!MapType) ? UsageDW : ~UsageDW;
                    }

                    if(_BitScanForward((uint32_t *)&LastBit, UsageDW)) // Gets lsb > BitNum, having reverse mapType
                    {
                        bFoundLastVA      = true;
                        uint32_t NumTiles = (GfxVA == TileAddr) ? (LastBit - BitNum) : LastBit;
                        LastAddr          = TileAddr + NumTiles * L1EntrySize;
                    }
                    else
                    {
                        uint32_t NumTiles = (GfxVA == TileAddr) ? (32 - BitNum) : 32;
                        TileAddr += NumTiles * L1EntrySize;
                    }
                }
                if(!bFoundLastVA)
                {
                    GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx);
                }
            }
            else //L2Entry is NULL
            {
                if(MapType) //First hit null-map
                {
                    LastAddr     = TileAddr;
                    bFoundLastVA = true;
                }
                else
                {
                    GMM_GFX_SIZE_T NumTiles = GMM_L1_SIZE(TTType, pGmmGlobalContext);
                    if(GfxVA == TileAddr)
                    {
                        MapType = false;
                        NumTiles -= L1eIdx;
                    }
                    TileAddr += NumTiles * L1EntrySize;
                    GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx)
                }
            }
        }
        else //L3entry is NULL
        {
            if(MapType) //First hit null-map
            {
                LastAddr     = TileAddr;
                bFoundLastVA = true;
            }
            else
            {
                GMM_GFX_SIZE_T NumTiles = 0;
                if(GfxVA == TileAddr)
                {
                    MapType  = false;
                    NumTiles = (GMM_L2_SIZE(TTType) - L2eIdx) * (GMM_L1_SIZE(TTType, pGmmGlobalContext) - L1eIdx);
                }
                else
                {
                    NumTiles = ((GMM_L2_SIZE(TTType)) * (GMM_L1_SIZE(TTType, pGmmGlobalContext)));
                }
                TileAddr += NumTiles * L1EntrySize;
                GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx)
            }
        }
    }

    if(!bFoundLastVA)
    {
        LastAddr = TileAddr;
    }

    LeaveCriticalSection(&TTLock);
    return MapType;
}

//=============================================================================
//
// Function: TrackTableUsage
//
// Desc: For given tile address, updates Table Usage.If Table has all Nullmappings
//       then its pool node can be unassigned
//
// Parameters:
//      Type:  Translation Table type (Aux)
//      IsL1:  Is called for L1table or L2 Table
//      TileAddr: Tiled Resource Virtual address
//      NullMapped: true if given tiled adr was null mapped, otherwise false
//
// Returns:
//     true, if Table for given tile adr is all null mapped
//     false,if Table does not exist or has non-null mapping
//-----------------------------------------------------------------------------
bool GmmLib::Table::TrackTableUsage(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, bool NullMapped)
{
    uint32_t EntryIdx;
    uint32_t ElemNum = 0, BitNum = 0;

    EntryIdx = IsL1 ? static_cast<uint32_t>(GMM_L1_ENTRY_IDX(Type, TileAdr, pGmmGlobalContext)) : static_cast<uint32_t>(GMM_L2_ENTRY_IDX(Type, TileAdr));

    ElemNum = EntryIdx / (sizeof(UsedEntries[0]) * 8);
    BitNum  = EntryIdx % (sizeof(UsedEntries[0]) * 8);

    if(NullMapped)
    {
        UsedEntries[ElemNum] &= ~(1 << BitNum);
    }
    else
    {
        UsedEntries[ElemNum] |= (1 << BitNum);
    }

    if(NullMapped)
    {
        int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type, pGmmGlobalContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
        for(int i = 0; i < TableDWSize; i++)
        {
            if(UsedEntries[i])
            {
                return false;
            }
        }
    }
    return NullMapped ? true : false;
}

//=============================================================================
//
// Function: __IsTableNullMapped
//
// Desc: For given tile address, checks if given Table has all Nullmappings
//       then its pool node can be unassigned
//
// Parameters:
//      Type:  Translation Table type (TR or Aux)
//      IsL1:  Is called for L1table or L2 Table
//      TileAddr: Tiled Resource Virtual address
//
// Returns:
//     true, if Table for given tile adr is all null mapped
//     false,if Table has non-null mapping
//-----------------------------------------------------------------------------
bool GmmLib::Table::IsTableNullMapped(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr)
{
    GMM_UNREFERENCED_PARAMETER(TileAdr);
    int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type, pGmmGlobalContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
    for(int i = 0; i < TableDWSize; i++)
    {
        if(UsedEntries[i])
        {
            return false;
        }
    }
    return true;
}

//=============================================================================
//
// Function: __UpdatePoolFence
//
// Desc: Updates AUXTTPool's or Table's BBFenceObj/value with current BB fence
//
// Parameters:
//      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
//      Table:     L1/L2 table pointer
//      L1Table:   true for L1 Table, else false
//      ClearNode: if true, Fence info is cleared for table
//                    false, Fence info is updated for table and pool
//-----------------------------------------------------------------------------
void GmmLib::Table::UpdatePoolFence(GMM_UMD_SYNCCONTEXT *UmdContext, bool ClearNode)
{
    if(!ClearNode)
    {
        //update both node and pool with current fence/handle
        PoolElem->GetPoolBBInfo().BBQueueHandle =
        BBInfo.BBQueueHandle = UmdContext->BBFenceObj;
        PoolElem->GetPoolBBInfo().BBFence =
        BBInfo.BBFence = UmdContext->BBLastFence + 1; //Save incremented fence value, since DX does it during submission
    }
    else
    {
        //Clear node fence/handle
        BBInfo.BBQueueHandle = 0;
        BBInfo.BBFence       = 0;
    }
}

/////////////////////////////////////////////////////////////////////////////////////
/// Releases all PageTable Pool(s) existing in Linked List
///
/// @param[in]  DeviceCallbacks   pointer to device callbacks structure
/// @return     GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::GmmPageTablePool::__DestroyPageTablePool(void *DeviceCallbacks, HANDLE hCsr)
{
    GMM_STATUS                Status   = GMM_SUCCESS;
    GMM_DEVICE_CALLBACKS_INT *DeviceCb = static_cast<GMM_DEVICE_CALLBACKS_INT *>(DeviceCallbacks);

    GMM_PAGETABLEPool *Node = this, *Next = NULL;
    GMM_CLIENT         ClientType;
    GMM_DEVICE_DEALLOC Dealloc = {0};

    //Evict/Free gpu Va is implictly done by OS when de-allocating
    while(Node)
    {
        Next = Node->NextPool;

        GET_GMM_CLIENT_TYPE(Node->pClientContext, ClientType);

        Dealloc.Handle = Node->PoolHandle;
        Dealloc.GfxVA  = Node->PoolGfxAddress;
        Dealloc.Priv   = Node->pGmmResInfo;
        Dealloc.hCsr   = hCsr;

        Status = __GmmDeviceDealloc(ClientType, DeviceCb, &Dealloc);

        Node->PoolHandle     = NULL;
        Node->PoolGfxAddress = 0;
        delete Node;
        Node = Next;
    }

    return Status;
}

/////////////////////////////////////////////////////////////////////////////////////
/// Releases memory allocated to PageTable's Root-table
///
/// @return     GMM_STATUS
/////////////////////////////////////////////////////////////////////////////////////
GMM_STATUS GmmLib::PageTable::DestroyL3Table()
{
    GMM_STATUS         Status = GMM_SUCCESS;
    uint8_t            hr     = GMM_SUCCESS;
    GMM_CLIENT         ClientType;
    GMM_DEVICE_DEALLOC Dealloc = {0};

    GET_GMM_CLIENT_TYPE(pClientContext, ClientType);

    EnterCriticalSection(&TTLock);

    if(TTL3.L3Handle)
    {
        Dealloc.Handle = TTL3.L3Handle;
        Dealloc.GfxVA  = TTL3.GfxAddress;
        Dealloc.Priv   = TTL3.pGmmResInfo;
        Dealloc.hCsr   = PageTableMgr->hCsr;

        Status = __GmmDeviceDealloc(ClientType, &PageTableMgr->DeviceCbInt, &Dealloc);

        TTL3.L3Handle   = NULL;
        TTL3.GfxAddress = 0;
        TTL3.CPUAddress = 0;
    }

    LeaveCriticalSection(&TTLock);
    return Status;
}

#endif //!__GMM_KMD
