1 /*
2  * SPDX-FileCopyrightText: Copyright (c) 2021 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 
112     NvU32           clientHandle;    /* Provided by the host driver */
113     NvU32           numSubDevices;   /* Provided by the host driver */
114 
115     NvU32           numClasses;      /* Provided by the host driver */
116     const NvU32    *supportedClasses;/* Provided by the host driver */
117 
118     struct {
119         NvU32       handle;          /* Provided by the host driver */
120         NvU32       deviceHandle;    /* Provided by the host driver */
121         NvU32       gpuVASpaceObject;/* Provided by the host driver */
122         NvU32       gpuVASpaceCtxDma;/* Provided by the host driver */
123         NvU32       hUserMode;       /* VOLTA_USERMODE_A object */
124         void       *pUserMode;       /* VOLTA_USERMODE_A mapping */
125     } subDevice[NV_MAX_SUBDEVICES];
126 
127     NvU32           gpfifoClass;
128     size_t          userDSize;
129 
130     NVAModelConfig  amodelConfig;
131 
132     NvPushHal hal;
133     const struct _NvPushImports *pImports;
134 
135     /* Provided by the host driver */
136     NvPushConfidentialComputeMode confidentialComputeMode;
137 } NvPushDeviceRec, *NvPushDevicePtr;
138 
139 
140 typedef struct _NvPushChannelSegmentRec
141 {
142     NvU32               freeDwords;  // free space (in dwords)
143     NvU32               sizeInBytes; // Push buffer size (in bytes)
144     NvU32               putOffset;   // Offset of last kickoff
145     NvPushChannelUnion *base;        // Push buffer start pointer
146     NvPushChannelUnion *buffer;      // Push buffer current pointer
147     NvU64               gpuMapOffset;
148 } NvPushChannelSegmentRec, *NvPushChannelSegmentPtr;
149 
150 struct _NvPushChannelRec
151 {
152     NvBool          initialized              : 1;
153     NvBool          logNvDiss                : 1;
154     NvBool          noTimeout                : 1;
155     NvBool          ignoreChannelErrors      : 1;
156     NvBool          channelErrorOccurred     : 1;
157 
158     NvU32           channelHandle[NV_MAX_SUBDEVICES];
159     NvU32           pushbufferHandle;
160     NvU32           pushbufferVAHandle[NV_MAX_SUBDEVICES];
161     NvPushChannelSegmentRec main;
162 
163     void           *control[NV_MAX_SUBDEVICES];
164     NvU32           numGpFifoEntries;
165     NvU32          *gpfifo;  // GPFIFO entries
166     NvU32           gpPutOffset; // GPFIFO entries last kicked off offset
167     NvU32           currentSubDevMask;
168 
169     NvPushChannelSegmentRec progressTracker;
170     struct {
171         NvU32       handle[NV_MAX_SUBDEVICES];
172         void       *ptr[NV_MAX_SUBDEVICES];
173         NvU64       gpuVA;
174     } progressSemaphore;
175 
176     struct {
177         NvU32 hMemory;
178     } userD[NV_MAX_SUBDEVICES];
179 
180     struct {
181         NvU8            num;
182         NvU32           memoryHandle;
183         NvNotification *cpuAddress;
184         NvU64           gpuAddress;
185         NvU32           errorCtxDma;
186     } notifiers;
187 
188     NvPushDeviceRec *pDevice;
189 };
190 
191 /* Opaque type, only used by pointer within the push buffer utility library. */
192 typedef struct _NvPushImportEvent NvPushImportEvent;
193 
194 /* Table of function pointers to be provided by the nvidia-push host driver. */
195 typedef struct _NvPushImports {
196 
197     NvU32  (*rmApiControl)          (NvPushDevicePtr pDevice,
198                                      NvU32 hObject,
199                                      NvU32 cmd,
200                                      void *pParams,
201                                      NvU32 paramsSize);
202 
203     NvU32  (*rmApiAlloc)            (NvPushDevicePtr pDevice,
204                                      NvU32 hParent,
205                                      NvU32 hObject,
206                                      NvU32 hClass,
207                                      void *pAllocParams);
208 
209     NvU32  (*rmApiFree)             (NvPushDevicePtr pDevice,
210                                      NvU32 hParent,
211                                      NvU32 hObject);
212 
213     NvU32  (*rmApiMapMemoryDma)     (NvPushDevicePtr pDevice,
214                                      NvU32 hDevice,
215                                      NvU32 hDma,
216                                      NvU32 hMemory,
217                                      NvU64 offset,
218                                      NvU64 length,
219                                      NvU32 flags,
220                                      NvU64 *pDmaOffset);
221 
222     NvU32  (*rmApiUnmapMemoryDma)   (NvPushDevicePtr pDevice,
223                                      NvU32 hDevice,
224                                      NvU32 hDma,
225                                      NvU32 hMemory,
226                                      NvU32 flags,
227                                      NvU64 dmaOffset);
228 
229     NvU32  (*rmApiAllocMemory64)    (NvPushDevicePtr pDevice,
230                                      NvU32 hParent,
231                                      NvU32 hMemory,
232                                      NvU32 hClass,
233                                      NvU32 flags,
234                                      void **ppAddress,
235                                      NvU64 *pLimit);
236 
237     NvU32  (*rmApiVidHeapControl)   (NvPushDevicePtr pDevice,
238                                      void *pVidHeapControlParms);
239 
240     NvU32  (*rmApiMapMemory)        (NvPushDevicePtr pDevice,
241                                      NvU32 hDevice,
242                                      NvU32 hMemory,
243                                      NvU64 offset,
244                                      NvU64 length,
245                                      void **ppLinearAddress,
246                                      NvU32 flags);
247 
248     NvU32  (*rmApiUnmapMemory)      (NvPushDevicePtr pDevice,
249                                      NvU32 hDevice,
250                                      NvU32 hMemory,
251                                      void *pLinearAddress,
252                                      NvU32 flags);
253 
254     NvU64  (*getMilliSeconds)       (NvPushDevicePtr pDevice);
255 
256     void   (*yield)                 (NvPushDevicePtr pDevice);
257 
258     NvBool (*waitForEvent)          (NvPushDevicePtr pDevice,
259                                      NvPushImportEvent *pEvent,
260                                      NvU64 timeout);
261 
262     void   (*emptyEventFifo)        (NvPushDevicePtr pDevice,
263                                      NvPushImportEvent *pEvent);
264 
265     void   (*channelErrorOccurred)  (NvPushChannelPtr pChannel, NvU32 channelErrCode);
266 
267     void   (*pushbufferWrapped)     (NvPushChannelPtr pChannel);
268 
269     void   (*logError)              (NvPushDevicePtr pDevice,
270                                      NV_PUSH_PRINTF_FORMAT_ARGUMENT const char *fmt, ...)
271         NV_PUSH_PRINTF_ATTRIBUTES(2,3);
272 
273     /*
274      * The logNvDiss() import, in DEBUG builds, logs strings to be
275      * parsed by nvdiss.  Note that multiple nvPushImportLogNvDiss()
276      * calls may be used to build one line of output (so, respect the
277      * newlines provided in the strings).
278      */
279 #if defined(DEBUG)
280     void   (*logNvDiss)              (NvPushChannelPtr pChannel,
281                                       NV_PUSH_PRINTF_FORMAT_ARGUMENT const char *fmt, ...)
282         NV_PUSH_PRINTF_ATTRIBUTES(2,3);
283 #endif
284 
285 } NvPushImports;
286 
287 
288 void __nvPushMakeRoom(NvPushChannelPtr, NvU32 count);
289 
290 #ifdef __cplusplus
291 };
292 #endif
293 
294 #endif /* __NVIDIA_PUSH_TYPES_H__ */
295