1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2014 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
24 #include "mmu/mmu_fmt.h"
25
26 NvU64
mmuFmtAllPageSizes(const MMU_FMT_LEVEL * pLevel)27 mmuFmtAllPageSizes(const MMU_FMT_LEVEL *pLevel)
28 {
29 NvU32 i;
30 NvU64 mask = 0;
31 if (pLevel->bPageTable)
32 {
33 mask |= mmuFmtLevelPageSize(pLevel);
34 }
35 for (i = 0; i < pLevel->numSubLevels; ++i)
36 {
37 mask |= mmuFmtAllPageSizes(pLevel->subLevels + i);
38 }
39 return mask;
40 }
41
42 NvU64
mmuFmtAllLevelCoverages(const MMU_FMT_LEVEL * pLevel)43 mmuFmtAllLevelCoverages(const MMU_FMT_LEVEL *pLevel)
44 {
45 NvU32 i;
46 NvU64 mask = mmuFmtLevelPageSize(pLevel);
47 for (i = 0; i < pLevel->numSubLevels; ++i)
48 {
49 mask |= mmuFmtAllLevelCoverages(pLevel->subLevels + i);
50 }
51 return mask;
52 }
53
54 const MMU_FMT_LEVEL *
mmuFmtFindLevelWithPageShift(const MMU_FMT_LEVEL * pLevel,const NvU64 pageShift)55 mmuFmtFindLevelWithPageShift
56 (
57 const MMU_FMT_LEVEL *pLevel,
58 const NvU64 pageShift
59 )
60 {
61 NvU32 i;
62 if (pLevel->virtAddrBitLo == pageShift)
63 {
64 return pLevel;
65 }
66 for (i = 0; i < pLevel->numSubLevels; ++i)
67 {
68 const MMU_FMT_LEVEL *pRes =
69 mmuFmtFindLevelWithPageShift(pLevel->subLevels + i, pageShift);
70 if (NULL != pRes)
71 {
72 return pRes;
73 }
74 }
75 return NULL;
76 }
77
78 const MMU_FMT_LEVEL *
mmuFmtFindLevelParent(const MMU_FMT_LEVEL * pRoot,const MMU_FMT_LEVEL * pLevel,NvU32 * pSubLevel)79 mmuFmtFindLevelParent
80 (
81 const MMU_FMT_LEVEL *pRoot,
82 const MMU_FMT_LEVEL *pLevel,
83 NvU32 *pSubLevel
84 )
85 {
86 NvU32 i;
87 for (i = 0; i < pRoot->numSubLevels; ++i)
88 {
89 const MMU_FMT_LEVEL *pRes;
90 if ((pRoot->subLevels + i) == pLevel)
91 {
92 if (NULL != pSubLevel)
93 {
94 *pSubLevel = i;
95 }
96 pRes = pRoot;
97 }
98 else
99 {
100 pRes = mmuFmtFindLevelParent(pRoot->subLevels + i, pLevel, pSubLevel);
101 }
102 if (NULL != pRes)
103 {
104 return pRes;
105 }
106 }
107 return NULL;
108 }
109
110 const MMU_FMT_LEVEL *
mmuFmtGetNextLevel(const MMU_FMT_LEVEL * pLevelFmt,const MMU_FMT_LEVEL * pTargetFmt)111 mmuFmtGetNextLevel
112 (
113 const MMU_FMT_LEVEL *pLevelFmt,
114 const MMU_FMT_LEVEL *pTargetFmt
115 )
116 {
117 if (pLevelFmt != pTargetFmt)
118 {
119 NvU32 subLevel = 0;
120 if (1 == pLevelFmt->numSubLevels)
121 {
122 return pLevelFmt->subLevels;
123 }
124 for (subLevel = 0; subLevel < pLevelFmt->numSubLevels; ++subLevel)
125 {
126 const MMU_FMT_LEVEL *pSubLevelFmt = pLevelFmt->subLevels + subLevel;
127 if (pSubLevelFmt == pTargetFmt)
128 {
129 return pSubLevelFmt;
130 }
131 }
132 }
133 return NULL;
134 }
135
136 const char*
mmuFmtConvertLevelIdToSuffix(const MMU_FMT_LEVEL * pLevelFmt)137 mmuFmtConvertLevelIdToSuffix
138 (
139 const MMU_FMT_LEVEL *pLevelFmt
140 )
141 {
142 switch (pLevelFmt->pageLevelIdTag)
143 {
144 case MMU_FMT_PT_SURF_ID_PD0:
145 return "_pd0";
146 case MMU_FMT_PT_SURF_ID_PD1:
147 return "_pd1";
148 case MMU_FMT_PT_SURF_ID_PD2:
149 return "_pd2";
150 case MMU_FMT_PT_SURF_ID_PD3:
151 return "_pd3";
152 case MMU_FMT_PT_SURF_ID_PD4:
153 return "_pd4";
154 case MMU_FMT_PT_SURF_ID_PT_4K:
155 return "_pt_4k";
156 case MMU_FMT_PT_SURF_ID_PT_BIG:
157 return "_pt_big";
158 default:
159 return NULL;
160 }
161 }
162
163