summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/rmq/rmq.c57
1 files changed, 46 insertions, 11 deletions
diff --git a/tools/rmq/rmq.c b/tools/rmq/rmq.c
index 97d1bed..189d647 100644
--- a/tools/rmq/rmq.c
+++ b/tools/rmq/rmq.c
@@ -15,11 +15,15 @@ typedef uint32_t NvHandle;
typedef uint32_t NvV32;
typedef uint64_t NvP64;
-#define NV_ESC_RM_ALLOC 0x2B
-#define NV_ESC_RM_CONTROL 0x2A
-#define NV01_ROOT 0x0
-#define NV01_DEVICE_0 0x80
-#define NV20_SUBDEVICE_0 0x2080
+/* NVIDIA ioctl encoding: _IOWR('F', nr, type) */
+#define NV_IOCTL_MAGIC 'F'
+#define NV_IOCTL_BASE 200
+#define NV_ESC_RM_ALLOC 0x2B
+#define NV_ESC_RM_CONTROL 0x2A
+
+#define NV01_ROOT 0x0
+#define NV01_DEVICE_0 0x80
+#define NV20_SUBDEVICE_0 0x2080
typedef struct {
NvHandle hRoot;
@@ -41,24 +45,54 @@ typedef struct {
NvV32 status;
} NVOS54_PARAMETERS;
+#define NV_IOCTL_RM_ALLOC _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_ALLOC, NVOS21_PARAMETERS)
+#define NV_IOCTL_RM_CONTROL _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_CONTROL, NVOS54_PARAMETERS)
+
static int fd;
+/* NVOS64: 48 bytes (0x30), used for device/subdevice allocs (with rights) */
+typedef struct {
+ NvHandle hRoot;
+ NvHandle hObjectParent;
+ NvHandle hObjectNew;
+ NvV32 hClass;
+ NvP64 pAllocParms __attribute__((aligned(8)));
+ NvP64 pRightsRequested __attribute__((aligned(8)));
+ NvU32 paramsSize;
+ NvU32 flags;
+ NvV32 status;
+} NVOS64_PARAMETERS;
+
+#define NV_IOCTL_RM_ALLOC64 _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_ALLOC, NVOS64_PARAMETERS)
+
static NvU32 rm_alloc(NvHandle hRoot, NvHandle hParent, NvU32 hClass, NvHandle *pOut)
{
NVOS21_PARAMETERS p = {0};
p.hRoot = hRoot; p.hObjectParent = hParent; p.hClass = hClass;
- if (ioctl(fd, NV_ESC_RM_ALLOC, &p) < 0) { perror("alloc ioctl"); return 1; }
+ if (ioctl(fd, NV_IOCTL_RM_ALLOC, &p) < 0) { perror("alloc ioctl"); return 1; }
if (p.status) { fprintf(stderr, "alloc class 0x%x failed: 0x%x\n", hClass, p.status); return p.status; }
*pOut = p.hObjectNew;
return 0;
}
+/* Device/subdevice allocs use NVOS64 (48 bytes) with rights */
+static NvU32 rm_alloc64(NvHandle hRoot, NvHandle hParent, NvU32 hClass, NvHandle *pOut)
+{
+ NVOS64_PARAMETERS p = {0};
+ p.hRoot = hRoot; p.hObjectParent = hParent; p.hClass = hClass;
+ p.flags = 1; /* FINN_SERIALIZED */
+ if (ioctl(fd, NV_IOCTL_RM_ALLOC64, &p) < 0) { perror("alloc64 ioctl"); return 1; }
+ if (p.status) { fprintf(stderr, "alloc64 class 0x%x failed: 0x%x\n", hClass, p.status); return p.status; }
+ *pOut = p.hObjectNew;
+ return 0;
+}
+
static NvU32 rm_control(NvHandle hClient, NvHandle hObject, NvU32 cmd, void *params, NvU32 size)
{
NVOS54_PARAMETERS p = {0};
p.hClient = hClient; p.hObject = hObject; p.cmd = cmd;
p.params = (NvP64)params; p.paramsSize = size;
- if (ioctl(fd, NV_ESC_RM_CONTROL, &p) < 0) { perror("control ioctl"); return 1; }
+ if (ioctl(fd, NV_IOCTL_RM_CONTROL, &p) < 0) { perror("control ioctl"); return 1; }
return p.status;
}
@@ -93,12 +127,13 @@ int main(int argc, char **argv)
NvHandle hClient = 0, hDevice = 0, hSubdevice = 0;
NvU32 st;
- fd = open("/dev/nvidia0", O_RDWR);
- if (fd < 0) { perror("open /dev/nvidia0"); return 1; }
+ /* RM_ALLOC creates clients on /dev/nvidiactl, not /dev/nvidia0 */
+ fd = open("/dev/nvidiactl", O_RDWR);
+ if (fd < 0) { perror("open /dev/nvidiactl"); return 1; }
if ((st = rm_alloc(0, 0, NV01_ROOT, &hClient))) return 1;
- if ((st = rm_alloc(hClient, hClient, NV01_DEVICE_0, &hDevice))) return 1;
- if ((st = rm_alloc(hClient, hDevice, NV20_SUBDEVICE_0, &hSubdevice))) return 1;
+ if ((st = rm_alloc64(hClient, hClient, NV01_DEVICE_0, &hDevice))) return 1;
+ if ((st = rm_alloc64(hClient, hDevice, NV20_SUBDEVICE_0, &hSubdevice))) return 1;
printf("hClient=0x%x hDevice=0x%x hSubdevice=0x%x\n", hClient, hDevice, hSubdevice);
/* FIFO_GET_DEVICE_INFO_TABLE (0x20801112) */