xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/TranslationTable/GmmUmdTranslationTable.cpp (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
1*35ffd701SAndroid Build Coastguard Worker /*==============================================================================
2*35ffd701SAndroid Build Coastguard Worker Copyright(c) 2019 Intel Corporation
3*35ffd701SAndroid Build Coastguard Worker 
4*35ffd701SAndroid Build Coastguard Worker Permission is hereby granted, free of charge, to any person obtaining a
5*35ffd701SAndroid Build Coastguard Worker copy of this software and associated documentation files(the "Software"),
6*35ffd701SAndroid Build Coastguard Worker to deal in the Software without restriction, including without limitation
7*35ffd701SAndroid Build Coastguard Worker the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*35ffd701SAndroid Build Coastguard Worker and / or sell copies of the Software, and to permit persons to whom the
9*35ffd701SAndroid Build Coastguard Worker Software is furnished to do so, subject to the following conditions:
10*35ffd701SAndroid Build Coastguard Worker 
11*35ffd701SAndroid Build Coastguard Worker The above copyright notice and this permission notice shall be included
12*35ffd701SAndroid Build Coastguard Worker in all copies or substantial portions of the Software.
13*35ffd701SAndroid Build Coastguard Worker 
14*35ffd701SAndroid Build Coastguard Worker THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15*35ffd701SAndroid Build Coastguard Worker OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*35ffd701SAndroid Build Coastguard Worker FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*35ffd701SAndroid Build Coastguard Worker THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*35ffd701SAndroid Build Coastguard Worker OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*35ffd701SAndroid Build Coastguard Worker ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*35ffd701SAndroid Build Coastguard Worker OTHER DEALINGS IN THE SOFTWARE.
21*35ffd701SAndroid Build Coastguard Worker 
22*35ffd701SAndroid Build Coastguard Worker Description: Contains functions of internal classes
23*35ffd701SAndroid Build Coastguard Worker              (ie PageTablePool, PageTable, Table), that support
24*35ffd701SAndroid Build Coastguard Worker              user mode page table management
25*35ffd701SAndroid Build Coastguard Worker 
26*35ffd701SAndroid Build Coastguard Worker ============================================================================*/
27*35ffd701SAndroid Build Coastguard Worker 
28*35ffd701SAndroid Build Coastguard Worker #include "Internal/Common/GmmLibInc.h"
29*35ffd701SAndroid Build Coastguard Worker #include "../TranslationTable/GmmUmdTranslationTable.h"
30*35ffd701SAndroid Build Coastguard Worker #include "Internal/Common/Texture/GmmTextureCalc.h"
31*35ffd701SAndroid Build Coastguard Worker 
32*35ffd701SAndroid Build Coastguard Worker #if !defined(__GMM_KMD)
33*35ffd701SAndroid Build Coastguard Worker 
34*35ffd701SAndroid Build Coastguard Worker #if defined(__linux__)
35*35ffd701SAndroid Build Coastguard Worker #include "Internal/Linux/GmmResourceInfoLinInt.h"
36*35ffd701SAndroid Build Coastguard Worker 
37*35ffd701SAndroid Build Coastguard Worker #define _aligned_free(ptr) free(ptr)
38*35ffd701SAndroid Build Coastguard Worker 
39*35ffd701SAndroid Build Coastguard Worker #endif
40*35ffd701SAndroid Build Coastguard Worker 
41*35ffd701SAndroid Build Coastguard Worker //=============================================================================
42*35ffd701SAndroid Build Coastguard Worker //
43*35ffd701SAndroid Build Coastguard Worker // Function: AllocateL3Table
44*35ffd701SAndroid Build Coastguard Worker //
45*35ffd701SAndroid Build Coastguard Worker // Desc: Allocates (always resident SVM) memory for AUXTT\L3 Table, and updates AUXTT object
46*35ffd701SAndroid Build Coastguard Worker //
47*35ffd701SAndroid Build Coastguard Worker // Parameters:
48*35ffd701SAndroid Build Coastguard Worker //      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
49*35ffd701SAndroid Build Coastguard Worker //
50*35ffd701SAndroid Build Coastguard Worker // Returns:
51*35ffd701SAndroid Build Coastguard Worker //      GMM_SUCCESS on success,
52*35ffd701SAndroid Build Coastguard Worker //      GMM_INVALIDPARAM on invalid parameter(s)
53*35ffd701SAndroid Build Coastguard Worker //      GMM_OUT_OF_MEMORY on memory allocation failure, failure to make resident
54*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
AllocateL3Table(uint32_t L3TableSize,uint32_t L3AddrAlignment)55*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::PageTable::AllocateL3Table(uint32_t L3TableSize, uint32_t L3AddrAlignment)
56*35ffd701SAndroid Build Coastguard Worker {
57*35ffd701SAndroid Build Coastguard Worker     GMM_STATUS       Status = GMM_SUCCESS;
58*35ffd701SAndroid Build Coastguard Worker     GMM_DEVICE_ALLOC Alloc  = {0};
59*35ffd701SAndroid Build Coastguard Worker 
60*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERTPTR(PageTableMgr, GMM_INVALIDPARAM);
61*35ffd701SAndroid Build Coastguard Worker 
62*35ffd701SAndroid Build Coastguard Worker     EnterCriticalSection(&TTLock);
63*35ffd701SAndroid Build Coastguard Worker 
64*35ffd701SAndroid Build Coastguard Worker     Alloc.Size      = L3TableSize;
65*35ffd701SAndroid Build Coastguard Worker     Alloc.Alignment = L3AddrAlignment;
66*35ffd701SAndroid Build Coastguard Worker     Alloc.hCsr      = PageTableMgr->hCsr;
67*35ffd701SAndroid Build Coastguard Worker 
68*35ffd701SAndroid Build Coastguard Worker     Status = __GmmDeviceAlloc(pClientContext, &PageTableMgr->DeviceCbInt, &Alloc);
69*35ffd701SAndroid Build Coastguard Worker     if(Status != GMM_SUCCESS)
70*35ffd701SAndroid Build Coastguard Worker     {
71*35ffd701SAndroid Build Coastguard Worker         LeaveCriticalSection(&TTLock);
72*35ffd701SAndroid Build Coastguard Worker         return Status;
73*35ffd701SAndroid Build Coastguard Worker     }
74*35ffd701SAndroid Build Coastguard Worker 
75*35ffd701SAndroid Build Coastguard Worker     TTL3.GfxAddress         = GMM_GFX_ADDRESS_CANONIZE(Alloc.GfxVA);
76*35ffd701SAndroid Build Coastguard Worker     TTL3.CPUAddress         = Alloc.CPUVA;
77*35ffd701SAndroid Build Coastguard Worker     TTL3.NeedRegisterUpdate = true;
78*35ffd701SAndroid Build Coastguard Worker     TTL3.L3Handle           = (HANDLE)(uintptr_t)Alloc.Handle;
79*35ffd701SAndroid Build Coastguard Worker     TTL3.pGmmResInfo        = (GMM_RESOURCE_INFO *)Alloc.Priv;
80*35ffd701SAndroid Build Coastguard Worker 
81*35ffd701SAndroid Build Coastguard Worker     // Invalidate L3e's
82*35ffd701SAndroid Build Coastguard Worker     for(int i = 0; i < (GMM_L3_SIZE(TTType)); i++)
83*35ffd701SAndroid Build Coastguard Worker     {
84*35ffd701SAndroid Build Coastguard Worker         //initialize L3e ie mark all entries with Null tile/invalid value
85*35ffd701SAndroid Build Coastguard Worker         ((GMM_AUXTTL3e *)TTL3.CPUAddress)[i].Value = 0;
86*35ffd701SAndroid Build Coastguard Worker 
87*35ffd701SAndroid Build Coastguard Worker     }
88*35ffd701SAndroid Build Coastguard Worker 
89*35ffd701SAndroid Build Coastguard Worker     LeaveCriticalSection(&TTLock);
90*35ffd701SAndroid Build Coastguard Worker     return Status;
91*35ffd701SAndroid Build Coastguard Worker }
92*35ffd701SAndroid Build Coastguard Worker 
93*35ffd701SAndroid Build Coastguard Worker //=============================================================================
94*35ffd701SAndroid Build Coastguard Worker //
95*35ffd701SAndroid Build Coastguard Worker // Function: __IsUnusedTRTTPoolOverLimit
96*35ffd701SAndroid Build Coastguard Worker //
97*35ffd701SAndroid Build Coastguard Worker // Desc: Checks if unused TRTTPools have reached residency limit and must be freed.
98*35ffd701SAndroid Build Coastguard Worker //
99*35ffd701SAndroid Build Coastguard Worker // Parameters:
100*35ffd701SAndroid Build Coastguard Worker //      pTRTT_Obj: per-device TT object. Contains TT node info
101*35ffd701SAndroid Build Coastguard Worker //      OverLimitSize: Size in bytes that can be freed
102*35ffd701SAndroid Build Coastguard Worker //
103*35ffd701SAndroid Build Coastguard Worker // Returns:
104*35ffd701SAndroid Build Coastguard Worker //      True, if unused TTPool reached max. residency limit
105*35ffd701SAndroid Build Coastguard Worker //      False, otherwise
106*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
__IsUnusedTRTTPoolOverLimit(GMM_GFX_SIZE_T * OverLimitSize)107*35ffd701SAndroid Build Coastguard Worker bool GmmLib::GmmPageTablePool::__IsUnusedTRTTPoolOverLimit(GMM_GFX_SIZE_T *OverLimitSize)
108*35ffd701SAndroid Build Coastguard Worker {
109*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_SIZE_T             UnusedTrTTPoolSize = 0;
110*35ffd701SAndroid Build Coastguard Worker     GmmLib::GMM_PAGETABLEPool *Pool               = NULL;
111*35ffd701SAndroid Build Coastguard Worker 
112*35ffd701SAndroid Build Coastguard Worker     Pool = this;
113*35ffd701SAndroid Build Coastguard Worker 
114*35ffd701SAndroid Build Coastguard Worker     while(Pool)
115*35ffd701SAndroid Build Coastguard Worker     {
116*35ffd701SAndroid Build Coastguard Worker         if(Pool->NumFreeNodes == PAGETABLE_POOL_MAX_NODES)
117*35ffd701SAndroid Build Coastguard Worker         {
118*35ffd701SAndroid Build Coastguard Worker             UnusedTrTTPoolSize += PAGETABLE_POOL_SIZE;
119*35ffd701SAndroid Build Coastguard Worker         }
120*35ffd701SAndroid Build Coastguard Worker         Pool = Pool->NextPool;
121*35ffd701SAndroid Build Coastguard Worker     }
122*35ffd701SAndroid Build Coastguard Worker 
123*35ffd701SAndroid Build Coastguard Worker     *OverLimitSize = (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? (UnusedTrTTPoolSize - PAGETABLE_POOL_MAX_UNUSED_SIZE) : 0;
124*35ffd701SAndroid Build Coastguard Worker     return (UnusedTrTTPoolSize > PAGETABLE_POOL_MAX_UNUSED_SIZE) ? true : false;
125*35ffd701SAndroid Build Coastguard Worker }
126*35ffd701SAndroid Build Coastguard Worker 
127*35ffd701SAndroid Build Coastguard Worker //=============================================================================
128*35ffd701SAndroid Build Coastguard Worker //
129*35ffd701SAndroid Build Coastguard Worker // Function: AllocateL1L2Table
130*35ffd701SAndroid Build Coastguard Worker //
131*35ffd701SAndroid Build Coastguard Worker // Desc: Assigns pages from AUXTTPool for L1/L2Table for translation of given TRVA
132*35ffd701SAndroid Build Coastguard Worker //
133*35ffd701SAndroid Build Coastguard Worker // Parameters:
134*35ffd701SAndroid Build Coastguard Worker //      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
135*35ffd701SAndroid Build Coastguard Worker //      TileAddr: Tiled Resource Virtual address
136*35ffd701SAndroid Build Coastguard Worker //
137*35ffd701SAndroid Build Coastguard Worker // Returns:
138*35ffd701SAndroid Build Coastguard Worker //     L2Table/L1Table Address
139*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
AllocateL1L2Table(GMM_GFX_ADDRESS TileAddr,GMM_GFX_ADDRESS * L1TableAdr,GMM_GFX_ADDRESS * L2TableAdr)140*35ffd701SAndroid Build Coastguard Worker void GmmLib::PageTable::AllocateL1L2Table(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
141*35ffd701SAndroid Build Coastguard Worker {
142*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_ADDRESS         L3TableAdr = GMM_NO_TABLE;
143*35ffd701SAndroid Build Coastguard Worker     uint32_t                L3eIdx     = static_cast<uint32_t>(GMM_L3_ENTRY_IDX(TTType, TileAddr));
144*35ffd701SAndroid Build Coastguard Worker     uint32_t                L2eIdx     = static_cast<uint32_t>(GMM_L2_ENTRY_IDX(TTType, TileAddr));
145*35ffd701SAndroid Build Coastguard Worker     GmmLib::LastLevelTable *pL1Tbl     = NULL;
146*35ffd701SAndroid Build Coastguard Worker 
147*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERTPTR(pClientContext, VOIDRETURN); // void return
148*35ffd701SAndroid Build Coastguard Worker 
149*35ffd701SAndroid Build Coastguard Worker     *L2TableAdr = GMM_NO_TABLE;
150*35ffd701SAndroid Build Coastguard Worker     *L1TableAdr = GMM_NO_TABLE;
151*35ffd701SAndroid Build Coastguard Worker 
152*35ffd701SAndroid Build Coastguard Worker     if(TTL3.L3Handle)
153*35ffd701SAndroid Build Coastguard Worker     {
154*35ffd701SAndroid Build Coastguard Worker         L3TableAdr = TTL3.GfxAddress;
155*35ffd701SAndroid Build Coastguard Worker     }
156*35ffd701SAndroid Build Coastguard Worker     else
157*35ffd701SAndroid Build Coastguard Worker     {
158*35ffd701SAndroid Build Coastguard Worker         //Should never hit -- L3Table is allocated during device creation
159*35ffd701SAndroid Build Coastguard Worker         __GMM_ASSERT(false);
160*35ffd701SAndroid Build Coastguard Worker     }
161*35ffd701SAndroid Build Coastguard Worker 
162*35ffd701SAndroid Build Coastguard Worker     if(pTTL2[L3eIdx].GetPool())
163*35ffd701SAndroid Build Coastguard Worker     {
164*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
165*35ffd701SAndroid Build Coastguard Worker         PoolElem                            = pTTL2[L3eIdx].GetPool();
166*35ffd701SAndroid Build Coastguard Worker         *L2TableAdr                         = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pTTL2[L3eIdx].GetNodeIdx()) : GMM_NO_TABLE;
167*35ffd701SAndroid Build Coastguard Worker     }
168*35ffd701SAndroid Build Coastguard Worker     else
169*35ffd701SAndroid Build Coastguard Worker     {
170*35ffd701SAndroid Build Coastguard Worker         uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
171*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
172*35ffd701SAndroid Build Coastguard Worker         POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL2;
173*35ffd701SAndroid Build Coastguard Worker         PoolElem                               = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
174*35ffd701SAndroid Build Coastguard Worker         if(PoolElem)
175*35ffd701SAndroid Build Coastguard Worker         {
176*35ffd701SAndroid Build Coastguard Worker             pTTL2[L3eIdx] = MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
177*35ffd701SAndroid Build Coastguard Worker             *L2TableAdr   = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx must be multiple of 8 (Aux L2) and multiple of 2 (Aux L1)
178*35ffd701SAndroid Build Coastguard Worker             ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
179*35ffd701SAndroid Build Coastguard Worker         }
180*35ffd701SAndroid Build Coastguard Worker     }
181*35ffd701SAndroid Build Coastguard Worker 
182*35ffd701SAndroid Build Coastguard Worker     pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
183*35ffd701SAndroid Build Coastguard Worker     if(pL1Tbl)
184*35ffd701SAndroid Build Coastguard Worker     {
185*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem = NULL;
186*35ffd701SAndroid Build Coastguard Worker         PoolElem                            = pL1Tbl->GetPool();
187*35ffd701SAndroid Build Coastguard Worker         *L1TableAdr                         = (PoolElem != NULL) ? PoolElem->GetGfxAddress() + (PAGE_SIZE * pL1Tbl->GetNodeIdx()) : GMM_NO_TABLE;
188*35ffd701SAndroid Build Coastguard Worker     }
189*35ffd701SAndroid Build Coastguard Worker     else
190*35ffd701SAndroid Build Coastguard Worker     {
191*35ffd701SAndroid Build Coastguard Worker         //Allocate L1 Table
192*35ffd701SAndroid Build Coastguard Worker         uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
193*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
194*35ffd701SAndroid Build Coastguard Worker         POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL1;
195*35ffd701SAndroid Build Coastguard Worker 
196*35ffd701SAndroid Build Coastguard Worker         PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
197*35ffd701SAndroid Build Coastguard Worker         if(PoolElem)
198*35ffd701SAndroid Build Coastguard Worker         {
199*35ffd701SAndroid Build Coastguard Worker             pL1Tbl = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext()), L2eIdx); // use TR vs Aux L1_Size_DWORD
200*35ffd701SAndroid Build Coastguard Worker 
201*35ffd701SAndroid Build Coastguard Worker             if(pL1Tbl)
202*35ffd701SAndroid Build Coastguard Worker             {
203*35ffd701SAndroid Build Coastguard Worker                 *L1TableAdr = PoolElem->GetGfxAddress() + PAGE_SIZE * PoolNodeIdx; //PoolNodeIdx should reflect 1 node per Tr-table and 2 nodes per AUX L1 TABLE
204*35ffd701SAndroid Build Coastguard Worker                 if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
205*35ffd701SAndroid Build Coastguard Worker                 {
206*35ffd701SAndroid Build Coastguard Worker                     uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES_2(GetGmmLibContext()) : 1;
207*35ffd701SAndroid Build Coastguard Worker 		    ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
208*35ffd701SAndroid Build Coastguard Worker                 }
209*35ffd701SAndroid Build Coastguard Worker                 pTTL2[L3eIdx].InsertInList(pL1Tbl);
210*35ffd701SAndroid Build Coastguard Worker             }
211*35ffd701SAndroid Build Coastguard Worker         }
212*35ffd701SAndroid Build Coastguard Worker     }
213*35ffd701SAndroid Build Coastguard Worker }
214*35ffd701SAndroid Build Coastguard Worker 
215*35ffd701SAndroid Build Coastguard Worker //=============================================================================
216*35ffd701SAndroid Build Coastguard Worker //
217*35ffd701SAndroid Build Coastguard Worker // Function: AllocateDummyTables
218*35ffd701SAndroid Build Coastguard Worker //
219*35ffd701SAndroid Build Coastguard Worker // Desc: Assigns pages from AUXTTPool for Dummy L1/L2Table
220*35ffd701SAndroid Build Coastguard Worker //
221*35ffd701SAndroid Build Coastguard Worker // Parameters:
222*35ffd701SAndroid Build Coastguard Worker //     L2Table - Ptr to initiatize dummy L2Table
223*35ffd701SAndroid Build Coastguard Worker //     L1Table - Ptr to initiatize dummy L1Table
224*35ffd701SAndroid Build Coastguard Worker //
225*35ffd701SAndroid Build Coastguard Worker // Returns:
226*35ffd701SAndroid Build Coastguard Worker //     L2Table/L1Tables
227*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
AllocateDummyTables(GmmLib::Table ** L2Table,GmmLib::Table ** L1Table)228*35ffd701SAndroid Build Coastguard Worker void GmmLib::PageTable::AllocateDummyTables(GmmLib::Table **L2Table, GmmLib::Table **L1Table)
229*35ffd701SAndroid Build Coastguard Worker {
230*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_ADDRESS         L3TableAdr = GMM_NO_TABLE;
231*35ffd701SAndroid Build Coastguard Worker     GmmLib::LastLevelTable *pL1Tbl     = NULL;
232*35ffd701SAndroid Build Coastguard Worker 
233*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERTPTR(pClientContext, VOIDRETURN);
234*35ffd701SAndroid Build Coastguard Worker 
235*35ffd701SAndroid Build Coastguard Worker     if(TTL3.L3Handle)
236*35ffd701SAndroid Build Coastguard Worker     {
237*35ffd701SAndroid Build Coastguard Worker         L3TableAdr = TTL3.GfxAddress;
238*35ffd701SAndroid Build Coastguard Worker     }
239*35ffd701SAndroid Build Coastguard Worker     else
240*35ffd701SAndroid Build Coastguard Worker     {
241*35ffd701SAndroid Build Coastguard Worker         //Should never hit -- L3Table is allocated during device creation
242*35ffd701SAndroid Build Coastguard Worker         __GMM_ASSERT(false);
243*35ffd701SAndroid Build Coastguard Worker     }
244*35ffd701SAndroid Build Coastguard Worker 
245*35ffd701SAndroid Build Coastguard Worker     //Allocate dummy L2Table
246*35ffd701SAndroid Build Coastguard Worker     {
247*35ffd701SAndroid Build Coastguard Worker         uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
248*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
249*35ffd701SAndroid Build Coastguard Worker         POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL2;
250*35ffd701SAndroid Build Coastguard Worker         PoolElem                               = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType);
251*35ffd701SAndroid Build Coastguard Worker         if(PoolElem)
252*35ffd701SAndroid Build Coastguard Worker         {
253*35ffd701SAndroid Build Coastguard Worker             *L2Table = new GmmLib::MidLevelTable(PoolElem, PoolNodeIdx, PoolElem->GetNodeBBInfoAtIndex(PoolNodeIdx));
254*35ffd701SAndroid Build Coastguard Worker             ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, NodesPerTable)
255*35ffd701SAndroid Build Coastguard Worker         }
256*35ffd701SAndroid Build Coastguard Worker     }
257*35ffd701SAndroid Build Coastguard Worker 
258*35ffd701SAndroid Build Coastguard Worker     //Allocate dummy L1Table
259*35ffd701SAndroid Build Coastguard Worker     {
260*35ffd701SAndroid Build Coastguard Worker         uint32_t                   PoolNodeIdx = PAGETABLE_POOL_MAX_NODES;
261*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *PoolElem    = NULL;
262*35ffd701SAndroid Build Coastguard Worker         POOL_TYPE                  PoolType    = POOL_TYPE_AUXTTL1;
263*35ffd701SAndroid Build Coastguard Worker 
264*35ffd701SAndroid Build Coastguard Worker         PoolElem = PageTableMgr->__GetFreePoolNode(&PoolNodeIdx, PoolType); //Recognize if Aux-L1 being allocated
265*35ffd701SAndroid Build Coastguard Worker         if(PoolElem)
266*35ffd701SAndroid Build Coastguard Worker         {
267*35ffd701SAndroid Build Coastguard Worker             *L1Table = new GmmLib::LastLevelTable(PoolElem, PoolNodeIdx, GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext()), 0); // use TR vs Aux L1_Size_DWORD
268*35ffd701SAndroid Build Coastguard Worker 
269*35ffd701SAndroid Build Coastguard Worker             if(*L1Table)
270*35ffd701SAndroid Build Coastguard Worker             {
271*35ffd701SAndroid Build Coastguard Worker                 if(PoolNodeIdx != PAGETABLE_POOL_MAX_NODES)
272*35ffd701SAndroid Build Coastguard Worker                 {
273*35ffd701SAndroid Build Coastguard Worker                     uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES_2(GetGmmLibContext()) : 1;
274*35ffd701SAndroid Build Coastguard Worker                     ASSIGN_POOLNODE(PoolElem, PoolNodeIdx, PerTableNodes)
275*35ffd701SAndroid Build Coastguard Worker                 }
276*35ffd701SAndroid Build Coastguard Worker             }
277*35ffd701SAndroid Build Coastguard Worker         }
278*35ffd701SAndroid Build Coastguard Worker     }
279*35ffd701SAndroid Build Coastguard Worker }
280*35ffd701SAndroid Build Coastguard Worker 
281*35ffd701SAndroid Build Coastguard Worker //=============================================================================
282*35ffd701SAndroid Build Coastguard Worker //
283*35ffd701SAndroid Build Coastguard Worker // Function: GetL1L2TableAddr
284*35ffd701SAndroid Build Coastguard Worker //
285*35ffd701SAndroid Build Coastguard Worker // Desc: For given tile address, returns L1/L2 Table address if the table exists
286*35ffd701SAndroid Build Coastguard Worker //
287*35ffd701SAndroid Build Coastguard Worker // Parameters:
288*35ffd701SAndroid Build Coastguard Worker //      pAUXTT_Obj: per-device AUX-TT object. Contains AXUTT node info
289*35ffd701SAndroid Build Coastguard Worker //      TileAddr: Tiled Resource Virtual address
290*35ffd701SAndroid Build Coastguard Worker //
291*35ffd701SAndroid Build Coastguard Worker // Returns:
292*35ffd701SAndroid Build Coastguard Worker //     L2Table/L1Table Address
293*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
GetL1L2TableAddr(GMM_GFX_ADDRESS TileAddr,GMM_GFX_ADDRESS * L1TableAdr,GMM_GFX_ADDRESS * L2TableAdr)294*35ffd701SAndroid Build Coastguard Worker void GmmLib::PageTable::GetL1L2TableAddr(GMM_GFX_ADDRESS TileAddr, GMM_GFX_ADDRESS *L1TableAdr, GMM_GFX_ADDRESS *L2TableAdr)
295*35ffd701SAndroid Build Coastguard Worker {
296*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_SIZE_T  L3eIdx, L2eIdx, L1eIdx;
297*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_ADDRESS L3TableAdr = GMM_NO_TABLE;
298*35ffd701SAndroid Build Coastguard Worker     *L2TableAdr                = GMM_NO_TABLE;
299*35ffd701SAndroid Build Coastguard Worker     *L1TableAdr                = GMM_NO_TABLE;
300*35ffd701SAndroid Build Coastguard Worker 
301*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERTPTR(pClientContext, VOIDRETURN);
302*35ffd701SAndroid Build Coastguard Worker 
303*35ffd701SAndroid Build Coastguard Worker     L3eIdx = GMM_L3_ENTRY_IDX(TTType, TileAddr);
304*35ffd701SAndroid Build Coastguard Worker     L2eIdx = GMM_L2_ENTRY_IDX(TTType, TileAddr);
305*35ffd701SAndroid Build Coastguard Worker     L1eIdx = GMM_L1_ENTRY_IDX(TTType, TileAddr, GetGmmLibContext());
306*35ffd701SAndroid Build Coastguard Worker 
307*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERT(TTL3.L3Handle);
308*35ffd701SAndroid Build Coastguard Worker     L3TableAdr = TTL3.GfxAddress;
309*35ffd701SAndroid Build Coastguard Worker     if(pTTL2[L3eIdx].GetPool())
310*35ffd701SAndroid Build Coastguard Worker     {
311*35ffd701SAndroid Build Coastguard Worker         GmmLib::GMM_PAGETABLEPool *Pool   = NULL;
312*35ffd701SAndroid Build Coastguard Worker         GmmLib::LastLevelTable *   pL1Tbl = NULL;
313*35ffd701SAndroid Build Coastguard Worker         Pool                              = pTTL2[L3eIdx].GetPool();
314*35ffd701SAndroid Build Coastguard Worker 
315*35ffd701SAndroid Build Coastguard Worker         if(Pool)
316*35ffd701SAndroid Build Coastguard Worker         {
317*35ffd701SAndroid Build Coastguard Worker             __GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
318*35ffd701SAndroid Build Coastguard Worker             __GMM_ASSERT(pTTL2[L3eIdx].GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
319*35ffd701SAndroid Build Coastguard Worker             __GMM_ASSERT(Pool->GetNodeUsageAtIndex(pTTL2[L3eIdx].GetNodeIdx() / (32 * NodesPerTable)) != 0);
320*35ffd701SAndroid Build Coastguard Worker 
321*35ffd701SAndroid Build Coastguard Worker             *L2TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pTTL2[L3eIdx].GetNodeIdx());
322*35ffd701SAndroid Build Coastguard Worker         }
323*35ffd701SAndroid Build Coastguard Worker 
324*35ffd701SAndroid Build Coastguard Worker         pL1Tbl = pTTL2[L3eIdx].GetL1Table(L2eIdx);
325*35ffd701SAndroid Build Coastguard Worker         if(pL1Tbl && pL1Tbl->GetPool())
326*35ffd701SAndroid Build Coastguard Worker         {
327*35ffd701SAndroid Build Coastguard Worker             Pool = NULL;
328*35ffd701SAndroid Build Coastguard Worker             Pool = pL1Tbl->GetPool();
329*35ffd701SAndroid Build Coastguard Worker             if(Pool)
330*35ffd701SAndroid Build Coastguard Worker             {
331*35ffd701SAndroid Build Coastguard Worker                 uint32_t PerTableNodes = (TTType == AUXTT) ? AUX_L1TABLE_SIZE_IN_POOLNODES_2(GetGmmLibContext()) : 1;
332*35ffd701SAndroid Build Coastguard Worker                 __GMM_ASSERT(Pool->GetNumFreeNode() != PAGETABLE_POOL_MAX_NODES);
333*35ffd701SAndroid Build Coastguard Worker                 __GMM_ASSERT(pL1Tbl->GetNodeIdx() < PAGETABLE_POOL_MAX_NODES);
334*35ffd701SAndroid Build Coastguard Worker                 __GMM_ASSERT(Pool->GetNodeUsageAtIndex(pL1Tbl->GetNodeIdx() / (32 * PerTableNodes)) != 0);
335*35ffd701SAndroid Build Coastguard Worker 
336*35ffd701SAndroid Build Coastguard Worker                 *L1TableAdr = Pool->GetGfxAddress() + PAGE_SIZE * (pL1Tbl->GetNodeIdx());
337*35ffd701SAndroid Build Coastguard Worker             }
338*35ffd701SAndroid Build Coastguard Worker         }
339*35ffd701SAndroid Build Coastguard Worker     }
340*35ffd701SAndroid Build Coastguard Worker }
341*35ffd701SAndroid Build Coastguard Worker 
342*35ffd701SAndroid Build Coastguard Worker //=============================================================================
343*35ffd701SAndroid Build Coastguard Worker //
344*35ffd701SAndroid Build Coastguard Worker // Function: GetMappingType
345*35ffd701SAndroid Build Coastguard Worker //
346*35ffd701SAndroid Build Coastguard Worker // Desc: For given gfx address and size, returns MappingType (null/non-null or
347*35ffd701SAndroid Build Coastguard Worker //       Valid/Invalid) of GfxVA and first gfx address have reverse mapping
348*35ffd701SAndroid Build Coastguard Worker //
349*35ffd701SAndroid Build Coastguard Worker /// @param[in] GfxVA: Gfx Address whose mapping type is being queried
350*35ffd701SAndroid Build Coastguard Worker /// @param[in] Size:  Size of interested Gfx address range
351*35ffd701SAndroid Build Coastguard Worker /// @param[out] LastAddr : 1st Gfx Address having reverse mapping type
352*35ffd701SAndroid Build Coastguard Worker //
353*35ffd701SAndroid Build Coastguard Worker /// @return    1/0 : for non-null/valid vs null/invalid mapping
354*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
GetMappingType(GMM_GFX_ADDRESS GfxVA,GMM_GFX_SIZE_T Size,GMM_GFX_ADDRESS & LastAddr)355*35ffd701SAndroid Build Coastguard Worker uint8_t GmmLib::PageTable::GetMappingType(GMM_GFX_ADDRESS GfxVA, GMM_GFX_SIZE_T Size, GMM_GFX_ADDRESS &LastAddr)
356*35ffd701SAndroid Build Coastguard Worker {
357*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_SIZE_T  L3eIdx, L2eIdx, L1eIdx, L1EntrySize;
358*35ffd701SAndroid Build Coastguard Worker     uint32_t        L1Size, L2Size;
359*35ffd701SAndroid Build Coastguard Worker     uint8_t         MapType      = 0; //true for non-null, false for null mapped
360*35ffd701SAndroid Build Coastguard Worker     bool            bFoundLastVA = false, bTerminate = false;
361*35ffd701SAndroid Build Coastguard Worker     GMM_GFX_ADDRESS TileAddr = GfxVA;
362*35ffd701SAndroid Build Coastguard Worker 
363*35ffd701SAndroid Build Coastguard Worker     L3eIdx      = GMM_L3_ENTRY_IDX(TTType, GfxVA);
364*35ffd701SAndroid Build Coastguard Worker     L2eIdx      = GMM_L2_ENTRY_IDX(TTType, GfxVA);
365*35ffd701SAndroid Build Coastguard Worker     L1eIdx      = GMM_L1_ENTRY_IDX(TTType, GfxVA, GetGmmLibContext());
366*35ffd701SAndroid Build Coastguard Worker     L1EntrySize = WA16K(GetGmmLibContext()) ? GMM_KBYTE(16) : WA64K(GetGmmLibContext()) ? GMM_KBYTE(64) : GMM_MBYTE(1);
367*35ffd701SAndroid Build Coastguard Worker 
368*35ffd701SAndroid Build Coastguard Worker     EnterCriticalSection(&TTLock);
369*35ffd701SAndroid Build Coastguard Worker     __GMM_ASSERT(TTL3.L3Handle);
370*35ffd701SAndroid Build Coastguard Worker 
371*35ffd701SAndroid Build Coastguard Worker #define GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx) \
372*35ffd701SAndroid Build Coastguard Worker     {                                            \
373*35ffd701SAndroid Build Coastguard Worker         L1eIdx = 0;                              \
374*35ffd701SAndroid Build Coastguard Worker         L2eIdx++;                                \
375*35ffd701SAndroid Build Coastguard Worker         if(L2eIdx == (GMM_L2_SIZE(TTType)))      \
376*35ffd701SAndroid Build Coastguard Worker         {                                        \
377*35ffd701SAndroid Build Coastguard Worker             L2eIdx = 0;                          \
378*35ffd701SAndroid Build Coastguard Worker             L3eIdx++;                            \
379*35ffd701SAndroid Build Coastguard Worker             if(L3eIdx == (GMM_L3_SIZE(TTType)))  \
380*35ffd701SAndroid Build Coastguard Worker             {                                    \
381*35ffd701SAndroid Build Coastguard Worker                 bTerminate = true;               \
382*35ffd701SAndroid Build Coastguard Worker             }                                    \
383*35ffd701SAndroid Build Coastguard Worker         }                                        \
384*35ffd701SAndroid Build Coastguard Worker     }
385*35ffd701SAndroid Build Coastguard Worker 
386*35ffd701SAndroid Build Coastguard Worker #define GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx) \
387*35ffd701SAndroid Build Coastguard Worker     {                                            \
388*35ffd701SAndroid Build Coastguard Worker         L1eIdx = L2eIdx = 0;                     \
389*35ffd701SAndroid Build Coastguard Worker         L3eIdx++;                                \
390*35ffd701SAndroid Build Coastguard Worker         if(L3eIdx == (GMM_L3_SIZE(TTType)))      \
391*35ffd701SAndroid Build Coastguard Worker         {                                        \
392*35ffd701SAndroid Build Coastguard Worker             bTerminate = true;                   \
393*35ffd701SAndroid Build Coastguard Worker         }                                        \
394*35ffd701SAndroid Build Coastguard Worker     }
395*35ffd701SAndroid Build Coastguard Worker 
396*35ffd701SAndroid Build Coastguard Worker     while(!(bFoundLastVA || bTerminate) && (TileAddr < GfxVA + Size))
397*35ffd701SAndroid Build Coastguard Worker     {
398*35ffd701SAndroid Build Coastguard Worker         if(pTTL2[L3eIdx].GetPool())
399*35ffd701SAndroid Build Coastguard Worker         {
400*35ffd701SAndroid Build Coastguard Worker             GmmLib::LastLevelTable *pL1Tbl = NULL;
401*35ffd701SAndroid Build Coastguard Worker             pL1Tbl                         = pTTL2[L3eIdx].GetL1Table(L2eIdx);
402*35ffd701SAndroid Build Coastguard Worker             if(pL1Tbl && pL1Tbl->GetPool())
403*35ffd701SAndroid Build Coastguard Worker             {
404*35ffd701SAndroid Build Coastguard Worker                 uint32_t LastBit = 0;
405*35ffd701SAndroid Build Coastguard Worker                 uint32_t i       = static_cast<uint32_t>(L1eIdx) / 32;
406*35ffd701SAndroid Build Coastguard Worker 
407*35ffd701SAndroid Build Coastguard Worker                 while(!bFoundLastVA && i < (uint32_t)(GMM_L1_SIZE_DWORD(TTType, GetGmmLibContext())))
408*35ffd701SAndroid Build Coastguard Worker                 {
409*35ffd701SAndroid Build Coastguard Worker                     uint32_t UsageDW = pL1Tbl->GetUsedEntries()[i++];
410*35ffd701SAndroid Build Coastguard Worker                     uint32_t BitNum  = 31;
411*35ffd701SAndroid Build Coastguard Worker                     if(GfxVA == TileAddr)
412*35ffd701SAndroid Build Coastguard Worker                     {
413*35ffd701SAndroid Build Coastguard Worker                         BitNum  = L1eIdx % 32;
414*35ffd701SAndroid Build Coastguard Worker                         MapType = ((UsageDW & __BIT(BitNum)) ? 0x1 : 0x0); //true for non-null, false for null mapped
415*35ffd701SAndroid Build Coastguard Worker                         UsageDW = (!MapType) ? UsageDW : ~UsageDW;
416*35ffd701SAndroid Build Coastguard Worker                         UsageDW = ((uint64_t)UsageDW >> (BitNum + 1)) << (BitNum + 1); // clear lsb <= BitNum
417*35ffd701SAndroid Build Coastguard Worker                     }
418*35ffd701SAndroid Build Coastguard Worker                     else
419*35ffd701SAndroid Build Coastguard Worker                     {
420*35ffd701SAndroid Build Coastguard Worker                         UsageDW = (!MapType) ? UsageDW : ~UsageDW;
421*35ffd701SAndroid Build Coastguard Worker                     }
422*35ffd701SAndroid Build Coastguard Worker 
423*35ffd701SAndroid Build Coastguard Worker                     if(_BitScanForward((uint32_t *)&LastBit, UsageDW)) // Gets lsb > BitNum, having reverse mapType
424*35ffd701SAndroid Build Coastguard Worker                     {
425*35ffd701SAndroid Build Coastguard Worker                         bFoundLastVA      = true;
426*35ffd701SAndroid Build Coastguard Worker                         uint32_t NumTiles = (GfxVA == TileAddr) ? (LastBit - BitNum) : LastBit;
427*35ffd701SAndroid Build Coastguard Worker                         LastAddr          = TileAddr + NumTiles * L1EntrySize;
428*35ffd701SAndroid Build Coastguard Worker                     }
429*35ffd701SAndroid Build Coastguard Worker                     else
430*35ffd701SAndroid Build Coastguard Worker                     {
431*35ffd701SAndroid Build Coastguard Worker                         uint32_t NumTiles = (GfxVA == TileAddr) ? (32 - BitNum) : 32;
432*35ffd701SAndroid Build Coastguard Worker                         TileAddr += NumTiles * L1EntrySize;
433*35ffd701SAndroid Build Coastguard Worker                     }
434*35ffd701SAndroid Build Coastguard Worker                 }
435*35ffd701SAndroid Build Coastguard Worker                 if(!bFoundLastVA)
436*35ffd701SAndroid Build Coastguard Worker                 {
437*35ffd701SAndroid Build Coastguard Worker                     GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx);
438*35ffd701SAndroid Build Coastguard Worker                 }
439*35ffd701SAndroid Build Coastguard Worker             }
440*35ffd701SAndroid Build Coastguard Worker             else //L2Entry is NULL
441*35ffd701SAndroid Build Coastguard Worker             {
442*35ffd701SAndroid Build Coastguard Worker                 if(MapType) //First hit null-map
443*35ffd701SAndroid Build Coastguard Worker                 {
444*35ffd701SAndroid Build Coastguard Worker                     LastAddr     = TileAddr;
445*35ffd701SAndroid Build Coastguard Worker                     bFoundLastVA = true;
446*35ffd701SAndroid Build Coastguard Worker                 }
447*35ffd701SAndroid Build Coastguard Worker                 else
448*35ffd701SAndroid Build Coastguard Worker                 {
449*35ffd701SAndroid Build Coastguard Worker                     GMM_GFX_SIZE_T NumTiles = GMM_L1_USABLESIZE(TTType, GetGmmLibContext());
450*35ffd701SAndroid Build Coastguard Worker                     if(GfxVA == TileAddr)
451*35ffd701SAndroid Build Coastguard Worker                     {
452*35ffd701SAndroid Build Coastguard Worker                         MapType = false;
453*35ffd701SAndroid Build Coastguard Worker                         NumTiles -= L1eIdx;
454*35ffd701SAndroid Build Coastguard Worker                     }
455*35ffd701SAndroid Build Coastguard Worker                     TileAddr += NumTiles * L1EntrySize;
456*35ffd701SAndroid Build Coastguard Worker                     GET_NEXT_L1TABLE(L1eIdx, L2eIdx, L3eIdx)
457*35ffd701SAndroid Build Coastguard Worker                 }
458*35ffd701SAndroid Build Coastguard Worker             }
459*35ffd701SAndroid Build Coastguard Worker         }
460*35ffd701SAndroid Build Coastguard Worker         else //L3entry is NULL
461*35ffd701SAndroid Build Coastguard Worker         {
462*35ffd701SAndroid Build Coastguard Worker             if(MapType) //First hit null-map
463*35ffd701SAndroid Build Coastguard Worker             {
464*35ffd701SAndroid Build Coastguard Worker                 LastAddr     = TileAddr;
465*35ffd701SAndroid Build Coastguard Worker                 bFoundLastVA = true;
466*35ffd701SAndroid Build Coastguard Worker             }
467*35ffd701SAndroid Build Coastguard Worker             else
468*35ffd701SAndroid Build Coastguard Worker             {
469*35ffd701SAndroid Build Coastguard Worker                 GMM_GFX_SIZE_T NumTiles = 0;
470*35ffd701SAndroid Build Coastguard Worker                 if(GfxVA == TileAddr)
471*35ffd701SAndroid Build Coastguard Worker                 {
472*35ffd701SAndroid Build Coastguard Worker                     MapType  = false;
473*35ffd701SAndroid Build Coastguard Worker                     L1Size   = GMM_L1_USABLESIZE(TTType, GetGmmLibContext()) - L1eIdx;
474*35ffd701SAndroid Build Coastguard Worker                     L2Size   = GMM_L2_SIZE(TTType) - L2eIdx;
475*35ffd701SAndroid Build Coastguard Worker                     NumTiles = ((uint64_t)L1Size * L2Size);
476*35ffd701SAndroid Build Coastguard Worker                 }
477*35ffd701SAndroid Build Coastguard Worker                 else
478*35ffd701SAndroid Build Coastguard Worker                 {
479*35ffd701SAndroid Build Coastguard Worker                     L1Size   = GMM_L1_USABLESIZE(TTType, GetGmmLibContext());
480*35ffd701SAndroid Build Coastguard Worker                     L2Size   = GMM_L2_SIZE(TTType);
481*35ffd701SAndroid Build Coastguard Worker                     NumTiles = ((uint64_t)L1Size * L2Size);
482*35ffd701SAndroid Build Coastguard Worker                 }
483*35ffd701SAndroid Build Coastguard Worker                 TileAddr += NumTiles * L1EntrySize;
484*35ffd701SAndroid Build Coastguard Worker                 GET_NEXT_L2TABLE(L1eIdx, L2eIdx, L3eIdx)
485*35ffd701SAndroid Build Coastguard Worker             }
486*35ffd701SAndroid Build Coastguard Worker         }
487*35ffd701SAndroid Build Coastguard Worker     }
488*35ffd701SAndroid Build Coastguard Worker 
489*35ffd701SAndroid Build Coastguard Worker     if(!bFoundLastVA)
490*35ffd701SAndroid Build Coastguard Worker     {
491*35ffd701SAndroid Build Coastguard Worker         LastAddr = TileAddr;
492*35ffd701SAndroid Build Coastguard Worker     }
493*35ffd701SAndroid Build Coastguard Worker 
494*35ffd701SAndroid Build Coastguard Worker     LeaveCriticalSection(&TTLock);
495*35ffd701SAndroid Build Coastguard Worker     return MapType;
496*35ffd701SAndroid Build Coastguard Worker }
497*35ffd701SAndroid Build Coastguard Worker 
498*35ffd701SAndroid Build Coastguard Worker //=============================================================================
499*35ffd701SAndroid Build Coastguard Worker //
500*35ffd701SAndroid Build Coastguard Worker // Function: TrackTableUsage
501*35ffd701SAndroid Build Coastguard Worker //
502*35ffd701SAndroid Build Coastguard Worker // Desc: For given tile address, updates Table Usage.If Table has all Nullmappings
503*35ffd701SAndroid Build Coastguard Worker //       then its pool node can be unassigned
504*35ffd701SAndroid Build Coastguard Worker //
505*35ffd701SAndroid Build Coastguard Worker // Parameters:
506*35ffd701SAndroid Build Coastguard Worker //      Type:  Translation Table type (Aux)
507*35ffd701SAndroid Build Coastguard Worker //      IsL1:  Is called for L1table or L2 Table
508*35ffd701SAndroid Build Coastguard Worker //      TileAddr: Tiled Resource Virtual address
509*35ffd701SAndroid Build Coastguard Worker //      NullMapped: true if given tiled adr was null mapped, otherwise false
510*35ffd701SAndroid Build Coastguard Worker //
511*35ffd701SAndroid Build Coastguard Worker // Returns:
512*35ffd701SAndroid Build Coastguard Worker //     true, if Table for given tile adr is all null mapped
513*35ffd701SAndroid Build Coastguard Worker //     false,if Table does not exist or has non-null mapping
514*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
TrackTableUsage(TT_TYPE Type,bool IsL1,GMM_GFX_ADDRESS TileAdr,bool NullMapped,GMM_LIB_CONTEXT * pGmmLibContext)515*35ffd701SAndroid Build Coastguard Worker bool GmmLib::Table::TrackTableUsage(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, bool NullMapped, GMM_LIB_CONTEXT *pGmmLibContext )
516*35ffd701SAndroid Build Coastguard Worker {
517*35ffd701SAndroid Build Coastguard Worker     uint32_t EntryIdx;
518*35ffd701SAndroid Build Coastguard Worker     uint32_t ElemNum = 0, BitNum = 0;
519*35ffd701SAndroid Build Coastguard Worker 
520*35ffd701SAndroid Build Coastguard Worker     EntryIdx = IsL1 ? static_cast<uint32_t>(GMM_L1_ENTRY_IDX(Type, TileAdr, pGmmLibContext)) : static_cast<uint32_t>(GMM_L2_ENTRY_IDX(Type, TileAdr));
521*35ffd701SAndroid Build Coastguard Worker 
522*35ffd701SAndroid Build Coastguard Worker     ElemNum = EntryIdx / (sizeof(UsedEntries[0]) * 8);
523*35ffd701SAndroid Build Coastguard Worker     BitNum  = EntryIdx % (sizeof(UsedEntries[0]) * 8);
524*35ffd701SAndroid Build Coastguard Worker 
525*35ffd701SAndroid Build Coastguard Worker     if(NullMapped)
526*35ffd701SAndroid Build Coastguard Worker     {
527*35ffd701SAndroid Build Coastguard Worker         UsedEntries[ElemNum] &= ~(1 << BitNum);
528*35ffd701SAndroid Build Coastguard Worker     }
529*35ffd701SAndroid Build Coastguard Worker     else
530*35ffd701SAndroid Build Coastguard Worker     {
531*35ffd701SAndroid Build Coastguard Worker         UsedEntries[ElemNum] |= (1 << BitNum);
532*35ffd701SAndroid Build Coastguard Worker     }
533*35ffd701SAndroid Build Coastguard Worker 
534*35ffd701SAndroid Build Coastguard Worker     if(NullMapped)
535*35ffd701SAndroid Build Coastguard Worker     {
536*35ffd701SAndroid Build Coastguard Worker         int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type,  pGmmLibContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
537*35ffd701SAndroid Build Coastguard Worker         for(int i = 0; i < TableDWSize; i++)
538*35ffd701SAndroid Build Coastguard Worker         {
539*35ffd701SAndroid Build Coastguard Worker             if(UsedEntries[i])
540*35ffd701SAndroid Build Coastguard Worker             {
541*35ffd701SAndroid Build Coastguard Worker                 return false;
542*35ffd701SAndroid Build Coastguard Worker             }
543*35ffd701SAndroid Build Coastguard Worker         }
544*35ffd701SAndroid Build Coastguard Worker     }
545*35ffd701SAndroid Build Coastguard Worker     return NullMapped ? true : false;
546*35ffd701SAndroid Build Coastguard Worker }
547*35ffd701SAndroid Build Coastguard Worker 
548*35ffd701SAndroid Build Coastguard Worker //=============================================================================
549*35ffd701SAndroid Build Coastguard Worker //
550*35ffd701SAndroid Build Coastguard Worker // Function: __IsTableNullMapped
551*35ffd701SAndroid Build Coastguard Worker //
552*35ffd701SAndroid Build Coastguard Worker // Desc: For given tile address, checks if given Table has all Nullmappings
553*35ffd701SAndroid Build Coastguard Worker //       then its pool node can be unassigned
554*35ffd701SAndroid Build Coastguard Worker //
555*35ffd701SAndroid Build Coastguard Worker // Parameters:
556*35ffd701SAndroid Build Coastguard Worker //      Type:  Translation Table type (TR or Aux)
557*35ffd701SAndroid Build Coastguard Worker //      IsL1:  Is called for L1table or L2 Table
558*35ffd701SAndroid Build Coastguard Worker //      TileAddr: Tiled Resource Virtual address
559*35ffd701SAndroid Build Coastguard Worker //
560*35ffd701SAndroid Build Coastguard Worker // Returns:
561*35ffd701SAndroid Build Coastguard Worker //     true, if Table for given tile adr is all null mapped
562*35ffd701SAndroid Build Coastguard Worker //     false,if Table has non-null mapping
563*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
IsTableNullMapped(TT_TYPE Type,bool IsL1,GMM_GFX_ADDRESS TileAdr,GMM_LIB_CONTEXT * pGmmLibContext)564*35ffd701SAndroid Build Coastguard Worker bool GmmLib::Table::IsTableNullMapped(TT_TYPE Type, bool IsL1, GMM_GFX_ADDRESS TileAdr, GMM_LIB_CONTEXT *pGmmLibContext)
565*35ffd701SAndroid Build Coastguard Worker {
566*35ffd701SAndroid Build Coastguard Worker     GMM_UNREFERENCED_PARAMETER(TileAdr);
567*35ffd701SAndroid Build Coastguard Worker     int TableDWSize = IsL1 ? static_cast<int>(GMM_L1_SIZE_DWORD(Type, pGmmLibContext)) : static_cast<int>(GMM_L2_SIZE_DWORD(Type));
568*35ffd701SAndroid Build Coastguard Worker     for(int i = 0; i < TableDWSize; i++)
569*35ffd701SAndroid Build Coastguard Worker     {
570*35ffd701SAndroid Build Coastguard Worker         if(UsedEntries[i])
571*35ffd701SAndroid Build Coastguard Worker         {
572*35ffd701SAndroid Build Coastguard Worker             return false;
573*35ffd701SAndroid Build Coastguard Worker         }
574*35ffd701SAndroid Build Coastguard Worker     }
575*35ffd701SAndroid Build Coastguard Worker     return true;
576*35ffd701SAndroid Build Coastguard Worker }
577*35ffd701SAndroid Build Coastguard Worker 
578*35ffd701SAndroid Build Coastguard Worker //=============================================================================
579*35ffd701SAndroid Build Coastguard Worker //
580*35ffd701SAndroid Build Coastguard Worker // Function: __UpdatePoolFence
581*35ffd701SAndroid Build Coastguard Worker //
582*35ffd701SAndroid Build Coastguard Worker // Desc: Updates AUXTTPool's or Table's BBFenceObj/value with current BB fence
583*35ffd701SAndroid Build Coastguard Worker //
584*35ffd701SAndroid Build Coastguard Worker // Parameters:
585*35ffd701SAndroid Build Coastguard Worker //      pAUXTT_Obj: per-device AUX-TT object. Contains AUXTT node info
586*35ffd701SAndroid Build Coastguard Worker //      Table:     L1/L2 table pointer
587*35ffd701SAndroid Build Coastguard Worker //      L1Table:   true for L1 Table, else false
588*35ffd701SAndroid Build Coastguard Worker //      ClearNode: if true, Fence info is cleared for table
589*35ffd701SAndroid Build Coastguard Worker //                    false, Fence info is updated for table and pool
590*35ffd701SAndroid Build Coastguard Worker //-----------------------------------------------------------------------------
UpdatePoolFence(GMM_UMD_SYNCCONTEXT * UmdContext,bool ClearNode)591*35ffd701SAndroid Build Coastguard Worker void GmmLib::Table::UpdatePoolFence(GMM_UMD_SYNCCONTEXT *UmdContext, bool ClearNode)
592*35ffd701SAndroid Build Coastguard Worker {
593*35ffd701SAndroid Build Coastguard Worker     if(!ClearNode)
594*35ffd701SAndroid Build Coastguard Worker     {
595*35ffd701SAndroid Build Coastguard Worker         //update both node and pool with current fence/handle
596*35ffd701SAndroid Build Coastguard Worker         PoolElem->GetPoolBBInfo().BBQueueHandle =
597*35ffd701SAndroid Build Coastguard Worker         BBInfo.BBQueueHandle = UmdContext->BBFenceObj;
598*35ffd701SAndroid Build Coastguard Worker         PoolElem->GetPoolBBInfo().BBFence =
599*35ffd701SAndroid Build Coastguard Worker         BBInfo.BBFence = UmdContext->BBLastFence + 1; //Save incremented fence value, since DX does it during submission
600*35ffd701SAndroid Build Coastguard Worker     }
601*35ffd701SAndroid Build Coastguard Worker     else
602*35ffd701SAndroid Build Coastguard Worker     {
603*35ffd701SAndroid Build Coastguard Worker         //Clear node fence/handle
604*35ffd701SAndroid Build Coastguard Worker         BBInfo.BBQueueHandle = 0;
605*35ffd701SAndroid Build Coastguard Worker         BBInfo.BBFence       = 0;
606*35ffd701SAndroid Build Coastguard Worker     }
607*35ffd701SAndroid Build Coastguard Worker }
608*35ffd701SAndroid Build Coastguard Worker 
609*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
610*35ffd701SAndroid Build Coastguard Worker /// Releases all PageTable Pool(s) existing in Linked List
611*35ffd701SAndroid Build Coastguard Worker ///
612*35ffd701SAndroid Build Coastguard Worker /// @param[in]  DeviceCallbacks   pointer to device callbacks structure
613*35ffd701SAndroid Build Coastguard Worker /// @return     GMM_STATUS
614*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
__DestroyPageTablePool(void * DeviceCallbacks,HANDLE hCsr)615*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::GmmPageTablePool::__DestroyPageTablePool(void *DeviceCallbacks, HANDLE hCsr)
616*35ffd701SAndroid Build Coastguard Worker {
617*35ffd701SAndroid Build Coastguard Worker     GMM_STATUS                Status   = GMM_SUCCESS;
618*35ffd701SAndroid Build Coastguard Worker     GMM_DEVICE_CALLBACKS_INT *DeviceCb = static_cast<GMM_DEVICE_CALLBACKS_INT *>(DeviceCallbacks);
619*35ffd701SAndroid Build Coastguard Worker 
620*35ffd701SAndroid Build Coastguard Worker     GMM_PAGETABLEPool *Node = this, *Next = NULL;
621*35ffd701SAndroid Build Coastguard Worker     GMM_CLIENT         ClientType;
622*35ffd701SAndroid Build Coastguard Worker     GMM_DEVICE_DEALLOC Dealloc = {0};
623*35ffd701SAndroid Build Coastguard Worker 
624*35ffd701SAndroid Build Coastguard Worker     //Evict/Free gpu Va is implictly done by OS when de-allocating
625*35ffd701SAndroid Build Coastguard Worker     while(Node)
626*35ffd701SAndroid Build Coastguard Worker     {
627*35ffd701SAndroid Build Coastguard Worker         Next = Node->NextPool;
628*35ffd701SAndroid Build Coastguard Worker 
629*35ffd701SAndroid Build Coastguard Worker         GET_GMM_CLIENT_TYPE(Node->pClientContext, ClientType);
630*35ffd701SAndroid Build Coastguard Worker 
631*35ffd701SAndroid Build Coastguard Worker         Dealloc.Handle = Node->PoolHandle;
632*35ffd701SAndroid Build Coastguard Worker         Dealloc.GfxVA  = Node->PoolGfxAddress;
633*35ffd701SAndroid Build Coastguard Worker         Dealloc.Priv   = Node->pGmmResInfo;
634*35ffd701SAndroid Build Coastguard Worker         Dealloc.hCsr   = hCsr;
635*35ffd701SAndroid Build Coastguard Worker 
636*35ffd701SAndroid Build Coastguard Worker         Status = __GmmDeviceDealloc(ClientType, DeviceCb, &Dealloc, Node->pClientContext);
637*35ffd701SAndroid Build Coastguard Worker 
638*35ffd701SAndroid Build Coastguard Worker         Node->PoolHandle     = NULL;
639*35ffd701SAndroid Build Coastguard Worker         Node->PoolGfxAddress = 0;
640*35ffd701SAndroid Build Coastguard Worker         delete Node;
641*35ffd701SAndroid Build Coastguard Worker         Node = Next;
642*35ffd701SAndroid Build Coastguard Worker     }
643*35ffd701SAndroid Build Coastguard Worker 
644*35ffd701SAndroid Build Coastguard Worker     return Status;
645*35ffd701SAndroid Build Coastguard Worker }
646*35ffd701SAndroid Build Coastguard Worker 
647*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
648*35ffd701SAndroid Build Coastguard Worker /// Releases memory allocated to PageTable's Root-table
649*35ffd701SAndroid Build Coastguard Worker ///
650*35ffd701SAndroid Build Coastguard Worker /// @return     GMM_STATUS
651*35ffd701SAndroid Build Coastguard Worker /////////////////////////////////////////////////////////////////////////////////////
DestroyL3Table()652*35ffd701SAndroid Build Coastguard Worker GMM_STATUS GmmLib::PageTable::DestroyL3Table()
653*35ffd701SAndroid Build Coastguard Worker {
654*35ffd701SAndroid Build Coastguard Worker     GMM_STATUS         Status = GMM_SUCCESS;
655*35ffd701SAndroid Build Coastguard Worker     uint8_t            hr     = GMM_SUCCESS;
656*35ffd701SAndroid Build Coastguard Worker     GMM_CLIENT         ClientType;
657*35ffd701SAndroid Build Coastguard Worker     GMM_DEVICE_DEALLOC Dealloc = {0};
658*35ffd701SAndroid Build Coastguard Worker 
659*35ffd701SAndroid Build Coastguard Worker     GET_GMM_CLIENT_TYPE(pClientContext, ClientType);
660*35ffd701SAndroid Build Coastguard Worker 
661*35ffd701SAndroid Build Coastguard Worker     EnterCriticalSection(&TTLock);
662*35ffd701SAndroid Build Coastguard Worker 
663*35ffd701SAndroid Build Coastguard Worker     if(TTL3.L3Handle)
664*35ffd701SAndroid Build Coastguard Worker     {
665*35ffd701SAndroid Build Coastguard Worker         Dealloc.Handle = TTL3.L3Handle;
666*35ffd701SAndroid Build Coastguard Worker         Dealloc.GfxVA  = TTL3.GfxAddress;
667*35ffd701SAndroid Build Coastguard Worker         Dealloc.Priv   = TTL3.pGmmResInfo;
668*35ffd701SAndroid Build Coastguard Worker         Dealloc.hCsr   = PageTableMgr->hCsr;
669*35ffd701SAndroid Build Coastguard Worker 
670*35ffd701SAndroid Build Coastguard Worker         Status = __GmmDeviceDealloc(ClientType, &PageTableMgr->DeviceCbInt, &Dealloc, pClientContext);
671*35ffd701SAndroid Build Coastguard Worker 
672*35ffd701SAndroid Build Coastguard Worker         TTL3.L3Handle   = NULL;
673*35ffd701SAndroid Build Coastguard Worker         TTL3.GfxAddress = 0;
674*35ffd701SAndroid Build Coastguard Worker         TTL3.CPUAddress = 0;
675*35ffd701SAndroid Build Coastguard Worker     }
676*35ffd701SAndroid Build Coastguard Worker 
677*35ffd701SAndroid Build Coastguard Worker     LeaveCriticalSection(&TTLock);
678*35ffd701SAndroid Build Coastguard Worker     return Status;
679*35ffd701SAndroid Build Coastguard Worker }
680*35ffd701SAndroid Build Coastguard Worker 
681*35ffd701SAndroid Build Coastguard Worker #endif //!__GMM_KMD
682