// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//  »Project«   Talina Gaming System (TgS) (∂)
//  »File«      TgS (XB2) Common - Mem MGR.c
//  »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
//  »Version«   4.0
// ------------------------------------------------------------------------------------------------------------------------------ //
//  Copyright: © 2002-2010, Andrew Aye.  All Rights Reserved.
//  This software is free for non-commercial use. Redistribution and use in source and binary forms, with or without modification,
//  are permitted provided that the following conditions are met: 
//    Redistributions of source code must retain this copyright notice, this list of conditions and the following disclaimers. 
//    Redistributions in binary form must reproduce this copyright notice, this list of conditions and the following
//      disclaimers in the documentation and other materials provided with the distribution. 
//  Neither the names of the copyright owner nor the names of its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission. 
//  The intellectual property rights of the algorithms used reside with Andrew Aye.  You may not use this software, in whole or
//  in part, in support of any commercial product without the express written consent of the author.
//  There is no warranty or other guarantee of fitness of this software for any purpose. It is provided solely "as is".
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //


// START TGS - MEMORY //////////////////////////////////////////////////////////////////////////////////////////////////////////////

P_TgUINT08 PM_Init_Scratch()
{
    PC_TgUINT08 pScratchMemory = (P_TgUINT08)XPhysicalAlloc(
        XLOCKL2_LOCK_SIZE_1_WAY, MAXULONG_PTR, XLOCKL2_LOCK_SIZE_1_WAY, PAGE_READWRITE | MEM_LARGE_PAGES
    );

    TgCOMPILER_ASSERT_MSG( KTgMaxScratch_Size == XLOCKL2_LOCK_SIZE_1_WAY, "Scratch size does not match L2 lock size" )
    TgCRITICAL( NULL != pScratchMemory );

    TgVERIFY(TRUE == XLockL2( XLOCKL2_INDEX_XPS, pScratchMemory, XLOCKL2_LOCK_SIZE_1_WAY, XLOCKL2_LOCK_SIZE_1_WAY, 0 ));

    return (pScratchMemory);
}


TgVOID PM_Free_Scratch( PC_TgUINT08 pScratchMemory )
{
    XUnlockL2(XLOCKL2_INDEX_XPS);

    if (NULL != pScratchMemory)
    {
        XPhysicalFree( pScratchMemory );
    };
}


TgSINT32 PM_Page_Size()
{
    return (64*1024);
}


P_TgVOID PM_Virtual_Reserve( C_TgUINT32 iSize, C_TgBOOL bTemp )
{
    return (VirtualAlloc( NULL, iSize, MEM_RESERVE | MEM_LARGE_PAGES | (bTemp ? MEM_TOP_DOWN : 0), PAGE_READWRITE ));
}


P_TgVOID PM_Virtual_Commit( PC_TgVOID pMem, C_TgUINT32 iSize )
{
    PC_TgVOID pCheck = VirtualAlloc( pMem, iSize, MEM_COMMIT | MEM_LARGE_PAGES | MEM_NOZERO, PAGE_READWRITE );
    TgCRITICAL( (0 == pMem) || (pCheck == (P_TgVOID)((TgUINTPTR)pMem & ((TgUINTPTR)(~tgMM_Page_Size())))) );
    return (pCheck);
}


TgVOID PM_Virtual_Free( PC_TgVOID pMem )
{
    TgVERIFY( 0 != VirtualFree( pMem, 0, MEM_RELEASE ) );
}


P_TgVOID PM_Physical_Alloc( C_TgUINT32 iSize, C_TgSINT32 uiAlignment, C_TgUINT32 uiFlags )
{
    return (XPhysicalAlloc( iSize, MAXULONG_PTR, uiAlignment, uiFlags ));
}


TgVOID PM_Physical_Free( PC_TgVOID pMem )
{
    XPhysicalFree( pMem );
}


TgSIZE PM_Physical_Size( PC_TgVOID pMem )
{
    return (XPhysicalSize( pMem ));
}


LPVOID WINAPI XMemAlloc( SIZE_T dwSize, DWORD dwAllocAttributes )
{
    return (TgMALLOC_PHYSICAL( dwSize, dwAllocAttributes, 0 ));
}


void WINAPI XMemFree( PVOID pAddress, DWORD dwAllocAttributes )
{
    TgFREE_PHYSICAL( pAddress );
}


SIZE_T WINAPI XMemSize( PVOID pAddress, DWORD dwAllocAttributes )
{
    return (tgMM_Size_Physical( pAddress ));
}