xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/CachePolicy/GmmGen10CachePolicy.cpp (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
1 /*==============================================================================
2 Copyright(c) 2017 Intel Corporation
3 
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files(the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and / or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13 
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 ============================================================================*/
22 
23 #include "Internal/Common/GmmLibInc.h"
24 #include "External/Common/GmmCachePolicy.h"
25 #include "External/Common/CachePolicy/GmmCachePolicyGen10.h"
26 //=============================================================================
27 //
28 // Function: __GmmGen10InitCachePolicy
29 //
30 // Desc: This function initializes the cache policy
31 //
32 // Parameters: pCachePolicy  -> Ptr to array to be populated with the
33 //             mapping of usages -> cache settings.
34 //
35 // Return: GMM_STATUS
36 //
37 //-----------------------------------------------------------------------------
InitCachePolicy()38 GMM_STATUS GmmLib::GmmGen10CachePolicy::InitCachePolicy()
39 {
40 
41     __GMM_ASSERTPTR(pCachePolicy, GMM_ERROR);
42 
43 #define DEFINE_CACHE_ELEMENT(usage, llc, ellc, l3, wt, age, lecc_scc, l3_scc, sso, cos, hdcl1) DEFINE_CP_ELEMENT(usage, llc, ellc, l3, wt, age, 0, lecc_scc, l3_scc, 0, sso, cos, hdcl1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
44 #include "GmmGen10CachePolicy.h"
45 
46 #define TC_LLC (1)
47 #define TC_ELLC (0) //Is this supported anymore in TargetCache?
48 #define TC_LLC_ELLC (2)
49 
50 #define LeCC_UNCACHEABLE (0x1)
51 #define LeCC_WT_CACHEABLE (0x2) //Only used as MemPushWRite disqualifier if set along with eLLC-only
52 #define LeCC_WB_CACHEABLE (0x3)
53 
54 #define L3_UNCACHEABLE (0x1)
55 #define L3_WB_CACHEABLE (0x3)
56 
57 #define DISABLE_SKIP_CACHING_CONTROL (0x0)
58 #define ENABLE_SKIP_CACHING_CONTROL (0x1)
59 
60 #define DISABLE_SELF_SNOOP_OVERRIDE (0x0)
61 #define ENABLE_SELF_SNOOP_OVERRIDE (0x1)
62 #define ENABLE_SELF_SNOOP_ALWAYS (0x3)
63 #define CLASS_SERVICE_ZERO 0
64     {
65         // Define index of cache element
66         uint32_t Usage = 0;
67 
68         uint32_t                      CurrentMaxIndex        = 0;
69         uint32_t                      CurrentMaxHDCL1Index   = GMM_GEN10_HDCL1_MOCS_INDEX_START - 1; // define constant
70         GMM_CACHE_POLICY_TBL_ELEMENT *pCachePolicyTlbElement = pGmmLibContext->GetCachePolicyTlbElement();
71 
72         // index 0 is uncached.
73         {
74             GMM_CACHE_POLICY_TBL_ELEMENT *Entry0 = &(pCachePolicyTlbElement[0]);
75             Entry0->LeCC.Cacheability            = LeCC_UNCACHEABLE;
76             Entry0->LeCC.TargetCache             = TC_LLC_ELLC;
77             Entry0->LeCC.LRUM                    = 0;
78             Entry0->LeCC.ESC                     = DISABLE_SKIP_CACHING_CONTROL;
79             Entry0->LeCC.SCC                     = 0;
80             Entry0->LeCC.CoS                     = CLASS_SERVICE_ZERO;
81             Entry0->LeCC.SelfSnoop               = DISABLE_SELF_SNOOP_OVERRIDE;
82             Entry0->L3.Cacheability              = L3_UNCACHEABLE;
83             Entry0->L3.ESC                       = DISABLE_SKIP_CACHING_CONTROL;
84             Entry0->L3.SCC                       = 0;
85             Entry0->HDCL1                        = 0;
86         }
87 
88         // Process the cache policy and fill in the look up table
89         for(; Usage < GMM_RESOURCE_USAGE_MAX; Usage++)
90         {
91             bool                         CachePolicyError = false;
92             int32_t                      CPTblIdx         = -1;
93             uint32_t                     j                = 0;
94             uint64_t                     PTEValue         = 0;
95             GMM_CACHE_POLICY_TBL_ELEMENT UsageEle         = {0};
96             UsageEle.LeCC.Reserved                        = 0; // Reserved bits zeroe'd, this is so we
97                                                                // we can compare the unioned LeCC.DwordValue.
98             UsageEle.LeCC.SelfSnoop = DISABLE_SELF_SNOOP_OVERRIDE;
99             UsageEle.LeCC.CoS       = CLASS_SERVICE_ZERO;
100             UsageEle.LeCC.SCC       = 0;
101             UsageEle.LeCC.ESC       = 0;
102             if(pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_OVERRIDE)
103             {
104                 UsageEle.LeCC.SelfSnoop = pCachePolicy[Usage].SSO & ENABLE_SELF_SNOOP_ALWAYS;
105             }
106             if(pCachePolicy[Usage].CoS)
107             {
108                 UsageEle.LeCC.CoS = pCachePolicy[Usage].CoS;
109             }
110             if(pCachePolicy[Usage].HDCL1)
111             {
112                 UsageEle.HDCL1 = 1;
113             }
114             if(pCachePolicy[Usage].LeCC_SCC)
115             {
116                 UsageEle.LeCC.SCC = pCachePolicy[Usage].LeCC_SCC;
117                 UsageEle.LeCC.ESC = ENABLE_SKIP_CACHING_CONTROL;
118             }
119             UsageEle.LeCC.LRUM = pCachePolicy[Usage].AGE;
120 
121             // default to LLC/ELLC target cache.
122             UsageEle.LeCC.TargetCache  = TC_LLC_ELLC;
123             UsageEle.LeCC.Cacheability = LeCC_WB_CACHEABLE;
124             if(pCachePolicy[Usage].LLC && pCachePolicy[Usage].ELLC)
125             {
126                 UsageEle.LeCC.TargetCache = TC_LLC_ELLC;
127             }
128             else if(pCachePolicy[Usage].LLC)
129             {
130                 UsageEle.LeCC.TargetCache = TC_LLC;
131             }
132             else if(pCachePolicy[Usage].ELLC)
133             {
134                 UsageEle.LeCC.TargetCache = TC_ELLC;
135                 if(pCachePolicy[Usage].WT)
136                 {
137                     UsageEle.LeCC.Cacheability = LeCC_WT_CACHEABLE;
138                 }
139             }
140             else
141             {
142                 UsageEle.LeCC.Cacheability = LeCC_UNCACHEABLE;
143             }
144             UsageEle.L3.Reserved = 0; // Reserved bits zeroe'd, this is so we
145                                       // we can compare the unioned L3.UshortValue.
146             UsageEle.L3.ESC          = DISABLE_SKIP_CACHING_CONTROL;
147             UsageEle.L3.SCC          = 0;
148             UsageEle.L3.Cacheability = pCachePolicy[Usage].L3 ? L3_WB_CACHEABLE : L3_UNCACHEABLE;
149 
150             if(pCachePolicy[Usage].L3_SCC)
151             {
152                 UsageEle.L3.ESC = ENABLE_SKIP_CACHING_CONTROL;
153                 UsageEle.L3.SCC = (uint16_t)pCachePolicy[Usage].L3_SCC;
154             }
155             //For HDC L1 caching, MOCS Table index 48-61 should be used
156             if(UsageEle.HDCL1)
157             {
158                 for(j = GMM_GEN10_HDCL1_MOCS_INDEX_START; j <= CurrentMaxHDCL1Index; j++)
159                 {
160                     GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pCachePolicyTlbElement[j];
161                     if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
162                        TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
163                        TblEle->HDCL1 == UsageEle.HDCL1)
164                     {
165                         CPTblIdx = j;
166                         break;
167                     }
168                 }
169             }
170             else
171             {
172                 for(j = 0; j <= CurrentMaxIndex; j++)
173                 {
174                     GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &pCachePolicyTlbElement[j];
175                     if(TblEle->LeCC.DwordValue == UsageEle.LeCC.DwordValue &&
176                        TblEle->L3.UshortValue == UsageEle.L3.UshortValue &&
177                        TblEle->HDCL1 == UsageEle.HDCL1)
178                     {
179                         CPTblIdx = j;
180                         break;
181                     }
182                 }
183             }
184 
185             // Didn't find the caching settings in one of the already programmed lookup table entries.
186             // Need to add a new lookup table entry.
187             if(CPTblIdx == -1)
188             {
189                 if(UsageEle.HDCL1 && CurrentMaxHDCL1Index < GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1)
190                 {
191                     GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pCachePolicyTlbElement[++CurrentMaxHDCL1Index]);
192                     CPTblIdx                             = CurrentMaxHDCL1Index;
193 
194                     TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
195                     TblEle->L3.UshortValue  = UsageEle.L3.UshortValue;
196                     TblEle->HDCL1           = UsageEle.HDCL1;
197                 }
198                 else if(CurrentMaxIndex < GMM_GEN10_HDCL1_MOCS_INDEX_START)
199                 {
200                     GMM_CACHE_POLICY_TBL_ELEMENT *TblEle = &(pCachePolicyTlbElement[++CurrentMaxIndex]);
201                     CPTblIdx                             = CurrentMaxIndex;
202 
203                     TblEle->LeCC.DwordValue = UsageEle.LeCC.DwordValue;
204                     TblEle->L3.UshortValue  = UsageEle.L3.UshortValue;
205                     TblEle->HDCL1           = UsageEle.HDCL1;
206                 }
207                 else
208                 {
209                     // Too many unique caching combinations to program the
210                     // MOCS lookup table.
211                     CachePolicyError = true;
212                     GMM_ASSERTDPF(
213                     "Cache Policy Init Error: Invalid Cache Programming, too many unique caching combinations"
214                     "(we only support GMM_GEN_MAX_NUMBER_MOCS_INDEXES = %d)",
215                     GMM_GEN9_MAX_NUMBER_MOCS_INDEXES - 1);
216                     // Set cache policy index to uncached.
217                     CPTblIdx = 0;
218                 }
219             }
220 
221             // PTE entries do not control caching on SKL+ (for legacy context)
222             if(!GetUsagePTEValue(pCachePolicy[Usage], Usage, &PTEValue))
223             {
224                 CachePolicyError = true;
225             }
226 
227             pCachePolicy[Usage].PTE.DwordValue     = PTEValue & 0xFFFFFFFF;
228             pCachePolicy[Usage].PTE.HighDwordValue = 0;
229 
230             pCachePolicy[Usage].MemoryObjectOverride.Gen10.Index = CPTblIdx;
231 
232             pCachePolicy[Usage].Override = ALWAYS_OVERRIDE;
233 
234             if(CachePolicyError)
235             {
236                 GMM_ASSERTDPF("Cache Policy Init Error: Invalid Cache Programming - Element %d", Usage);
237             }
238         }
239         CurrentMaxMocsIndex      = CurrentMaxIndex;
240         CurrentMaxL1HdcMocsIndex = CurrentMaxHDCL1Index;
241     }
242 
243     return GMM_SUCCESS;
244 }
245 
246 /////////////////////////////////////////////////////////////////////////////////////
247 /// Initializes WA's needed for setting up the Private PATs
248 /// WaNoMocsEllcOnly, WaGttPat0, WaGttPat0GttWbOverOsIommuEllcOnly, WaGttPat0WB
249 ///
250 /// @return        GMM_STATUS
251 ///
252 /////////////////////////////////////////////////////////////////////////////////////
SetPATInitWA()253 GMM_STATUS GmmLib::GmmGen10CachePolicy::SetPATInitWA()
254 {
255     GMM_STATUS Status = GMM_SUCCESS;
256 
257 #if(defined(__GMM_KMD__))
258     if(pGmmLibContext->GetGtSysInfoPtr()->EdramSizeInKb)
259     {
260         const_cast<WA_TABLE &>(pGmmLibContext->GetWaTable()).WaNoMocsEllcOnly = 1;
261     }
262 #else
263     Status = GMM_ERROR;
264 #endif
265 
266     return Status;
267 }
268 
269 /////////////////////////////////////////////////////////////////////////////////////
270 /// Returns the PAT idx that best matches the cache policy for this usage.
271 ///
272 /// @param: CachePolicy: cache policy for a usage
273 ///
274 /// @return        PAT Idx to use in the PTE
275 /////////////////////////////////////////////////////////////////////////////////////
BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)276 uint32_t GmmLib::GmmGen10CachePolicy::BestMatchingPATIdx(GMM_CACHE_POLICY_ELEMENT CachePolicy)
277 {
278     uint32_t             i;
279     uint32_t             PATIdx           = 0;
280     GMM_GFX_MEMORY_TYPE  WantedMemoryType = GMM_GFX_UC_WITH_FENCE, MemoryType;
281     GMM_GFX_TARGET_CACHE WantedTC         = GMM_GFX_TC_ELLC_LLC;
282 
283     WantedMemoryType = GetWantedMemoryType(CachePolicy);
284 
285     if(CachePolicy.LLC && CachePolicy.ELLC)
286     {
287         WantedTC = GMM_GFX_TC_ELLC_LLC;
288     }
289     else if(CachePolicy.LLC)
290     {
291         WantedTC = GMM_GFX_TC_LLC_ONLY;
292     }
293     else if(CachePolicy.ELLC)
294     {
295         WantedTC = GMM_GFX_TC_ELLC_ONLY; // Note: this overrides the MOCS target cache selection.
296     }
297 
298     for(i = 1; i < NumPATRegisters; i++)
299     {
300         GMM_PRIVATE_PAT PAT1 = GetPrivatePATEntry(PATIdx);
301         GMM_PRIVATE_PAT PAT2 = GetPrivatePATEntry(i);
302 
303         if(SelectNewPATIdx(WantedMemoryType, WantedTC,
304                            (GMM_GFX_MEMORY_TYPE)PAT1.Gen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT1.Gen10.TargetCache,
305                            (GMM_GFX_MEMORY_TYPE)PAT2.Gen10.MemoryType, (GMM_GFX_TARGET_CACHE)PAT2.Gen10.TargetCache))
306         {
307             PATIdx = i;
308         }
309     }
310 
311     MemoryType = (GMM_GFX_MEMORY_TYPE)GetPrivatePATEntry(PATIdx).Gen10.MemoryType;
312 
313     if(MemoryType != WantedMemoryType)
314     {
315         // Failed to find a matching PAT entry
316         return GMM_PAT_ERROR;
317     }
318     return PATIdx;
319 }
320 
321 /////////////////////////////////////////////////////////////////////////////////////
322 ///  Initializes the Gfx PAT tables for AdvCtx and Gfx MMIO/Private PAT
323 ///    PAT0 = WB_COHERENT or UC depending on WaGttPat0WB
324 ///    PAT1 = UC or WB_COHERENT depending on WaGttPat0WB
325 ///    PAT2 = WB_MOCSLESS, with TC = eLLC+LLC
326 ///    PAT3 = WB
327 ///    PAT4 = WT
328 ///    PAT5 = WC
329 ///    PAT6 = WC
330 ///    PAT7 = WC
331 ///  HLD says to set to PAT0/1 to WC, but since we don't have a WC in GPU,
332 ///  WC option is same as UC. Hence setting PAT0 or PAT1 to UC.
333 ///  Unused PAT's (5,6,7) are set to WC.
334 ///
335 /// @return        GMM_STATUS
336 /////////////////////////////////////////////////////////////////////////////////////
SetupPAT()337 GMM_STATUS GmmLib::GmmGen10CachePolicy::SetupPAT()
338 {
339     GMM_STATUS Status = GMM_SUCCESS;
340 #if(defined(__GMM_KMD__))
341     uint32_t i = 0;
342 
343     GMM_GFX_MEMORY_TYPE GfxMemType = GMM_GFX_UC_WITH_FENCE;
344     // No optional selection on Age or Target Cache because for an SVM-OS Age and
345     // Target Cache would not work [for an SVM-OS the Page Table is shared with IA
346     // and we don't have control of the PAT Idx]. If there is a strong ask from D3D
347     // or the performance analysis team, Age could be added.
348     // Add Class of Service when required.
349     GMM_GFX_TARGET_CACHE GfxTargetCache             = GMM_GFX_TC_ELLC_LLC;
350     uint8_t              Age                        = 1;
351     uint8_t              ServiceClass               = 0;
352     int32_t *            pPrivatePATTableMemoryType = NULL;
353     pPrivatePATTableMemoryType                      = pGmmLibContext->GetPrivatePATTableMemoryType();
354 
355     __GMM_ASSERT(pGmmLibContext->GetSkuTable().FtrIA32eGfxPTEs);
356     for(i = 0; i < GMM_NUM_GFX_PAT_TYPES; i++)
357     {
358         pPrivatePATTableMemoryType[i] = -1;
359     }
360 
361     // Set values for GmmGlobalInfo PrivatePATTable
362     for(i = 0; i < NumPATRegisters; i++)
363     {
364         GMM_PRIVATE_PAT PAT = {0};
365 
366 	if(pGmmLibContext->GetWaTable().WaNoMocsEllcOnly)
367         {
368             GfxTargetCache = GMM_GFX_TC_ELLC_ONLY;
369         }
370         else
371         {
372             GfxTargetCache = GMM_GFX_TC_ELLC_LLC;
373         }
374 
375         switch(i)
376         {
377             case PAT0:
378                 if(pGmmLibContext->GetWaTable().WaGttPat0)
379 		{
380                     if(pGmmLibContext->GetWaTable().WaGttPat0WB)
381 	            {
382                         GfxMemType = GMM_GFX_WB;
383                         if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
384                         {
385                             PAT.PreGen10.Snoop = 1;
386                         }
387                         pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
388                     }
389                     else
390                     {
391                         GfxMemType                                 = GMM_GFX_UC_WITH_FENCE;
392                         pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT0;
393                     }
394                 }
395                 else // if GTT is not tied to PAT0 then WaGttPat0WB is NA
396                 {
397                     GfxMemType = GMM_GFX_WB;
398                     if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
399                     {
400                         PAT.PreGen10.Snoop = 1;
401                     }
402                     pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT0;
403                 }
404                 break;
405 
406             case PAT1:
407                 if(pGmmLibContext->GetWaTable().WaGttPat0 && !pGmmLibContext->GetWaTable().WaGttPat0WB)
408                 {
409                     GfxMemType = GMM_GFX_WB;
410                     if(GFX_IS_ATOM_PLATFORM(pGmmLibContext))
411                     {
412                         PAT.PreGen10.Snoop = 1;
413                     }
414                     pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_COHERENT] = PAT1;
415                 }
416                 else
417                 {
418                     GfxMemType                                 = GMM_GFX_UC_WITH_FENCE;
419                     pPrivatePATTableMemoryType[GMM_GFX_PAT_UC] = PAT1;
420                 }
421                 break;
422 
423             case PAT2:
424                 // This PAT idx shall be used for MOCS'Less resources like Page Tables
425                 // Page Tables have TC hardcoded to eLLC+LLC in Adv Ctxt. Hence making this to have same in Leg Ctxt.
426                 // For BDW-H, due to Perf issue, TC has to be eLLC only for Page Tables when eDRAM is present.
427                 GfxMemType                                          = GMM_GFX_WB;
428                 GfxTargetCache                                      = GMM_GFX_TC_ELLC_LLC;
429                 pPrivatePATTableMemoryType[GMM_GFX_PAT_WB_MOCSLESS] = PAT2;
430                 break;
431 
432             case PAT3:
433                 GfxMemType                                 = GMM_GFX_WB;
434                 pPrivatePATTableMemoryType[GMM_GFX_PAT_WB] = PAT3;
435                 break;
436 
437             case PAT4:
438                 GfxMemType                                 = GMM_GFX_WT;
439                 pPrivatePATTableMemoryType[GMM_GFX_PAT_WT] = PAT4;
440                 break;
441 
442             case PAT5:
443             case PAT6:
444             case PAT7:
445                 GfxMemType                                 = GMM_GFX_WC;
446                 pPrivatePATTableMemoryType[GMM_GFX_PAT_WC] = PAT5;
447                 break;
448 
449             default:
450                 __GMM_ASSERT(0);
451                 Status = GMM_ERROR;
452         }
453 
454         PAT.Gen10.MemoryType  = GfxMemType;
455         PAT.Gen10.TargetCache = GfxTargetCache;
456         PAT.Gen10.Age         = Age;
457         PAT.Gen10.CoS         = ServiceClass;
458 
459         SetPrivatePATEntry(i, PAT);
460     }
461 
462 #else
463     Status = GMM_ERROR;
464 #endif
465     return Status;
466 }
467