1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021-2024 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 /*
25  * This file contains core definitions (structures and enums) for use in the
26  * rest of the nvidia-push code.
27  */
28 
29 #ifndef __NVIDIA_PUSH_TYPES_H__
30 #define __NVIDIA_PUSH_TYPES_H__
31 
32 #include <stddef.h>          /* size_t */
33 
34 
35 
36 #include "nvtypes.h"
37 #include "nvlimits.h"
38 #include "nvmisc.h"
39 #include "nvgputypes.h"      /* NvNotificationRec */
40 #include "nv_common_utils.h" /* TRUE/FALSE */
41 #include "nvctassert.h"
42 #include "nv_assert.h"       /* nvAssert() */
43 #include "nv_amodel_enum.h"  /* NVAModelConfig */
44 #include "nvos.h"            /* NV_CHANNELGPFIFO_NOTIFICATION_* */
45 
46 #ifdef __cplusplus
47 extern "C" {
48 #endif
49 
50 #define NV_PUSH_NOTIFIER_SHORT_TIMEOUT 3000 /* in milliseconds (ie:  3 seconds) */
51 #define NV_PUSH_NOTIFIER_LONG_TIMEOUT 10000 /* in milliseconds (ie: 10 seconds) */
52 
53 # define NV_PUSH_PRINTF_FORMAT_ARGUMENT
54 # define NV_PUSH_PRINTF_ATTRIBUTES(_fmt,_var) \
55     __attribute__((format (printf, _fmt, _var)))
56 
57 
58 #if defined(NV_PUSH_IN_KERNEL)
59 #  define NV_PUSH_ALLOW_FLOAT 0
60 #else
61 #  define NV_PUSH_ALLOW_FLOAT 1
62 #endif
63 
64 typedef union _NvPushChannelUnion
65 {
66     NvU32 u;
67 #if NV_PUSH_ALLOW_FLOAT
68     float f;
69 #endif
70 } NvPushChannelUnion;
71 
72 typedef enum _NvPushConfidentialComputeMode {
73     /* Confidential computing is not in use. */
74     NV_PUSH_CONFIDENTIAL_COMPUTE_MODE_NONE,
75 
76     /*
77      * The confidential compute mode of operation is Hopper Confidential
78      * Compute (HCC).
79      */
80     NV_PUSH_CONFIDENTIAL_COMPUTE_MODE_HCC,
81 } NvPushConfidentialComputeMode;
82 
83 typedef struct _NvPushChannelRec NvPushChannelRec;
84 typedef struct _NvPushChannelRec *NvPushChannelPtr;
85 
86 typedef struct _nv_push_hal {
87     void (*kickoff)(struct _NvPushChannelRec*, NvU32 oldGpPut, NvU32 newGpPut);
88     void (*releaseTimelineSemaphore)(NvPushChannelPtr, void *cpuAddress, NvU64 gpuAddress, NvU64 val);
89     void (*acquireTimelineSemaphore)(NvPushChannelPtr, NvU64 gpuAddress, NvU64 val);
90     struct {
91         /* Requires USERD memory to be specified at channel allocation */
92         NvU32 clientAllocatesUserD                      :1;
93 
94         /* On Tegra, we currently need to allocate double the requested GPFIFO
95          * entries */
96         NvU32 allocateDoubleSizeGpFifo                  :1;
97 
98         /* Use Volta+ semaphore methods */
99         NvU32 voltaSemMethods                           :1;
100 
101         NvU32 extendedBase                              :1;
102     } caps;
103 } NvPushHal;
104 
105 typedef struct _NvPushDeviceRec {
106 
107     void           *hostDevice;     /* Provided by the host driver */
108 
109     NvBool          hostLBoverflowBug1667921 : 1;
110     NvBool          clientSli : 1;   /* Provided by the host driver */
111     NvBool          hasFb : 1;       /* Computed from supportedClasses[] */
112 
113     NvU32           clientHandle;    /* Provided by the host driver */
114     NvU32           numSubDevices;   /* Provided by the host driver */
115 
116     NvU32           numClasses;      /* Provided by the host driver */
117     const NvU32    *supportedClasses;/* Provided by the host driver */
118 
119     struct {
120         NvU32       handle;          /* Provided by the host driver */
121         NvU32       deviceHandle;    /* Provided by the host driver */
122         NvU32       gpuVASpaceObject;/* Provided by the host driver */
123         NvU32       gpuVASpaceCtxDma;/* Provided by the host driver */
124         NvU32       hUserMode;       /* VOLTA_USERMODE_A object */
125         void       *pUserMode;       /* VOLTA_USERMODE_A mapping */
126     } subDevice[NV_MAX_SUBDEVICES];
127 
128     NvU32           gpfifoClass;
129     size_t          userDSize;
130 
131     NVAModelConfig  amodelConfig;
132 
133     NvPushHal hal;
134     const struct _NvPushImports *pImports;
135 
136     /* Provided by the host driver */
137     NvPushConfidentialComputeMode confidentialComputeMode;
138 } NvPushDeviceRec, *NvPushDevicePtr;
139 
140 
141 typedef struct _NvPushChannelSegmentRec
142 {
143     NvU32               freeDwords;  // free space (in dwords)
144     NvU32               sizeInBytes; // Push buffer size (in bytes)
145     NvU32               putOffset;   // Offset of last kickoff
146     NvPushChannelUnion *base;        // Push buffer start pointer
147     NvPushChannelUnion *buffer;      // Push buffer current pointer
148     NvU64               gpuMapOffset;
149 } NvPushChannelSegmentRec, *NvPushChannelSegmentPtr;
150 
151 struct _NvPushChannelRec
152 {
153     NvBool          initialized              : 1;
154     NvBool          logNvDiss                : 1;
155     NvBool          noTimeout                : 1;
156     NvBool          ignoreChannelErrors      : 1;
157     NvBool          channelErrorOccurred     : 1;
158 
159     NvU32           channelHandle[NV_MAX_SUBDEVICES];
160     NvU32           pushbufferHandle;
161     NvU32           pushbufferVAHandle[NV_MAX_SUBDEVICES];
162     NvPushChannelSegmentRec main;
163 
164     void           *control[NV_MAX_SUBDEVICES];
165     NvU32           numGpFifoEntries;
166     NvU32          *gpfifo;  // GPFIFO entries
167     NvU32           gpPutOffset; // GPFIFO entries last kicked off offset
168     NvU32           currentSubDevMask;
169 
170     NvPushChannelSegmentRec progressTracker;
171     struct {
172         NvU32       handle[NV_MAX_SUBDEVICES];
173         void       *ptr[NV_MAX_SUBDEVICES];
174         NvU64       gpuVA;
175     } progressSemaphore;
176 
177     struct {
178         NvU32 hMemory;
179     } userD[NV_MAX_SUBDEVICES];
180 
181     struct {
182         NvU8            num;
183         NvU32           memoryHandle;
184         NvNotification *cpuAddress;
185         NvU64           gpuAddress;
186         NvU32           errorCtxDma;
187     } notifiers;
188 
189     NvPushDeviceRec *pDevice;
190 };
191 
192 /* Opaque type, only used by pointer within the push buffer utility library. */
193 typedef struct _NvPushImportEvent NvPushImportEvent;
194 
195 /* Table of function pointers to be provided by the nvidia-push host driver. */
196 typedef struct _NvPushImports {
197 
198     NvU32  (*rmApiControl)          (NvPushDevicePtr pDevice,
199                                      NvU32 hObject,
200                                      NvU32 cmd,
201                                      void *pParams,
202                                      NvU32 paramsSize);
203 
204     NvU32  (*rmApiAlloc)            (NvPushDevicePtr pDevice,
205                                      NvU32 hParent,
206                                      NvU32 hObject,
207                                      NvU32 hClass,
208                                      void *pAllocParams);
209 
210     NvU32  (*rmApiFree)             (NvPushDevicePtr pDevice,
211                                      NvU32 hParent,
212                                      NvU32 hObject);
213 
214     NvU32  (*rmApiMapMemoryDma)     (NvPushDevicePtr pDevice,
215                                      NvU32 hDevice,
216                                      NvU32 hDma,
217                                      NvU32 hMemory,
218                                      NvU64 offset,
219                                      NvU64 length,
220                                      NvU32 flags,
221                                      NvU64 *pDmaOffset);
222 
223     NvU32  (*rmApiUnmapMemoryDma)   (NvPushDevicePtr pDevice,
224                                      NvU32 hDevice,
225                                      NvU32 hDma,
226                                      NvU32 hMemory,
227                                      NvU32 flags,
228                                      NvU64 dmaOffset);
229 
230     NvU32  (*rmApiAllocMemory64)    (NvPushDevicePtr pDevice,
231                                      NvU32 hParent,
232                                      NvU32 hMemory,
233                                      NvU32 hClass,
234                                      NvU32 flags,
235                                      void **ppAddress,
236                                      NvU64 *pLimit);
237 
238     NvU32  (*rmApiVidHeapControl)   (NvPushDevicePtr pDevice,
239                                      void *pVidHeapControlParms);
240 
241     NvU32  (*rmApiMapMemory)        (NvPushDevicePtr pDevice,
242                                      NvU32 hDevice,
243                                      NvU32 hMemory,
244                                      NvU64 offset,
245                                      NvU64 length,
246                                      void **ppLinearAddress,
247                                      NvU32 flags);
248 
249     NvU32  (*rmApiUnmapMemory)      (NvPushDevicePtr pDevice,
250                                      NvU32 hDevice,
251                                      NvU32 hMemory,
252                                      void *pLinearAddress,
253                                      NvU32 flags);
254 
255     NvU64  (*getMilliSeconds)       (NvPushDevicePtr pDevice);
256 
257     void   (*yield)                 (NvPushDevicePtr pDevice);
258 
259     NvBool (*waitForEvent)          (NvPushDevicePtr pDevice,
260                                      NvPushImportEvent *pEvent,
261                                      NvU64 timeout);
262 
263     void   (*emptyEventFifo)        (NvPushDevicePtr pDevice,
264                                      NvPushImportEvent *pEvent);
265 
266     void   (*channelErrorOccurred)  (NvPushChannelPtr pChannel, NvU32 channelErrCode);
267 
268     void   (*pushbufferWrapped)     (NvPushChannelPtr pChannel);
269 
270     void   (*logError)              (NvPushDevicePtr pDevice,
271                                      NV_PUSH_PRINTF_FORMAT_ARGUMENT const char *fmt, ...)
272         NV_PUSH_PRINTF_ATTRIBUTES(2,3);
273 
274     /*
275      * The logNvDiss() import, in DEBUG builds, logs strings to be
276      * parsed by nvdiss.  Note that multiple nvPushImportLogNvDiss()
277      * calls may be used to build one line of output (so, respect the
278      * newlines provided in the strings).
279      */
280 #if defined(DEBUG)
281     void   (*logNvDiss)              (NvPushChannelPtr pChannel,
282                                       NV_PUSH_PRINTF_FORMAT_ARGUMENT const char *fmt, ...)
283         NV_PUSH_PRINTF_ATTRIBUTES(2,3);
284 #endif
285 
286 } NvPushImports;
287 
288 
289 void __nvPushMakeRoom(NvPushChannelPtr, NvU32 count);
290 
291 #ifdef __cplusplus
292 };
293 #endif
294 
295 #endif /* __NVIDIA_PUSH_TYPES_H__ */
296