1 /*
2 * SPDX-FileCopyrightText: Copyright (c) 2016-2022 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 #include "core/core.h"
24 #include "resource_desc.h"
25
26 // Need the full header for the class allocation param structure.
27 #define SDK_ALL_CLASSES_INCLUDE_FULL_HEADER
28 #include "g_allclasses.h"
29
30 #include "resource_list_required_includes.h"
31
32 #include "rmapi/alloc_size.h"
33 #include "rmapi/resource_fwd_decls.h"
34 #include "resserv/rs_access_rights.h"
35
36 //
37 // Macros to transform list into static table
38 //
39
40 // NULL terminated list
41 #define RS_LIST(...) {__VA_ARGS__, 0}
42 #define RS_ROOT_OBJECT {0}
43 #define RS_ANY_PARENT {0}
44
45 // Populate parents
46 #define RS_ENTRY(cls, internalClass, bMultiInstance, parentList, allocParam, freePriority, flags, rightsRequired) \
47 NvU32 cls##ParentList[] = parentList;
48
49 #include "resource_list.h"
50
51 #undef RS_LIST
52 #undef RS_ROOT_OBJECT
53 #undef RS_ANY_PARENT
54
55
56 #define RS_ACCESS_NONE {-1}
57 #define RS_ACCESS_LIST(...) {__VA_ARGS__}
58
59 // Populate rights required
60 #define RS_ENTRY(cls, internalClass, bMultiInstance, parentList, allocParam, freePriority, flags, rightsRequired) \
61 static const RsAccessRight cls##_RightsRequiredArray[] = rightsRequired;
62
63 #include "resource_list.h"
64
65 #undef RS_ACCESS_NONE
66 #undef RS_ACCESS_LIST
67
68 // Populate forward declarations
69 #define RS_ENTRY(cls, internalClass, bMultiInstance, parentList, allocParam, freePriority, flags, rightsRequired) \
70 extern const struct NVOC_CLASS_DEF __nvoc_class_def_##internalClass; /* defn here to keep POPULATE_STRUCT happy if the class is disabled */
71
72 #include "resource_list.h"
73
74
75 #define RS_REQUIRED(allocParam) sizeof(allocParam), NV_TRUE
76 #define RS_OPTIONAL(allocParam) sizeof(allocParam), NV_FALSE
77 #define RS_NONE 0, NV_FALSE
78 #define RS_ENTRY(cls, internalClass, bMultiInstance, bAnyParent, allocParam, freePriority, flags, bRightsRequired) \
79 { \
80 cls, \
81 classId(internalClass), \
82 classInfo(internalClass), \
83 allocParam, \
84 bMultiInstance, \
85 bAnyParent, \
86 cls##ParentList, \
87 freePriority, \
88 flags, \
89 cls##_RightsRequiredArray, \
90 bRightsRequired ? NV_ARRAY_ELEMENTS(cls##_RightsRequiredArray) : 0, \
91 },
92
93 #define RS_LIST(...) NV_FALSE
94 #define RS_ROOT_OBJECT NV_FALSE
95 #define RS_ANY_PARENT NV_TRUE
96 #define RS_ACCESS_NONE NV_FALSE
97 #define RS_ACCESS_LIST(...) NV_TRUE
98 static RS_RESOURCE_DESC
99 g_RsResourceDescList[] =
100 {
101 #include "resource_list.h"
102 };
103 #undef RS_LIST
104 #undef RS_ROOT_OBJECT
105 #undef RS_ANY_PARENT
106 #undef RS_ACCESS_NONE
107 #undef RS_ACCESS_LIST
108 #undef RS_REQUIRED
109 #undef RS_OPTIONAL
110 #undef RS_NONE
111
112 #define NUM_ENTRIES_DESC_LIST NV_ARRAY_ELEMENTS(g_RsResourceDescList)
113
RsResInfoInitialize(void)114 void RsResInfoInitialize(void)
115 {
116 //
117 // Keep the array sorted by externalClassId, so we can binary search it
118 // Simple bubble-sort is fine here as the number of elements is below 300,
119 // and we only call this once on boot anyway.
120 //
121 NvU32 i, j;
122 for (i = 0; i < NUM_ENTRIES_DESC_LIST - 1; i++)
123 {
124 for (j = i + 1; j < NUM_ENTRIES_DESC_LIST; j++)
125 {
126 RS_RESOURCE_DESC *a = &g_RsResourceDescList[i];
127 RS_RESOURCE_DESC *b = &g_RsResourceDescList[j];
128
129 if (a->externalClassId > b->externalClassId)
130 {
131 RS_RESOURCE_DESC tmp;
132 portMemCopy(&tmp, sizeof(tmp), a, sizeof(*a));
133 portMemCopy(a, sizeof(*a), b, sizeof(*b));
134 portMemCopy(b, sizeof(*b), &tmp, sizeof(tmp));
135 }
136 }
137 }
138 }
139
140 RS_RESOURCE_DESC *
RsResInfoByExternalClassId(NvU32 externalClassId)141 RsResInfoByExternalClassId
142 (
143 NvU32 externalClassId
144 )
145 {
146 NvU32 low = 0;
147 NvU32 high = NUM_ENTRIES_DESC_LIST;
148
149 // Binary search the array; If not found, the break in the middle will be hit
150 while (1)
151 {
152 NvU32 mid = (low + high) / 2;
153
154 if (g_RsResourceDescList[mid].externalClassId == externalClassId)
155 return &g_RsResourceDescList[mid];
156
157 if (high == mid || low == mid)
158 break;
159
160 if (g_RsResourceDescList[mid].externalClassId > externalClassId)
161 high = mid;
162 else
163 low = mid;
164 }
165
166 return NULL;
167 }
168
RsResInfoGetInternalClassId(const RS_RESOURCE_DESC * pResDesc)169 NvU32 RsResInfoGetInternalClassId(const RS_RESOURCE_DESC *pResDesc)
170 {
171 return pResDesc ? pResDesc->internalClassId : 0;
172 }
173
RsResInfoGetResourceList(const RS_RESOURCE_DESC ** ppResourceList,NvU32 * numResources)174 void RsResInfoGetResourceList(const RS_RESOURCE_DESC **ppResourceList, NvU32 *numResources)
175 {
176 *ppResourceList = g_RsResourceDescList;
177 *numResources = NV_ARRAY_ELEMENTS(g_RsResourceDescList);
178 }
179
180 NV_STATUS
rmapiGetClassAllocParamSize(NvU32 * pAllocParamSizeBytes,NvP64 pUserParams,NvBool * pBAllowNull,NvU32 hClass)181 rmapiGetClassAllocParamSize
182 (
183 NvU32 *pAllocParamSizeBytes,
184 NvP64 pUserParams,
185 NvBool *pBAllowNull,
186 NvU32 hClass
187 )
188 {
189 RS_RESOURCE_DESC *pResDesc;
190
191 *pAllocParamSizeBytes = 0;
192 *pBAllowNull = NV_FALSE;
193
194 pResDesc = RsResInfoByExternalClassId(hClass);
195
196 if (!pResDesc)
197 return NV_ERR_INVALID_CLASS;
198
199 if (pResDesc->bParamRequired)
200 {
201 // params are required
202 *pAllocParamSizeBytes = pResDesc->allocParamSize;
203 }
204 else if (pResDesc->allocParamSize)
205 {
206 // params are *optional*
207 *pBAllowNull = NV_TRUE;
208 if (pUserParams != (NvP64) 0)
209 *pAllocParamSizeBytes = pResDesc->allocParamSize;
210 }
211 else
212 {
213 // no params
214 *pBAllowNull = NV_TRUE;
215 }
216
217 return NV_OK;
218 }
219