mirror of https://github.com/intel/gmmlib.git
514 lines
18 KiB
C++
514 lines
18 KiB
C++
/*==============================================================================
|
|
Copyright(c) 2017 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.
|
|
============================================================================*/
|
|
|
|
#include "Internal/Common/GmmLibInc.h"
|
|
#include "External/Common/GmmCachePolicy.h"
|
|
|
|
//=============================================================================
|
|
//
|
|
// Function: __GmmGen8InitCachePolicy
|
|
//
|
|
// Desc: This function initializes the cache policy
|
|
//
|
|
// Parameters: pCachePolicy -> Ptr to array to be populated with the
|
|
// mapping of usages -> cache settings.
|
|
//
|
|
// Return: GMM_STATUS
|
|
//-----------------------------------------------------------------------------
|
|
GMM_STATUS GmmLib::GmmGen8CachePolicy::InitCachePolicy()
|
|
{
|
|
|
|
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
|
|
|
|
#define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
#include "GmmGen8CachePolicy.h"
|
|
|
|
{
|
|
// Gen8 Memory Object Definitions
|
|
#define MO_ELLC 0x0
|
|
#define MO_LLC 0x1
|
|
#define MO_LLC_ELLC 0x2
|
|
#define MO_L3_LLC_ELLC 0x3
|
|
|
|
#define MO_USE_PTE 0x0
|
|
#define MO_UC 0x1
|
|
#define MO_WT 0x2
|
|
#define MO_WB 0x3
|
|
|
|
// Define index of cache element
|
|
uint32_t Usage = 0;
|
|
|
|
// Process Cache Policy and fill in look up table
|
|
for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
|
|
{
|
|
bool CachePolicyError = false;
|
|
uint32_t PTEValue = 0;
|
|
|
|
if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC && pCachePolicy[Usage].L3)
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_L3_LLC_ELLC;
|
|
else if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC)
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_LLC_ELLC;
|
|
else if(pCachePolicy[Usage].ELLC)
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_ELLC;
|
|
else if(pCachePolicy[Usage].LLC)
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.TargetCache = MO_LLC;
|
|
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.Age = pCachePolicy[Usage].AGE;
|
|
|
|
if(pCachePolicy[Usage].WT)
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_WT;
|
|
// L3 is not included because WT vs UC vs WB only effects uncore
|
|
else if(!(pCachePolicy[Usage].LLC || pCachePolicy[Usage].ELLC))
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_UC;
|
|
|
|
else
|
|
pCachePolicy[Usage].MemoryObjectOverride.Gen8.CacheControl = MO_WB;
|
|
|
|
|
|
if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
|
|
{
|
|
CachePolicyError = true;
|
|
}
|
|
// On error, the PTE value is set to a UC PAT entry
|
|
pCachePolicy[Usage].PTE.DwordValue = PTEValue;
|
|
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
|
|
|
|
if(CachePolicyError)
|
|
{
|
|
GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
|
|
}
|
|
}
|
|
}
|
|
|
|
return GMM_SUCCESS;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Returns true if usage PTE entries are set for caching, false otherwise.
|
|
///
|
|
/// @param[in] Usage: type of usage
|
|
///
|
|
/// @return true if the usage PTE entry is set for cached, false otherwise.
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
uint8_t GMM_STDCALL GmmLib::GmmGen8CachePolicy::CachePolicyIsUsagePTECached(GMM_RESOURCE_USAGE_TYPE Usage)
|
|
{
|
|
GMM_UNREFERENCED_PARAMETER(Usage);
|
|
return 0;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
|
|
/// PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
|
|
/// PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
|
|
/// PAT2 = WB_MOCSLESS, with TC = eLLC+LLC
|
|
/// PAT3 = WB
|
|
/// PAT4 = WT
|
|
/// PAT5 = WC
|
|
/// PAT6 = WC
|
|
/// PAT7 = WC
|
|
/// HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
|
|
/// WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
|
|
/// Unused PAT's (5,6,7) are set to WC.
|
|
///
|
|
/// @return GMM_STATUS
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
GMM_STATUS GmmLib::GmmGen8CachePolicy::SetupPAT()
|
|
{
|
|
GMM_STATUS Status = GMM_SUCCESS;
|
|
#if(defined(__GMM_KMD__))
|
|
uint32_t i = 0;
|
|
|
|
GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
|
|
// No optional selection on Age or Target Cache because for an SVM-OS Age and
|
|
// Target Cache would not work [for an SVM-OS the Page Table is shared with IA
|
|
// and we don't have control of the PAT Idx]. If there is a strong ask from D3D
|
|
// or the performance analysis team, Age could be added.
|
|
// Add Class of Service when required.
|
|
GMM_GFX_TARGET_CACHE GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
|
|
uint8_t Age = 1;
|
|
uint8_t ServiceClass = 0;
|
|
int32_t * pPrivatePATTableMemoryType = NULL;
|
|
|
|
pPrivatePATTableMemoryType = pGmmGlobalContext->GetPrivatePATTableMemoryType();
|
|
|
|
__GMM_ASSERT(pGmmGlobalContext->GetSkuTable().FtrIA32eGfxPTEs);
|
|
|
|
for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
|
|
{
|
|
pPrivatePATTableMemoryType[i] = -1;
|
|
}
|
|
|
|
// Set values for GmmGlobalInfo PrivatePATTable
|
|
for(i = 0; i < GMM_NUM_PAT_ENTRIES; i++)
|
|
{
|
|
GMM_PRIVATE_PAT PAT = {0};
|
|
|
|
if(pGmmGlobalContext->GetWaTable().WaNoMocsEllcOnly)
|
|
{
|
|
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
|
|
}
|
|
else
|
|
{
|
|
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
|
|
}
|
|
|
|
switch(i)
|
|
{
|
|
case PAT0:
|
|
if(pGmmGlobalContext->GetWaTable().WaGttPat0)
|
|
{
|
|
if(pGmmGlobalContext->GetWaTable().WaGttPat0WB)
|
|
{
|
|
GfxMemType = GMM_GFX_WB;
|
|
if(GFX_IS_ATOM_PLATFORM)
|
|
{
|
|
PAT.PreGen10.Snoop = 1;
|
|
}
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
|
|
}
|
|
else
|
|
{
|
|
GfxMemType = GMM_GFX_UC_WITH_FENCE;
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
|
|
}
|
|
}
|
|
else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
|
|
{
|
|
GfxMemType = GMM_GFX_WB;
|
|
if(GFX_IS_ATOM_PLATFORM)
|
|
{
|
|
PAT.PreGen10.Snoop = 1;
|
|
}
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
|
|
}
|
|
break;
|
|
|
|
case PAT1:
|
|
if(pGmmGlobalContext->GetWaTable().WaGttPat0 && !pGmmGlobalContext->GetWaTable().WaGttPat0WB)
|
|
{
|
|
GfxMemType = GMM_GFX_WB;
|
|
if(GFX_IS_ATOM_PLATFORM)
|
|
{
|
|
PAT.PreGen10.Snoop = 1;
|
|
}
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
|
|
}
|
|
else
|
|
{
|
|
GfxMemType = GMM_GFX_UC_WITH_FENCE;
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
|
|
}
|
|
break;
|
|
|
|
case PAT2:
|
|
// This PAT idx shall be used for MOCS'Less resources like Page Tables
|
|
// Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
|
|
// For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
|
|
GfxMemType = GMM_GFX_WB;
|
|
|
|
if(pGmmGlobalContext->GetWaTable().WaNoMocsEllcOnly)
|
|
{
|
|
GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
|
|
}
|
|
else
|
|
{
|
|
GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
|
|
}
|
|
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
|
|
break;
|
|
|
|
case PAT3:
|
|
GfxMemType = GMM_GFX_WB;
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
|
|
break;
|
|
|
|
case PAT4:
|
|
GfxMemType = GMM_GFX_WT;
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
|
|
break;
|
|
|
|
case PAT5:
|
|
case PAT6:
|
|
case PAT7:
|
|
GfxMemType = GMM_GFX_WC;
|
|
pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
|
|
break;
|
|
|
|
default:
|
|
__GMM_ASSERT(0);
|
|
Status = GMM_ERROR;
|
|
}
|
|
|
|
PAT.PreGen10.MemoryType = GfxMemType;
|
|
PAT.PreGen10.TargetCache = GfxTargetCache;
|
|
PAT.PreGen10.Age = Age;
|
|
|
|
SetPrivatePATEntry(i, PAT);
|
|
}
|
|
|
|
#else
|
|
Status = GMM_ERROR;
|
|
#endif
|
|
return Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Initializes WA's needed for setting up the Private PATs
|
|
/// WaNoMocsEllcOnly, WaGttPat0, WaGttPat0GttWbOverOsIommuEllcOnly, WaGttPat0WB
|
|
///
|
|
/// @return GMM_STATUS
|
|
///
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
GMM_STATUS GmmLib::GmmGen8CachePolicy::SetPATInitWA()
|
|
{
|
|
GMM_STATUS Status = GMM_SUCCESS;
|
|
WA_TABLE * pWaTable = &const_cast<WA_TABLE &>(pGmmGlobalContext->GetWaTable());
|
|
|
|
#if(defined(__GMM_KMD__))
|
|
if(pGmmGlobalContext->GetGtSysInfoPtr()->EdramSizeInKb)
|
|
{
|
|
pWaTable->WaNoMocsEllcOnly = 1;
|
|
}
|
|
|
|
pWaTable->WaGttPat0 = 1;
|
|
pWaTable->WaGttPat0WB = 1;
|
|
pWaTable->WaGttPat0GttWbOverOsIommuEllcOnly = 1;
|
|
|
|
// Platforms which support OS-IOMMU.
|
|
if(pGmmGlobalContext->GetSkuTable().FtrWddm2Svm)
|
|
{
|
|
pWaTable->WaGttPat0GttWbOverOsIommuEllcOnly = 0;
|
|
pWaTable->WaGttPat0WB = 0;
|
|
}
|
|
|
|
#else
|
|
Status = GMM_ERROR;
|
|
#endif
|
|
|
|
return Status;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Returns the PAT idx that best matches the cache policy for this usage.
|
|
///
|
|
/// @param: CachePolicy: cache policy for a usage
|
|
///
|
|
/// @return PAT Idx to use in the PTE
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
uint32_t GmmLib::GmmGen8CachePolicy::BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)
|
|
{
|
|
uint32_t i;
|
|
uint32_t PATIdx = 0;
|
|
GMM_GFX_MEMORY_TYPE WantedMemoryType = GMM_GFX_UC_WITH_FENCE, MemoryType;
|
|
GMM_GFX_TARGET_CACHE WantedTC = GMM_GFX_TC_ELLC_LLC;
|
|
|
|
WantedMemoryType = GetWantedMemoryType(CachePolicy);
|
|
|
|
if(CachePolicy.LLC && CachePolicy.ELLC)
|
|
{
|
|
WantedTC = GMM_GFX_TC_ELLC_LLC;
|
|
}
|
|
else if(CachePolicy.LLC)
|
|
{
|
|
WantedTC = GMM_GFX_TC_LLC_ONLY;
|
|
}
|
|
else if(CachePolicy.ELLC)
|
|
{
|
|
WantedTC = GMM_GFX_TC_ELLC_ONLY; // Note: this overrides the MOCS target cache selection.
|
|
}
|
|
|
|
for(i = 1; i < GMM_NUM_PAT_ENTRIES; i++)
|
|
{
|
|
GMM_PRIVATE_PAT PAT1 = GetPrivatePATEntry(PATIdx);
|
|
GMM_PRIVATE_PAT PAT2 = GetPrivatePATEntry(i);
|
|
|
|
if(SelectNewPATIdx(WantedMemoryType, WantedTC,
|
|
(GMM_GFX_MEMORY_TYPE)PAT1.PreGen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT1.PreGen10.TargetCache,
|
|
(GMM_GFX_MEMORY_TYPE)PAT2.PreGen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT2.PreGen10.TargetCache))
|
|
{
|
|
PATIdx = i;
|
|
}
|
|
}
|
|
|
|
MemoryType = (GMM_GFX_MEMORY_TYPE)GetPrivatePATEntry(PATIdx).PreGen10.MemoryType;
|
|
|
|
if(MemoryType != WantedMemoryType)
|
|
{
|
|
// Failed to find a matching PAT entry
|
|
return GMM_PAT_ERROR;
|
|
}
|
|
return PATIdx;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Sets the GMM Private PAT in the PrivatePATTable for the PATIdx, GMM_PRIVATE_PAT
|
|
/// Entry passed
|
|
///
|
|
/// @param[in] PATIdx
|
|
/// @param[in] GMM_PRIVATE_PAT: PAT Entry
|
|
///
|
|
/// @return Pass/ fail
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
bool GmmLib::GmmGen8CachePolicy::SetPrivatePATEntry(uint32_t PATIdx, GMM_PRIVATE_PAT Entry)
|
|
{
|
|
if(PATIdx >= GMM_NUM_PAT_ENTRIES)
|
|
{
|
|
GMM_ASSERTDPF(false, "CRITICAL ERROR: INVALID PAT IDX");
|
|
return false;
|
|
}
|
|
#if(!defined(__GMM_KMD__))
|
|
GMM_UNREFERENCED_PARAMETER(Entry);
|
|
GMM_ASSERTDPF(false, "Should only be called from KMD");
|
|
return false;
|
|
#else
|
|
pGmmGlobalContext->GetPrivatePATTable()[PATIdx] = Entry;
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Gets the GMM Private PAT from the PrivatePATTable for the PATIdx passed
|
|
///
|
|
/// @param[in] PATIdx
|
|
///
|
|
/// @return GMM_PRIVATE_PAT: Entry
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
GMM_PRIVATE_PAT GmmLib::GmmGen8CachePolicy::GetPrivatePATEntry(uint32_t PATIdx)
|
|
{
|
|
GMM_PRIVATE_PAT NullPAT = {0};
|
|
|
|
if(PATIdx >= GMM_NUM_PAT_ENTRIES)
|
|
{
|
|
GMM_ASSERTDPF(false, "CRITICAL ERROR: INVALID PAT IDX");
|
|
return NullPAT;
|
|
}
|
|
|
|
#if(!defined(__GMM_KMD__))
|
|
return NullPAT;
|
|
#else
|
|
return pGmmGlobalContext->GetPrivatePATTable()[PATIdx];
|
|
#endif
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Return true if (MT2, TC2) is a better match for (WantedMT, WantedTC)
|
|
/// than (MT1, TC1)
|
|
///
|
|
/// @param[in] WantedMT: Wanted Memory Type
|
|
/// @param[in] WantedTC: Wanted Target Cache
|
|
/// @param[in] MT1: Memory Type for PATIdx1
|
|
/// @param[in] TC1: Target Cache for PATIdx1
|
|
/// @param[in] MT2: Memory Type for PATIdx2
|
|
/// @param[in] TC2: Target Cache for PATIdx2
|
|
///
|
|
/// @return Select the new PAT Index True/False
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
bool GmmLib::GmmGen8CachePolicy::SelectNewPATIdx(GMM_GFX_MEMORY_TYPE WantedMT, GMM_GFX_TARGET_CACHE WantedTC,
|
|
GMM_GFX_MEMORY_TYPE MT1, GMM_GFX_TARGET_CACHE TC1,
|
|
GMM_GFX_MEMORY_TYPE MT2, GMM_GFX_TARGET_CACHE TC2)
|
|
{
|
|
bool SelectPAT2 = false;
|
|
|
|
// select on Memory Type
|
|
if(MT1 != WantedMT)
|
|
{
|
|
if(MT2 == WantedMT || MT2 == GMM_GFX_UC_WITH_FENCE)
|
|
{
|
|
SelectPAT2 = true;
|
|
}
|
|
goto EXIT;
|
|
}
|
|
|
|
// select on Target Cache
|
|
if(WantedTC != TC1)
|
|
{
|
|
if(WantedMT == MT2 && WantedTC == TC2)
|
|
{
|
|
SelectPAT2 = true;
|
|
}
|
|
goto EXIT;
|
|
}
|
|
|
|
EXIT:
|
|
return SelectPAT2;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
/// Returns PTE value
|
|
///
|
|
/// @param[in] CachePolicyUsage: Cache Policy for Usage
|
|
///
|
|
/// @return true: success, false: failure
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
bool GmmLib::GmmGen8CachePolicy::GetUsagePTEValue(GMM_CACHE_POLICY_ELEMENT CachePolicyUsage,
|
|
uint32_t Usage,
|
|
uint32_t * pPTEDwordValue)
|
|
{
|
|
GMM_PTE_CACHE_CONTROL_BITS PTE = {0};
|
|
bool Success = true;
|
|
uint32_t PATIdx = 0;
|
|
|
|
// Don't setup PTE values in UMD
|
|
#if __GMM_KMD__
|
|
if((PATIdx = BestMatchingPATIdx(CachePolicyUsage)) == GMM_PAT_ERROR)
|
|
{
|
|
// IAe32 PAT table does not necessarily have an entry for WT memory type
|
|
// => not a cache policy init error if WT is unavailable.
|
|
Success = CachePolicyUsage.WT ? true : false;
|
|
|
|
// degrade to UC
|
|
{
|
|
GMM_CACHE_POLICY_ELEMENT CachePolicyElement = {0};
|
|
|
|
const char *MemTypes[4] = {"UC", "WC", "WT", "WB"}; // matches GMM_GFX_MEMORY_TYPE enum values
|
|
|
|
CachePolicyElement.Initialized = 1;
|
|
|
|
GMM_DPF(GFXDBG_CRITICAL,
|
|
"Cache Policy Init: Degrading PAT settings to UC (uncached) from %s for Element %d\n",
|
|
MemTypes[GetWantedMemoryType(CachePolicyUsage)], Usage);
|
|
|
|
PATIdx = BestMatchingPATIdx(CachePolicyElement);
|
|
if(PATIdx == GMM_PAT_ERROR)
|
|
{
|
|
Success = false;
|
|
}
|
|
}
|
|
}
|
|
if(PATIdx != GMM_PAT_ERROR)
|
|
{
|
|
PTE.Gen8.PAT = (PATIdx & __BIT(2)) ? 1 : 0;
|
|
PTE.Gen8.PCD = (PATIdx & __BIT(1)) ? 1 : 0;
|
|
PTE.Gen8.PWT = (PATIdx & __BIT(0)) ? 1 : 0;
|
|
}
|
|
else
|
|
{
|
|
PTE.DwordValue = 0x0;
|
|
}
|
|
#else
|
|
GMM_UNREFERENCED_PARAMETER(CachePolicyUsage);
|
|
GMM_UNREFERENCED_PARAMETER(Usage);
|
|
#endif
|
|
*pPTEDwordValue = PTE.DwordValue;
|
|
return Success;
|
|
} |