1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2014-2019 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3  * SPDX-License-Identifier: MIT
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23 #ifndef _NV_GMMU_FMT_H_
24 #define _NV_GMMU_FMT_H_
25 
26 #include <ctrl/ctrl90f1.h>
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 /*!
33  * @file gmmu_fmt.h
34  *
35  * @brief Defines a light abstraction over GPU MMU (GMMU) HW formats.
36  *
37  * There are two main components of the abstraction:
38  * 1. General topology of the format provided by mmu_fmt.h.
39  * 2. Description of the fields within PDEs and PTEs described by the
40  *    field_desc.h and GMMU_FMT_P*E structs.
41  *
42  * The GMMU_FMT structure wraps these compoments together.
43  *
44  * The goals of this abstraction are:
45  * G1. Allow common page table management code to work across a variety
46  *     of GMMU HW formats.
47  * G2. Provide as much low-level control as if directly using the HW
48  *     manuals.
49  * G3. As close to DRF-macro efficiency as possible for critical paths.
50  *     An example of a critical path is writing PTE values in a tight loop.
51  *     On the other hand, PDE value writes (some which have more complex
52  *     formats) occur orders of magnitude less frequently, and thus can
53  *     afford more generality.
54  *
55  * One design consideration is how to distinguish
56  * MMU fields which are specific to certain architectures.
57  *
58  * The current approach is to describe the union of all fields
59  * across the supported formats.
60  * HW that does not support a given field must initialize the descriptor to
61  * zero (invalid) which will assert in the field setter/getter if used.
62  *
63  * While this introduces risk of "kitchen sink" syndrome, this approach was
64  * taken for the following reasons:
65  * 1. There are few fundamental feature differences between GMMU formats.
66  * 2. GMMU formats change relatively infrequently (e.g. rarely per-chip).
67  */
68 
69 #include "nvtypes.h"
70 #include "field_desc.h"
71 #include "mmu_fmt.h"
72 
73 //
74 // Defines needed by PCF programming in PTE V3.
75 // Index bits are used when callers set flags. The below defines are only used
76 // for the HW <-> SW translation.
77 //
78 
79 //
80 // Note: The following PCF patterns have not been verified in HW
81 // and have been currently added to help overcome issues wrt
82 // PCF patterns tested in rmtest.
83 //
84 // SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD
85 // SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACE
86 // SW_MMU_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACE
87 // SW_MMU_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACE
88 // SW_MMU_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACE
89 // SW_MMU_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACE
90 // SW_MMU_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACE
91 // SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD
92 // SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD
93 // SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACE
94 //
95 
96 // Used by PDE
97 #define SW_MMU_PDE_PCF_INVALID_ATS_ALLOWED                  0x00000201
98 #define SW_MMU_PDE_PCF_INVALID_ATS_NOT_ALLOWED              0x00000001
99 #define SW_MMU_PDE_PCF_SPARSE_ATS_ALLOWED                   0x00000204
100 #define SW_MMU_PDE_PCF_SPARSE_ATS_NOT_ALLOWED               0x00000004
101 
102 #define SW_MMU_PDE_PCF_VALID_CACHED_ATS_ALLOWED             0x00000200
103 #define SW_MMU_PDE_PCF_VALID_UNCACHED_ATS_ALLOWED           0x00000220
104 #define SW_MMU_PDE_PCF_VALID_CACHED_ATS_NOT_ALLOWED         0x00000000
105 #define SW_MMU_PDE_PCF_VALID_UNCACHED_ATS_NOT_ALLOWED       0x00000020
106 
107 // Used by PTEs
108 #define SW_MMU_PTE_PCF_INVALID                              0x00000001
109 #define SW_MMU_PTE_PCF_NO_VALID_4KB_PAGE                    0x00000002
110 #define SW_MMU_PTE_PCF_SPARSE                               0x00000004
111 #define SW_MMU_PTE_PCF_MAPPING_NOWHERE                      0x00000008
112 
113 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACD       0x00000000
114 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_CACHED_ACE       0x00000010
115 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACD     0x00000020
116 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_ATOMIC_UNCACHED_ACE     0x00000030
117 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_CACHED_ACE    0x00000050
118 #define SW_MMU_PTE_PCF_PRIVILEGE_RW_NO_ATOMIC_UNCACHED_ACE  0x00000070
119 #define SW_MMU_PTE_PCF_PRIVILEGE_RO_ATOMIC_UNCACHED_ACE     0x000000B0
120 #define SW_MMU_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_CACHED_ACE    0x000000D0
121 #define SW_MMU_PTE_PCF_PRIVILEGE_RO_NO_ATOMIC_UNCACHED_ACE  0x000000F0
122 
123 #define SW_MMU_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACD         0x00000100
124 #define SW_MMU_PTE_PCF_REGULAR_RW_ATOMIC_CACHED_ACE         0x00000110
125 #define SW_MMU_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACD       0x00000120
126 #define SW_MMU_PTE_PCF_REGULAR_RW_ATOMIC_UNCACHED_ACE       0x00000130
127 
128 #define SW_MMU_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACD      0x00000140
129 #define SW_MMU_PTE_PCF_REGULAR_RW_NO_ATOMIC_CACHED_ACE      0x00000150
130 #define SW_MMU_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACD    0x00000160
131 #define SW_MMU_PTE_PCF_REGULAR_RW_NO_ATOMIC_UNCACHED_ACE    0x00000170
132 
133 #define SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACD         0x00000180
134 #define SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_CACHED_ACE         0x00000190
135 #define SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACD       0x000001A0
136 #define SW_MMU_PTE_PCF_REGULAR_RO_ATOMIC_UNCACHED_ACE       0x000001B0
137 
138 #define SW_MMU_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACD      0x000001C0
139 #define SW_MMU_PTE_PCF_REGULAR_RO_NO_ATOMIC_CACHED_ACE      0x000001D0
140 #define SW_MMU_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACD    0x000001E0
141 #define SW_MMU_PTE_PCF_REGULAR_RO_NO_ATOMIC_UNCACHED_ACE    0x000001F0
142 
143 //
144 // Defines all toggles in either PTE or PDE PCF space
145 // Note: please do not change these defines without careful review!
146 // PTE and PDE defines are allowed to collide as they will not be
147 // processed in the same code paths anyway.
148 //
149 #define SW_MMU_PCF_INVALID_IDX     0  // Used for PDE and PTE
150 #define SW_MMU_PCF_NV4K_IDX        1  // PTE specific
151 #define SW_MMU_PCF_SPARSE_IDX      2  // Used for PDE and PTE
152 #define SW_MMU_PCF_NOMAPPING_IDX   3  // PTE specific
153 
154 #define SW_MMU_PCF_ACE_IDX         4  // PTE specific
155 #define SW_MMU_PCF_UNCACHED_IDX    5  // Used for PDE and PTE
156 #define SW_MMU_PCF_NOATOMIC_IDX    6  // PTE specific
157 #define SW_MMU_PCF_RO_IDX          7  // PTE specific
158 
159 #define SW_MMU_PCF_REGULAR_IDX     8  // PTE specific
160 #define SW_MMU_PCF_ATS_ALLOWED_IDX 9  // PDE specific
161 
162 // Forward declarations.
163 typedef union  GMMU_ENTRY_VALUE     GMMU_ENTRY_VALUE;
164 typedef struct GMMU_FIELD_APERTURE  GMMU_FIELD_APERTURE;
165 typedef struct GMMU_FIELD_ADDRESS   GMMU_FIELD_ADDRESS;
166 typedef struct GMMU_FMT             GMMU_FMT;
167 typedef struct GMMU_FMT_PDE         GMMU_FMT_PDE;
168 typedef struct GMMU_FMT_PDE_MULTI   GMMU_FMT_PDE_MULTI;
169 typedef struct GMMU_FMT_PTE         GMMU_FMT_PTE;
170 typedef struct GMMU_COMPR_INFO      GMMU_COMPR_INFO;
171 
172 /*!
173  * Maximum size in bytes of page directory and table entries across
174  * the supported formats.
175  */
176 #define GMMU_FMT_MAX_ENTRY_SIZE 16
177 
178 /*!
179  * Default version specifier for API args to indicate no preference.
180  * This is not a real version number and not part of the
181  * enumeration array below.
182  */
183 #define GMMU_FMT_VERSION_DEFAULT  0
184 
185 /*!
186  * 2-level (40b VA) format supported Fermi through Maxwell.
187  * Still supported in Pascal HW as fallback.
188  */
189 #define GMMU_FMT_VERSION_1        1
190 
191 /*!
192  * 5-level (49b VA) format supported on Pascal+.
193  */
194 #define GMMU_FMT_VERSION_2        2
195 
196 /*!
197  * 6-level (57b VA) format supported on Hopper+.
198  */
199 #define GMMU_FMT_VERSION_3        3
200 
201 /*!
202  * Maximum number of MMU versions supported.
203  */
204 #define GMMU_FMT_MAX_VERSION_COUNT 3
205 
206 /*!
207  * Array of format version numbers for enumeration utility.
208  */
209 extern const NvU32 g_gmmuFmtVersions[GMMU_FMT_MAX_VERSION_COUNT];
210 
211 /*!
212  * Maximum number of big page sizes supported by a single GPU.
213  */
214 #define GMMU_FMT_MAX_BIG_PAGE_SIZES 2
215 
216 /*!
217  * Array of big page shifts for enumeration utility.
218  */
219 extern const NvU32 g_gmmuFmtBigPageShifts[GMMU_FMT_MAX_BIG_PAGE_SIZES];
220 
221 /*!
222  * Convenience type for declaring generic temporary GMMU entry values.
223  */
224 union GMMU_ENTRY_VALUE
225 {
226     NvU8   v8[GMMU_FMT_MAX_ENTRY_SIZE / 1];
227     NvU32 v32[GMMU_FMT_MAX_ENTRY_SIZE / 4];
228     NvU64 v64[GMMU_FMT_MAX_ENTRY_SIZE / 8];
229 };
230 
231 /*!
232  * Top-level structure describing a GPU MMU format.
233  */
234 struct GMMU_FMT
235 {
236     NvU32 version;
237 
238     /*!
239      * Root of the page level topology (e.g. the root page directory).
240      */
241     const MMU_FMT_LEVEL *pRoot;
242 
243     /*!
244      * Description of page directory entry fields common
245      * across page directory levels with a single sub-level.
246      */
247     const GMMU_FMT_PDE       *pPde;
248 
249     /*!
250      * Description of page directory entry fields common
251      * across page directory levels with two sub-levels.
252      */
253     const GMMU_FMT_PDE_MULTI *pPdeMulti;
254 
255     /*!
256      * Description of page table entry fields common
257      * across all page table levels in the topology.
258      */
259     const GMMU_FMT_PTE       *pPte;
260 
261     /*!
262      * Indicates if the MMU HW supports sparse through the
263      * volatile field of each PDE/PTE.
264      */
265     NvBool bSparseHwSupport;
266 };
267 
268 /*!
269  * Physical apertures for the supported GMMU formats.
270  */
271 typedef enum
272 {
273     /*!
274      * Indicates an invalid aperture.
275      * @note Only supported for GPU PDEs to distinguish invalid sub-sevels.
276      */
277     GMMU_APERTURE_INVALID,
278 
279     /*!
280      * GPU-local video memory (a.k.a. FB).
281      * @note Only supported for GPU PDEs and PTEs.
282      */
283     GMMU_APERTURE_VIDEO,
284 
285     /*!
286      * GPU-peer video memory.
287      * @note Only supported for GPU PTEs.
288      * @note Peer index must be initialized in the appropriate address field.
289      */
290     GMMU_APERTURE_PEER,
291 
292     /*!
293      * Non-coherent system memory.
294      *
295      * (GPU) MMU will NOT maintain coherence with CPU L2 cache.
296      *
297      * Higher-level APIs should only allow this when it is known
298      * the memory is not cacheable by CPU or the coherency is
299      * managed explicitly (e.g. w/ flushes in SW).
300      * Also consider that this path is not necessarily faster.
301      */
302     GMMU_APERTURE_SYS_NONCOH,
303 
304     /*!
305      * Coherent system memory.
306      *
307      * (GPU) MMU will snoop CPU L2 cache if possible.
308      * TODO: Wiki link on arch differences.
309      *
310      * This is usually the safer choice over NONCOH since it works
311      * whether the memory is cached by CPU L2 or not.
312      * On some CPU architectures going through CPU L2 may
313      * even be faster than the non-coherent path.
314      */
315     GMMU_APERTURE_SYS_COH,
316 
317     // Last value.
318     GMMU_APERTURE__COUNT
319 } GMMU_APERTURE;
320 
321 /*!
322  * Aperture field descriptor.
323  */
324 struct GMMU_FIELD_APERTURE
325 {
326     NV_FIELD_ENUM _enum;
327 };
328 
329 #define INIT_FIELD_APERTURE(pAper, drf, _entries)                               \
330     do {                                                                        \
331         INIT_FIELD_ENUM(&(pAper)->_enum, drf, GMMU_APERTURE__COUNT, _entries);  \
332     } while(0)
333 
334 /*!
335  * Encode and set a GMMU aperture enum value to a HW aperture field.
336  */
337 static NV_FORCEINLINE void
gmmuFieldSetAperture(const GMMU_FIELD_APERTURE * pAperture,const GMMU_APERTURE value,NvU8 * pMem)338 gmmuFieldSetAperture
339 (
340     const GMMU_FIELD_APERTURE *pAperture,
341     const GMMU_APERTURE        value,
342     NvU8                      *pMem
343 )
344 {
345     nvFieldSetEnum(&pAperture->_enum, value, pMem);
346 }
347 
348 /*!
349  * Get and decode a HW aperture field value to a GMMU aperture enum value.
350  */
351 static NV_FORCEINLINE GMMU_APERTURE
gmmuFieldGetAperture(const GMMU_FIELD_APERTURE * pAperture,const NvU8 * pMem)352 gmmuFieldGetAperture
353 (
354     const GMMU_FIELD_APERTURE *pAperture,
355     const NvU8                *pMem
356 )
357 {
358     return (GMMU_APERTURE)nvFieldGetEnum(&pAperture->_enum, pMem);
359 }
360 
361 /*!
362  * Address field descriptor.
363  */
364 struct GMMU_FIELD_ADDRESS
365 {
366     NV_FIELD_DESC64 desc;
367     NvU32           shift;
368 };
369 
370 #define INIT_FIELD_ADDRESS(pAddr, drf, _shift)          \
371     do {                                                \
372         INIT_FIELD_DESC64(&(pAddr)->desc, drf);         \
373         (pAddr)->shift = _shift;                        \
374     } while(0)
375 
376 /*!
377  * Encode (shift) and set a GMMU address field.
378  */
379 static NV_FORCEINLINE void
gmmuFieldSetAddress(const GMMU_FIELD_ADDRESS * pField,const NvU64 address,NvU8 * pMem)380 gmmuFieldSetAddress
381 (
382     const GMMU_FIELD_ADDRESS *pField,
383     const NvU64               address,
384     NvU8                     *pMem
385 )
386 {
387     NV_ASSERT_CHECKED_PRECOMP(0 == (address & (NVBIT64(pField->shift) - 1)));
388     nvFieldSet64(&pField->desc, address >> pField->shift, pMem);
389 }
390 
391 /*!
392  * Get and decode (shift) a GMMU address field.
393  */
394 static NV_FORCEINLINE NvU64
gmmuFieldGetAddress(const GMMU_FIELD_ADDRESS * pField,const NvU8 * pMem)395 gmmuFieldGetAddress
396 (
397     const GMMU_FIELD_ADDRESS *pField,
398     const NvU8               *pMem
399 )
400 {
401     return nvFieldGet64(&pField->desc, pMem) << pField->shift;
402 }
403 
404 /*!
405  * Page directory entry (PDE) format.
406  */
407 struct GMMU_FMT_PDE
408 {
409     /*!
410      * Version information is needed to interpret fields differently.
411      * Should be always the same as version in GMMU_FMT above.
412      */
413     NvU32 version;
414 
415     /*!
416      * Aperture field indicating which physical address space the sublevel resides.
417      */
418     GMMU_FIELD_APERTURE fldAperture;
419 
420     /*!
421      * Physical address field when aperture is system memory.
422      */
423     GMMU_FIELD_ADDRESS fldAddrSysmem;
424 
425     /*!
426      * Physical address field when aperture is video memory.
427      */
428     GMMU_FIELD_ADDRESS fldAddrVidmem;
429 
430     /*!
431      * Physical address field (used by V3 format only).
432      */
433     GMMU_FIELD_ADDRESS fldAddr;
434 
435     /*!
436      * Indicates GPU reads memory on every access to the
437      * next page directory/table level.
438      *
439      * @note This is not the same as caching, and is ignored for some
440      *       apertures on some chips.
441      *       TODO: Wiki link to explain arch differences.
442      */
443     NV_FIELD_BOOL fldVolatile;
444 
445     /*!
446      * PDE_PCF field for V3 format.
447      */
448     NV_FIELD_DESC32 fldPdePcf;
449 };
450 
451 /*!
452  * Get the PDE physical address field format for a given aperture.
453  */
454 const GMMU_FIELD_ADDRESS *gmmuFmtPdePhysAddrFld(
455                         const GMMU_FMT_PDE *pPde,
456                         const GMMU_APERTURE aperture);
457 
458 /*!
459  * Multi (e.g. dual) page directory entry format.
460  */
461 struct GMMU_FMT_PDE_MULTI
462 {
463     /*!
464      * Reciprocal exponent field for partial sub-level size.
465      * Minimum size of each sub-level is FullLevelSize / (2 ^ sizeRecipExpMax).
466      */
467     NV_FIELD_DESC32 fldSizeRecipExp;
468 
469     /*!
470      * Per-sub-level information.
471      */
472     GMMU_FMT_PDE subLevels[MMU_FMT_MAX_SUB_LEVELS];
473 };
474 
475 /*!
476  * Retrieve the PDE format corresponding to a particular level and sub-level.
477  *
478  * @param[in]  pFmt     MMU format.
479  * @param[in]  pLevel   Level format.
480  * @param[in]  subLevel Sub-level index <= MMU_FMT_MAX_SUB_LEVELS.
481  *
482  * @returns Sub-level PDE format or NULL if not a page directory level.
483  */
484 const GMMU_FMT_PDE* gmmuFmtGetPde(
485             const GMMU_FMT      *pFmt,
486             const MMU_FMT_LEVEL *pLevel,
487             const NvU32          subLevel);
488 
489 /*!
490  * Page table entry (PTE) format.
491  */
492 struct GMMU_FMT_PTE
493 {
494     /*!
495      * Version information is needed to interpret fields differently.
496      * Should be always the same as version in GMMU_FMT above.
497      */
498     NvU32 version;
499 
500     /*!
501      * Field that determines if the PTE is valid.
502      */
503     NV_FIELD_BOOL fldValid;
504 
505     /*!
506      * Aperture field indicating which the physical page resides.
507      */
508     GMMU_FIELD_APERTURE fldAperture;
509 
510     /*!
511      * Physical address field when aperture is system memory.
512      */
513     GMMU_FIELD_ADDRESS fldAddrSysmem;
514 
515     /*!
516      * Physical address field when aperture is video memory.
517      */
518     GMMU_FIELD_ADDRESS fldAddrVidmem;
519 
520     /*!
521      * Physical address field when aperture is peer memory.
522      */
523     GMMU_FIELD_ADDRESS fldAddrPeer;
524 
525     /*!
526      * Peer index field when aperture is peer memory.
527      */
528     NV_FIELD_DESC32 fldPeerIndex;
529 
530     /*!
531      * Indicates GPU reads/writes memory on every access to the page.
532      *
533      * @note This is not the same as caching, and is ignored for some
534      *       apertures on some chips.
535      *       TODO: Wiki link to explain arch differences.
536      */
537     NV_FIELD_BOOL fldVolatile;
538 
539     /*!
540      * Indicates to generate a read-only (RO) fault on writes.
541      *
542      * @note This does not affect L1 cache access if
543      *       fldWriteDisable is supported.
544      */
545     NV_FIELD_BOOL fldReadOnly;
546 
547     /*!
548      * Indicates to generate a write-only (WO) fault on L1 reads.
549      * @note Only supported on some GPU architectures.
550      */
551     NV_FIELD_BOOL fldReadDisable;
552 
553     /*!
554      * Indicates to generate a read-only (WO) fault on L1 writes.
555      * @note Only supported on some GPU architectures.
556      */
557     NV_FIELD_BOOL fldWriteDisable;
558 
559     /*!
560      * Indicates to fault on non-priviledged access.
561      */
562     NV_FIELD_BOOL fldPrivilege;
563 
564     /*!
565      * See HW manuals.
566      */
567     NV_FIELD_BOOL fldEncrypted;
568 
569     /*!
570      * Indicates to lock the PTE in the GPU TLBs, giving precedence over
571      * unlocked-PTEs.
572      * TLB invalidate will still evict the PTE.
573      */
574     NV_FIELD_BOOL fldLocked;
575 
576     /*!
577      * TODO: TBD
578      */
579     NV_FIELD_BOOL fldAtomicDisable;
580 
581     /*!
582      * Kind (storage format) field.
583      */
584     NV_FIELD_DESC32 fldKind;
585 
586     /*!
587      * Compression tag field.
588      */
589     NV_FIELD_DESC32 fldCompTagLine;
590 
591     /*!
592      * Compression tag sub-index field.
593      */
594     NV_FIELD_DESC32 fldCompTagSubIndex;
595 
596     /*!
597      * PTE_PCF field for V3 format.
598      */
599     NV_FIELD_DESC32 fldPtePcf;
600 };
601 
602 /*!
603  * Determine if an entry is a PTE or PDE based either on its static format or
604  * dynamic value.
605  *
606  * @param[in]  pFmt   MMU format.
607  * @param[in]  pLevel Level format.
608  * @param[in]  pEntry Entry value of size pLevel->entrySize.
609  *
610  * @returns true if the entry is a PTE, false if it is a PDE.
611  */
612 NvBool gmmuFmtEntryIsPte(
613             const GMMU_FMT      *pFmt,
614             const MMU_FMT_LEVEL *pLevel,
615             const NvU8          *pEntry);
616 
617 /*!
618  * Get the PTE physical address field format for a given aperture.
619  */
620 const GMMU_FIELD_ADDRESS *gmmuFmtPtePhysAddrFld(
621                         const GMMU_FMT_PTE *pPte,
622                         const GMMU_APERTURE aperture);
623 
624 /*!
625  * GPU compression attributes for a physical surface.
626  *
627  * This info will be returned by RM from HW resource alloc API.
628  */
629 struct GMMU_COMPR_INFO
630 {
631     /*!
632      * log2 of compression page size.
633      */
634     NvU32 compPageShift;
635 
636     /*!
637      * Compressed kind.
638      */
639     NvU32 compressedKind;
640 
641     /*!
642      * Index of the first compression page relative to the surface.
643      * e.g. if the entire surface is compressed this is 0.
644      */
645     NvU32 compPageIndexLo;
646 
647     /*!
648      * Index of the last compression page relative to the surface.
649      * e.g. (compPageIndexHi - compPageIndexLo + 1) is the number of comp
650      *      tag lines used for the surface.
651      * CompPageIndex is tracked in a (1 << compPageShift) granularity
652      */
653     NvU32 compPageIndexHi;
654 
655     /*!
656      * Starting comptag line to use at compPageIndexLo.
657      * Comptags are used contiguously up to the maximum
658      * compTagLineMin + (compPageIndexHi - compPageIndexLo).
659      */
660     NvU32 compTagLineMin;
661 
662     /*!
663      *  Granularity of comptagline assignment.
664      *  Used for Verif only, Deprecated from Turing
665      */
666     NvU32 compTagLineMultiplier;
667 };
668 
669 /*!
670  * Update a PTE value's compression fields based
671  * on the legacy compression attributes of the surface being mapped.
672  *
673  * @param[in]     pFmt        MMU format.
674  * @param[in]     pLevel      Level format.
675  * @param[in]     pCompr      Compression info of the physical surface.
676  * @param[in]     surfOffset  Offset in bytes into the physical surface.
677  * @param[in]     startPteIndex Starting pte index for comptagSubIndex calculation.
678  * @param[in]     numPages    Number of pages (PTEs) to update.
679  * @param[in,out] pEntries    Array of PTE values to update of length
680  *                            numPages * pLevel->entrySize.
681  */
682 void gmmuFmtInitPteCompTags(
683                 const GMMU_FMT        *pFmt,
684                 const MMU_FMT_LEVEL   *pLevel,
685                 const GMMU_COMPR_INFO *pCompr,
686                 const NvU64            surfOffset,
687                 const NvU32            startPteIndex,
688                 const NvU32            numPages,
689                 NvU8                  *pEntries);
690 
691 
692 #ifdef __cplusplus
693 }
694 #endif
695 
696 #endif
697