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