2024-06-21 00:31:14 +08:00
|
|
|
/*==============================================================================
|
|
|
|
Copyright(c) 2024 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"
|
|
|
|
#include "External/Common/CachePolicy/GmmCachePolicyXe2_LPG.h"
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// Function: GmmXe2_LPGCachePolicy::InitCachePolicy()
|
|
|
|
//
|
|
|
|
// Desc: This function initializes the Xe2 cache policy
|
|
|
|
//
|
|
|
|
// Return: GMM_STATUS
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
GMM_STATUS GmmLib::GmmXe2_LPGCachePolicy::InitCachePolicy()
|
|
|
|
{
|
|
|
|
__GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
|
|
|
|
|
|
|
|
#define DEFINE_CACHE_ELEMENT(usage, l3_cc, l3_clos, l1cc, l2cc, l4cc, coherency, igPAT, segov) DEFINE_CP_ELEMENT(usage, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, segov, 0, 0, l1cc, l2cc, l4cc, coherency, l3_cc, l3_clos, igPAT)
|
|
|
|
|
|
|
|
#include "GmmXe2_LPGCachePolicy.h"
|
|
|
|
|
|
|
|
SetUpMOCSTable();
|
|
|
|
SetupPAT();
|
|
|
|
|
|
|
|
// Define index of cache element
|
|
|
|
uint32_t Usage = 0;
|
2024-11-29 15:05:50 +08:00
|
|
|
uint32_t ReservedPATIdx = 16; /* Rsvd PAT section 16-19 */
|
|
|
|
uint32_t ReservedPATIdxEnd = 20;
|
2024-06-21 00:31:14 +08:00
|
|
|
|
|
|
|
#if (_WIN32 && (_DEBUG || _RELEASE_INTERNAL))
|
|
|
|
void *pKmdGmmContext = NULL;
|
|
|
|
#if (defined(__GMM_KMD__))
|
|
|
|
pKmdGmmContext = pGmmLibContext->GetGmmKmdContext();
|
|
|
|
#endif
|
|
|
|
OverrideCachePolicy(pKmdGmmContext);
|
|
|
|
#endif
|
|
|
|
// Process the cache policy and fill in the look up table
|
|
|
|
for (; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
|
|
|
|
{
|
|
|
|
bool CachePolicyError = false;
|
|
|
|
int32_t PATIdx = -1, CPTblIdx = -1, PATIdxCompressed = -1, CoherentPATIdx = -1;
|
|
|
|
uint32_t i, j;
|
|
|
|
GMM_XE2_PRIVATE_PAT UsagePATElement = {0};
|
|
|
|
GMM_CACHE_POLICY_TBL_ELEMENT UsageEle = {0};
|
|
|
|
GMM_PTE_CACHE_CONTROL_BITS PTE = {0};
|
|
|
|
|
|
|
|
// MOCS data
|
|
|
|
{
|
|
|
|
|
|
|
|
// Get L3 ,L4 and Convert GMM indicative values to actual regiser values.
|
|
|
|
GetL3L4(&UsageEle, &UsagePATElement, Usage);
|
|
|
|
// Convert L1 GMM indicative values to actual regiser values and store into pCachePolicy to return to UMD's.
|
|
|
|
SetL1CachePolicy(Usage);
|
|
|
|
|
|
|
|
if ((!pGmmLibContext->GetSkuTable().FtrL3TransientDataFlush) && (UsageEle.L3.PhysicalL3.L3CC == GMM_GFX_PHY_L3_MT_WB_XD))
|
|
|
|
{
|
|
|
|
UsageEle.L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_WB; // No Transient Flush Support
|
|
|
|
}
|
|
|
|
|
|
|
|
/* If MOCS is not needed fall back to Defer to PAT i.e MOCS#0 */
|
|
|
|
if (false == UsageEle.L3.PhysicalL3.igPAT)
|
|
|
|
{
|
|
|
|
/* Set cache policy index to defered to PAT i.e. MOCS Index 0 */
|
|
|
|
CPTblIdx = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* MOCS Index 1-3 are valid */
|
|
|
|
for (j = 1; j <= CurrentMaxMocsIndex; j++)
|
|
|
|
{
|
|
|
|
GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pGmmLibContext->GetCachePolicyTlbElement()[j];
|
|
|
|
if (UsageEle.L3.PhysicalL3.L4CC == TblEle->L3.PhysicalL3.L4CC &&
|
|
|
|
UsageEle.L3.PhysicalL3.L3CC == TblEle->L3.PhysicalL3.L3CC &&
|
|
|
|
UsageEle.L3.PhysicalL3.L3CLOS == TblEle->L3.PhysicalL3.L3CLOS &&
|
|
|
|
UsageEle.L3.PhysicalL3.igPAT == true)
|
|
|
|
{
|
|
|
|
CPTblIdx = j;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CPTblIdx == -1)
|
|
|
|
{
|
|
|
|
|
|
|
|
{
|
|
|
|
/* Invalid MOCS setting Fail the GMM Initialzation */
|
|
|
|
GMM_ASSERTDPF(false, "CRITICAL: Cache Policy Usage value for L3/L4 specified by Client is not defined in Fixed MOCS Table");
|
|
|
|
CachePolicyError = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Validate Caching restrictions as below
|
|
|
|
1. MemoryType WB-XD must be used in Non-Coherent and allowed only for displayable surfaces
|
|
|
|
2. Coherent mode(1-way/2-way) must be Memory Type WB
|
|
|
|
3. No 2-way coherency on dGPU
|
|
|
|
4. Memory Type WT is available only for L4 in Non Coherent Mode
|
|
|
|
5. Memory Type UC must be used in Non-Coherent Mode
|
|
|
|
*/
|
|
|
|
|
|
|
|
// PAT data
|
|
|
|
{
|
|
|
|
if (!pGmmLibContext->GetSkuTable().FtrL3TransientDataFlush && (UsagePATElement.Xe2.L3CC == GMM_GFX_PHY_L3_MT_WB_XD))
|
|
|
|
{
|
|
|
|
UsagePATElement.Xe2.L3CC = GMM_GFX_PHY_L3_MT_WB; // No Transient Flush Support
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find a PATIndex from the PAT table for uncompressed case*/
|
|
|
|
if ((UsagePATElement.Xe2.L4CC == GMM_GFX_PHY_L4_MT_WT) && (UsagePATElement.Xe2.L3CC == GMM_GFX_PHY_L3_MT_WB_XD))
|
|
|
|
{
|
|
|
|
|
2024-09-06 17:51:19 +08:00
|
|
|
// With L3:XD, L4:WT, NC combination
|
|
|
|
if (pGmmLibContext->GetSkuTable().FtrDiscrete)
|
|
|
|
{
|
|
|
|
// On BMG, L4 is a pass through, demote L4 to UC, keep L3 at XD
|
|
|
|
PATIdx = PAT6;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// On LNL, L3:XD is not needed
|
|
|
|
PATIdx = PAT13;
|
|
|
|
}
|
2024-06-21 00:31:14 +08:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i <= CurrentMaxPATIndex; i++)
|
|
|
|
{
|
|
|
|
GMM_PRIVATE_PAT PAT = GetPrivatePATEntry(i);
|
|
|
|
if (UsagePATElement.Xe2.L4CC == PAT.Xe2.L4CC &&
|
|
|
|
UsagePATElement.Xe2.Coherency == PAT.Xe2.Coherency &&
|
|
|
|
UsagePATElement.Xe2.L3CC == PAT.Xe2.L3CC &&
|
|
|
|
UsagePATElement.Xe2.L3CLOS == PAT.Xe2.L3CLOS &&
|
|
|
|
false == PAT.Xe2.LosslessCompressionEn)
|
|
|
|
{
|
|
|
|
PATIdx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find a PATIndex from the PAT table for compressed case*/
|
|
|
|
for (i = 0; i <= CurrentMaxPATIndex; i++)
|
|
|
|
{
|
|
|
|
GMM_PRIVATE_PAT PAT = GetPrivatePATEntry(i);
|
|
|
|
if (UsagePATElement.Xe2.L4CC == PAT.Xe2.L4CC &&
|
|
|
|
UsagePATElement.Xe2.Coherency == PAT.Xe2.Coherency &&
|
|
|
|
UsagePATElement.Xe2.L3CC == PAT.Xe2.L3CC &&
|
|
|
|
UsagePATElement.Xe2.L3CLOS == PAT.Xe2.L3CLOS &&
|
|
|
|
true == PAT.Xe2.LosslessCompressionEn)
|
|
|
|
{
|
|
|
|
PATIdxCompressed = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PATIdx == -1)
|
|
|
|
{
|
|
|
|
// Didn't find the caching settings in one of the already programmed PAT table entries.
|
|
|
|
// Need to add a new lookup table entry.
|
|
|
|
GMM_ASSERTDPF(
|
|
|
|
"Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
|
|
|
|
"(we only support NumPATRegisters = %d)",
|
|
|
|
CurrentMaxPATIndex);
|
|
|
|
CachePolicyError = true;
|
|
|
|
|
|
|
|
PATIdx = GMM_PAT_ERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Find a PATIndex for a coherent uncompressed case, if usage is 2-way or 1-way already, take that, otherwise search for oneway*/
|
|
|
|
if ((UsagePATElement.Xe2.Coherency == GMM_GFX_PHY_COHERENT_ONE_WAY_IA_SNOOP) ||
|
|
|
|
(UsagePATElement.Xe2.Coherency == GMM_GFX_PHY_COHERENT_TWO_WAY_IA_GPU_SNOOP))
|
|
|
|
{
|
|
|
|
//Already coherent
|
|
|
|
CoherentPATIdx = PATIdx;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// search for equivalent one way coherent index
|
|
|
|
for (i = 0; i <= CurrentMaxPATIndex; i++)
|
|
|
|
{
|
|
|
|
GMM_PRIVATE_PAT PAT = GetPrivatePATEntry(i);
|
|
|
|
if (UsagePATElement.Xe2.L4CC == PAT.Xe2.L4CC &&
|
|
|
|
UsagePATElement.Xe2.L3CC == PAT.Xe2.L3CC &&
|
|
|
|
UsagePATElement.Xe2.L3CLOS == PAT.Xe2.L3CLOS &&
|
|
|
|
GMM_GFX_PHY_COHERENT_ONE_WAY_IA_SNOOP == PAT.Xe2.Coherency)
|
|
|
|
{
|
|
|
|
if ((false == PAT.Xe2.LosslessCompressionEn) && (CoherentPATIdx == -1))
|
|
|
|
{
|
|
|
|
CoherentPATIdx = i;
|
|
|
|
}
|
|
|
|
if (CoherentPATIdx != -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (CoherentPATIdx == -1)
|
|
|
|
{
|
|
|
|
//redo matching based on L3:UC, L4:UC, we should find one
|
|
|
|
for (i = 0; i <= CurrentMaxPATIndex; i++)
|
|
|
|
{
|
|
|
|
GMM_PRIVATE_PAT PAT = GetPrivatePATEntry(i);
|
|
|
|
if (GMM_GFX_PHY_L4_MT_UC == PAT.Xe2.L4CC &&
|
|
|
|
GMM_GFX_PHY_L3_MT_UC == PAT.Xe2.L3CC &&
|
|
|
|
UsagePATElement.Xe2.L3CLOS == PAT.Xe2.L3CLOS &&
|
|
|
|
GMM_GFX_PHY_COHERENT_ONE_WAY_IA_SNOOP == PAT.Xe2.Coherency)
|
|
|
|
{
|
|
|
|
if ((false == PAT.Xe2.LosslessCompressionEn) && (CoherentPATIdx == -1))
|
|
|
|
{
|
|
|
|
CoherentPATIdx = i;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CoherentPATIdx != -1)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pCachePolicy[Usage].PATIndex = PATIdx;
|
|
|
|
pCachePolicy[Usage].CoherentPATIndex = GET_COHERENT_PATINDEX_LOWER_BITS(CoherentPATIdx); // Coherent uncompressed lower bits
|
|
|
|
pCachePolicy[Usage].CoherentPATIndexHigherBit = GET_COHERENT_PATINDEX_HIGHER_BIT(CoherentPATIdx); // Coherent uncompressed higher bits
|
|
|
|
pCachePolicy[Usage].PATIndexCompressed = PATIdxCompressed;
|
|
|
|
pCachePolicy[Usage].PTE.DwordValue = GMM_GET_PTE_BITS_FROM_PAT_IDX(PATIdx) & 0xFFFFFFFF;
|
|
|
|
pCachePolicy[Usage].PTE.HighDwordValue = GMM_GET_PTE_BITS_FROM_PAT_IDX(PATIdx) >> 32;
|
|
|
|
pCachePolicy[Usage].MemoryObjectOverride.XE_HP.Index = CPTblIdx;
|
|
|
|
pCachePolicy[Usage].MemoryObjectOverride.XE_HP.EncryptedData = 0;
|
|
|
|
pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
|
|
|
|
|
|
|
|
|
|
|
|
if (CachePolicyError)
|
|
|
|
{
|
|
|
|
GMM_ASSERTDPF(false, "Cache Policy Init Error: Invalid Cache Programming ");
|
|
|
|
|
|
|
|
return GMM_INVALIDPARAM;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return GMM_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// Function: __:GetL3L4
|
|
|
|
//
|
|
|
|
// Desc: This function // converting GMM indicative values to actual register values
|
|
|
|
//
|
|
|
|
// Parameters:
|
|
|
|
//
|
|
|
|
// Return: GMM_STATUS
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void GmmLib::GmmXe2_LPGCachePolicy::GetL3L4(GMM_CACHE_POLICY_TBL_ELEMENT *pUsageEle, GMM_XE2_PRIVATE_PAT *pUsagePATElement, uint32_t Usage)
|
|
|
|
{
|
|
|
|
|
|
|
|
//MOCS
|
|
|
|
pUsageEle->L3.PhysicalL3.Reserved0 = pUsageEle->L3.PhysicalL3.Reserved = 0;
|
|
|
|
//L3CLOS
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CLOS = 0;
|
|
|
|
//IgPAT
|
|
|
|
pUsageEle->L3.PhysicalL3.igPAT = pCachePolicy[Usage].IgnorePAT;
|
|
|
|
|
|
|
|
|
|
|
|
//PAT
|
|
|
|
pUsagePATElement->Xe2.Reserved1 = 0;
|
|
|
|
pUsagePATElement->Xe2.Reserved2 = 0;
|
|
|
|
|
|
|
|
pUsagePATElement->Xe2.L3CLOS = 0;
|
|
|
|
switch (pCachePolicy[Usage].L3CC)
|
|
|
|
{
|
|
|
|
case GMM_UC:
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_UC;
|
|
|
|
pUsagePATElement->Xe2.L3CC = GMM_GFX_PHY_L3_MT_UC;
|
|
|
|
break;
|
|
|
|
case GMM_WB:
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_WB;
|
|
|
|
pUsagePATElement->Xe2.L3CC = GMM_GFX_PHY_L3_MT_WB;
|
|
|
|
break;
|
|
|
|
case GMM_WBTD:
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_WB_XD; // Transient:Display on Xe2
|
|
|
|
pUsagePATElement->Xe2.L3CC = GMM_GFX_PHY_L3_MT_WB_XD;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_UC;
|
|
|
|
pUsagePATElement->Xe2.L3CC = GMM_GFX_PHY_L3_MT_UC;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (pCachePolicy[Usage].L4CC)
|
|
|
|
{
|
|
|
|
case GMM_UC:
|
|
|
|
pUsageEle->L3.PhysicalL3.L4CC = GMM_GFX_PHY_L4_MT_UC;
|
|
|
|
pUsagePATElement->Xe2.L4CC = GMM_GFX_PHY_L4_MT_UC;
|
|
|
|
break;
|
|
|
|
case GMM_WB:
|
|
|
|
pUsageEle->L3.PhysicalL3.L4CC = GMM_GFX_PHY_L4_MT_WB;
|
|
|
|
pUsagePATElement->Xe2.L4CC = GMM_GFX_PHY_L4_MT_WB;
|
|
|
|
break;
|
|
|
|
case GMM_WT:
|
|
|
|
pUsageEle->L3.PhysicalL3.L4CC = GMM_GFX_PHY_L4_MT_WT;
|
|
|
|
pUsagePATElement->Xe2.L4CC = GMM_GFX_PHY_L4_MT_WT;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pUsageEle->L3.PhysicalL3.L4CC = GMM_GFX_PHY_L4_MT_UC;
|
|
|
|
pUsagePATElement->Xe2.L4CC = GMM_GFX_PHY_L4_MT_UC;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (pCachePolicy[Usage].Coherency)
|
|
|
|
{
|
|
|
|
case GMM_NON_COHERENT_NO_SNOOP:
|
|
|
|
pUsagePATElement->Xe2.Coherency = GMM_GFX_NON_COHERENT_NO_SNOOP;
|
|
|
|
break;
|
|
|
|
case GMM_COHERENT_ONE_WAY_IA_SNOOP:
|
|
|
|
pUsagePATElement->Xe2.Coherency = GMM_GFX_COHERENT_ONE_WAY_IA_SNOOP;
|
|
|
|
break;
|
|
|
|
case GMM_COHERENT_TWO_WAY_IA_GPU_SNOOP:
|
|
|
|
pUsagePATElement->Xe2.Coherency = GMM_GFX_COHERENT_TWO_WAY_IA_GPU_SNOOP;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
pUsagePATElement->Xe2.Coherency = GMM_GFX_NON_COHERENT_NO_SNOOP;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-08-07 18:39:47 +08:00
|
|
|
if (pGmmLibContext->GetWaTable().Wa_14018443005 &&
|
|
|
|
(pCachePolicy[Usage].L3CC == GMM_UC) &&
|
|
|
|
(ISWA_1401844305USAGE(Usage)) &&
|
|
|
|
(pGmmLibContext->GetClientType() != GMM_KMD_VISTA) &&
|
|
|
|
(pGmmLibContext->GetClientType() != GMM_OCL_VISTA))
|
|
|
|
{
|
|
|
|
pUsageEle->L3.PhysicalL3.L3CC = GMM_GFX_PHY_L3_MT_WB;
|
|
|
|
pUsagePATElement->Xe2.L3CC = GMM_GFX_PHY_L3_MT_WB;
|
|
|
|
pCachePolicy[Usage].L3CC = GMM_WB;
|
|
|
|
}
|
2024-06-21 00:31:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// A simple getter function returning the PAT (cache policy) for a given
|
|
|
|
/// use Usage of the named resource pResInfo.
|
|
|
|
/// Typically used to populate PPGTT/GGTT.
|
|
|
|
///
|
|
|
|
/// @param[in] pResInfo: Resource info for resource, can be NULL.
|
|
|
|
/// @param[in] Usage: Current usage for resource.
|
|
|
|
/// @param[in] pCompressionEnabl: for Xe2 compression parameter
|
|
|
|
/// @param[in] IsCpuCacheable: Indicates Cacheability
|
|
|
|
/// @return PATIndex
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
uint32_t GMM_STDCALL GmmLib::GmmXe2_LPGCachePolicy::CachePolicyGetPATIndex(GMM_RESOURCE_INFO *pResInfo, GMM_RESOURCE_USAGE_TYPE Usage, bool *pCompressionEnable, bool IsCpuCacheable)
|
|
|
|
{
|
|
|
|
__GMM_ASSERT(pGmmLibContext->GetCachePolicyElement(Usage).Initialized);
|
|
|
|
|
|
|
|
uint32_t PATIndex = pGmmLibContext->GetCachePolicyElement(Usage).PATIndex;
|
|
|
|
GMM_CACHE_POLICY_ELEMENT TempElement = pGmmLibContext->GetCachePolicyElement(Usage);
|
|
|
|
uint32_t TempCoherentPATIndex = 0;
|
|
|
|
|
|
|
|
// This is to check if PATIndexCompressed, CoherentPATIndex are valid
|
|
|
|
// Increment by 1 to have the rollover and value resets to 0 if the PAT in not valid.
|
|
|
|
TempElement.PATIndexCompressed += 1;
|
|
|
|
TempCoherentPATIndex = (uint32_t)GET_COHERENT_PATINDEX_VALUE(pGmmLibContext, Usage);
|
|
|
|
|
|
|
|
// Higher bit of CoherentPATIndex would tell us if its a valid or not.0--> valid, 1-->invalid
|
|
|
|
uint32_t CoherentPATIndex = (uint32_t)((GET_COHERENT_PATINDEX_HIGHER_BIT(TempCoherentPATIndex) == 1) ? GMM_PAT_ERROR : GET_COHERENT_PATINDEX_VALUE(pGmmLibContext, Usage));
|
|
|
|
//For PATIndexCompressed, rollover value would be 0 if its invalid
|
|
|
|
uint32_t PATIndexCompressed = (uint32_t)(TempElement.PATIndexCompressed == 0 ? GMM_PAT_ERROR : pGmmLibContext->GetCachePolicyElement(Usage).PATIndexCompressed);
|
|
|
|
uint32_t ReturnPATIndex = GMM_PAT_ERROR;
|
|
|
|
bool CompressionEnable = (pCompressionEnable) ? *pCompressionEnable : false;
|
|
|
|
|
|
|
|
// Prevent wrong Usage for XAdapter resources. UMD does not call GetMemoryObject on shader resources but,
|
|
|
|
// when they add it someone could call it without knowing the restriction.
|
|
|
|
if (pResInfo &&
|
|
|
|
pResInfo->GetResFlags().Info.XAdapter &&
|
|
|
|
(Usage != GMM_RESOURCE_USAGE_XADAPTER_SHARED_RESOURCE))
|
|
|
|
{
|
|
|
|
__GMM_ASSERT(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if (defined __linux__ || defined(WDDM_LINUX))
|
|
|
|
IsCpuCacheable = false;
|
|
|
|
#endif
|
|
|
|
// requested compressed and coherent
|
|
|
|
if (CompressionEnable && IsCpuCacheable)
|
|
|
|
{
|
|
|
|
// return coherent uncompressed
|
|
|
|
ReturnPATIndex = CoherentPATIndex;
|
|
|
|
CompressionEnable = false;
|
|
|
|
GMM_ASSERTDPF(false, "Coherent Compressed is not supported on Xe2. However, respecting the coherency and returning CoherentPATIndex");
|
|
|
|
}
|
|
|
|
// requested compressed only
|
|
|
|
else if (CompressionEnable)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (GMM_PAT_ERROR != PATIndexCompressed)
|
|
|
|
{
|
|
|
|
// return compresed, may or may not coherent which depends on orinigal usage
|
|
|
|
ReturnPATIndex = PATIndexCompressed;
|
|
|
|
CompressionEnable = true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// return original index
|
|
|
|
ReturnPATIndex = PATIndex;
|
|
|
|
CompressionEnable = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// requested coherent only
|
|
|
|
else if (IsCpuCacheable)
|
|
|
|
{
|
|
|
|
//return coherent uncompressed
|
|
|
|
ReturnPATIndex = CoherentPATIndex;
|
|
|
|
CompressionEnable = false;
|
|
|
|
}
|
|
|
|
/* Requested UnCompressed PAT */
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (GMM_PAT_ERROR != PATIndex)
|
|
|
|
{
|
|
|
|
ReturnPATIndex = PATIndex;
|
|
|
|
CompressionEnable = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* No valid PAT Index found */
|
|
|
|
if (GMM_PAT_ERROR == ReturnPATIndex)
|
|
|
|
{
|
|
|
|
ReturnPATIndex = GMM_XE2_DEFAULT_PAT_INDEX; //default to uncached PAT index 2: GMM_CP_NON_COHERENT_UC
|
|
|
|
CompressionEnable = false;
|
|
|
|
__GMM_ASSERT(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pCompressionEnable)
|
|
|
|
{
|
|
|
|
*pCompressionEnable = CompressionEnable;
|
|
|
|
}
|
|
|
|
|
|
|
|
return ReturnPATIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// Function: SetUpMOCSTable
|
|
|
|
//
|
|
|
|
// Desc:
|
|
|
|
//
|
|
|
|
// Parameters:
|
|
|
|
//
|
|
|
|
// Return: GMM_STATUS
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void GmmLib::GmmXe2_LPGCachePolicy::SetUpMOCSTable()
|
|
|
|
{
|
|
|
|
GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = &(pGmmLibContext->GetCachePolicyTlbElement()[0]);
|
|
|
|
|
|
|
|
#define L4_WB (0x0)
|
|
|
|
#define L4_WT (0x1)
|
|
|
|
#define L4_UC (0x3)
|
|
|
|
|
|
|
|
#define L3_WB (0x0)
|
|
|
|
#define L3_XD (pGmmLibContext->GetSkuTable().FtrL3TransientDataFlush ? 0x1 : 0x0)
|
|
|
|
#define L3_UC (0x3)
|
|
|
|
|
|
|
|
#define GMM_DEFINE_MOCS(indx, L4Caching, L3Caching, L3ClassOfService, ignorePAT) \
|
|
|
|
{ \
|
|
|
|
pCachePolicyTlbElement[indx].L3.PhysicalL3.L4CC = L4Caching; \
|
|
|
|
pCachePolicyTlbElement[indx].L3.PhysicalL3.Reserved0 = 0; \
|
|
|
|
pCachePolicyTlbElement[indx].L3.PhysicalL3.L3CC = L3Caching; \
|
|
|
|
pCachePolicyTlbElement[indx].L3.PhysicalL3.L3CLOS = L3ClassOfService; \
|
|
|
|
pCachePolicyTlbElement[indx].L3.PhysicalL3.igPAT = ignorePAT; \
|
|
|
|
}
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
// Default MOCS Table
|
|
|
|
for(uint32_t j = 0; j < GMM_XE2_NUM_MOCS_ENTRIES; j++)
|
|
|
|
{ // Index CachingPolicy L3Caching L3ClassOfService ignorePAT
|
|
|
|
GMM_DEFINE_MOCS( j, L4_UC, L3_UC, 0 , 0 )
|
|
|
|
}
|
|
|
|
|
|
|
|
// Index L4 CachingPolicy L3 CachingPolicy L3 CLOS ignorePAT
|
|
|
|
GMM_DEFINE_MOCS( 0 , L4_UC , L3_WB , 0 , 0) // Defer to PAT
|
|
|
|
GMM_DEFINE_MOCS( 1 , L4_UC , L3_WB , 0 , 1) // L3
|
|
|
|
GMM_DEFINE_MOCS( 2 , L4_WB , L3_UC , 0 , 1) // L4
|
|
|
|
GMM_DEFINE_MOCS( 3 , L4_UC , L3_UC , 0 , 1) // UC
|
|
|
|
GMM_DEFINE_MOCS( 4 , L4_WB , L3_WB , 0 , 1) // L3+L4
|
|
|
|
|
|
|
|
CurrentMaxMocsIndex = 4;
|
|
|
|
CurrentMaxL1HdcMocsIndex = 0;
|
|
|
|
CurrentMaxSpecialMocsIndex = 0;
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
#undef GMM_DEFINE_MOCS
|
|
|
|
#undef L4_WB
|
|
|
|
#undef L4_WT
|
|
|
|
#undef L4_UC
|
|
|
|
|
|
|
|
#undef L3_WB
|
|
|
|
#undef L3_XD
|
|
|
|
#undef L3_UC
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
|
|
//
|
|
|
|
// Function: SetupPAT
|
|
|
|
//
|
|
|
|
// Desc:
|
|
|
|
//
|
|
|
|
// Parameters:
|
|
|
|
//
|
|
|
|
// Return: GMM_STATUS
|
|
|
|
//
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
GMM_STATUS GmmLib::GmmXe2_LPGCachePolicy::SetupPAT()
|
|
|
|
{
|
|
|
|
GMM_PRIVATE_PAT *pPATTlbElement = &(pGmmLibContext->GetPrivatePATTable()[0]);
|
|
|
|
|
|
|
|
#define L4_WB (0x0)
|
|
|
|
#define L4_WT (0x1)
|
|
|
|
#define L4_UC (0x3)
|
|
|
|
|
|
|
|
#define L3_WB (0x0)
|
|
|
|
#define L3_XD (pGmmLibContext->GetSkuTable().FtrL3TransientDataFlush ? 0x1 : 0x0)
|
|
|
|
#define L3_UC (0x3)
|
|
|
|
#define L3_XA (0x2) // WB Transient App
|
|
|
|
|
|
|
|
#define GMM_DEFINE_PAT_ELEMENT(indx, Coh, L4Caching, L3Caching, L3ClassOfService, CompressionEn, NoCachePromote) \
|
|
|
|
{ \
|
|
|
|
pPATTlbElement[indx].Xe2.Coherency = Coh; \
|
|
|
|
pPATTlbElement[indx].Xe2.L4CC = L4Caching; \
|
|
|
|
pPATTlbElement[indx].Xe2.Reserved1 = 0; \
|
|
|
|
pPATTlbElement[indx].Xe2.Reserved2 = 0; \
|
|
|
|
pPATTlbElement[indx].Xe2.L3CC = L3Caching; \
|
|
|
|
pPATTlbElement[indx].Xe2.L3CLOS = L3ClassOfService; \
|
|
|
|
pPATTlbElement[indx].Xe2.LosslessCompressionEn = CompressionEn; \
|
|
|
|
pPATTlbElement[indx].Xe2.NoCachingPromote = NoCachePromote; \
|
|
|
|
}
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
|
|
|
// Default PAT Table
|
|
|
|
// 32 nos
|
|
|
|
for (uint32_t i = 0; i < (NumPATRegisters); i++)
|
|
|
|
{ // Index Coherency CachingPolicy L3Caching L3ClassOfService CompressionEn NoCachingPromote
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( i, 3, L4_UC, L3_UC, 0, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fixed PAT Table
|
|
|
|
// Index Coherency L4 CachingPolicy L3 CachingPolicy L3 CLOS CompressionEn NoCachingPromote
|
|
|
|
//Group: GGT/PPGTT[4]
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 0 , 0 , L4_UC , L3_WB , 0 , 0 , 0) // | L3_WB
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 1 , 2 , L4_UC , L3_WB , 0 , 0 , 0) // | L3_WB | 1 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 2 , 3 , L4_UC , L3_WB , 0 , 0 , 0) // | L3_WB | 2 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 3 , 0 , L4_UC , L3_UC , 0 , 0 , 0) // **UC
|
|
|
|
//Group: 1 way Coh
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 4 , 2 , L4_WB , L3_UC , 0 , 0 , 0) // L4_WB | 1 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 5 , 2 , L4_UC , L3_UC , 0 , 0 , 0) // **UC | 1 way coherent
|
|
|
|
//Group: Compression Disabled
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 6 , 0 , L4_UC , L3_XD , 0 , 0 , 1) // | L3_XD
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 7 , 3 , L4_WB , L3_UC , 0 , 0 , 0) // L4_WB | 2 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 8 , 0 , L4_WB , L3_UC , 0 , 0 , 0) // L4_WB
|
|
|
|
//Group: Compression Enabled
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 9 , 0 , L4_UC , L3_WB , 0 , 1 , 0) // | L3_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 10 , 0 , L4_WB , L3_UC , 0 , 1 , 0) // L4_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 11 , 0 , L4_UC , L3_XD , 0 , 1 , 1) // | L3_XD | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 12 , 0 , L4_UC , L3_UC , 0 , 1 , 0) // **UC | Comp
|
|
|
|
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 13 , 0 , L4_WB , L3_WB , 0 , 0 , 0) // L4_WB | L3_WB
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 14 , 0 , L4_WB , L3_WB , 0 , 1 , 0) // L4_WB | L3_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 15 , 0 , L4_WT , L3_XD , 0 , 1 , 1) // L4_WT | L3_XD | Comp
|
|
|
|
|
|
|
|
//Reserved 16-19
|
|
|
|
//Group: CLOS1
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 20 , 0 , L4_UC , L3_WB , 1 , 0 , 0) // | L3_WB
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 21 , 0 , L4_UC , L3_WB , 1 , 1 , 0) // | L3_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 22 , 2 , L4_UC , L3_WB , 1 , 0 , 0) // | L3_WB | 1 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 23 , 3 , L4_UC , L3_WB , 1 , 0 , 0) // | L3_WB | 2 way coherent
|
|
|
|
//Group:CLOS2=>Clone of CLOS1
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 24 , 0 , L4_UC , L3_WB , 2 , 0 , 0) // | L3_WB
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 25 , 0 , L4_UC , L3_WB , 2 , 1 , 0) // | L3_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 26 , 2 , L4_UC , L3_WB , 2 , 0 , 0) // | L3_WB | 1 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 27 , 3 , L4_UC , L3_WB , 2 , 0 , 0) // | L3_WB | 2 way coherent
|
|
|
|
//Group:CLOS3=>Clone of CLOS1
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 28 , 0 , L4_UC , L3_WB , 3 , 0 , 0) // | L3_WB
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 29 , 0 , L4_UC , L3_WB , 3 , 1 , 0) // | L3_WB | Comp
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 30 , 2 , L4_UC , L3_WB , 3 , 0 , 0) // | L3_WB | 1 way coherent
|
|
|
|
GMM_DEFINE_PAT_ELEMENT( 31 , 3 , L4_UC , L3_WB , 3 , 0 , 0) // | L3_WB | 2 way coherent
|
|
|
|
|
|
|
|
CurrentMaxPATIndex = 31;
|
|
|
|
|
|
|
|
// clang-format on
|
|
|
|
#undef GMM_DEFINE_PAT
|
|
|
|
#undef L4_WB
|
|
|
|
#undef L4_WT
|
|
|
|
#undef L4_UC
|
|
|
|
|
|
|
|
#undef L3_WB
|
|
|
|
#undef L3_XD
|
|
|
|
#undef L3_UC
|
|
|
|
return GMM_SUCCESS;
|
|
|
|
}
|