summaryrefslogtreecommitdiffstats
path: root/tools/rmtool/src/query.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 10:58:21 -0400
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-10-02 10:58:21 -0400
commitf909a5f822c5c4a4e9526b861d4171f8925f5113 (patch)
treeed362021c83569f49b48079a774f05775e84b0bd /tools/rmtool/src/query.c
parent09f241601423b1ae98e97846ee451768ff8a0a9e (diff)
downloadopen-iov-f909a5f822c5c4a4e9526b861d4171f8925f5113.tar.gz
open-iov-f909a5f822c5c4a4e9526b861d4171f8925f5113.zip
debug: green-eye wave 3 - RM harness, local simulator, device map, MCP plugin, value-validation demos, CI pipeline, toolchain docs; add host RM tools rmtool/rmtop
Diffstat (limited to 'tools/rmtool/src/query.c')
-rw-r--r--tools/rmtool/src/query.c256
1 files changed, 256 insertions, 0 deletions
diff --git a/tools/rmtool/src/query.c b/tools/rmtool/src/query.c
new file mode 100644
index 0000000..c9a7460
--- /dev/null
+++ b/tools/rmtool/src/query.c
@@ -0,0 +1,256 @@
+/* query.c - shared read-only RM queries used by rmtool and rmtop. */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "rmtool.h"
+
+int rm_ctx_open(struct rm_ctx *ctx)
+{
+ int rc;
+
+ if (ctx->have_rm)
+ return 0;
+ rc = rm_client_open(&ctx->rm, ctx->gpu_minor, ctx->dev_path);
+ if (rc != 0)
+ return rc;
+ ctx->have_rm = 1;
+ return 0;
+}
+
+NvU32 rm_query_name(struct rm_ctx *ctx, char *buf, size_t len)
+{
+ NV2080_CTRL_GPU_GET_NAME_STRING_PARAMS p;
+ NvU32 status;
+ int ioctl_ret;
+
+ memset(&p, 0, sizeof(p));
+ p.gpuNameStringFlags = 0;
+ status = rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_GPU_GET_NAME_STRING, &p,
+ sizeof(p), &ioctl_ret);
+ if (status != 0)
+ return status;
+ p.gpuNameString.ascii[sizeof(p.gpuNameString.ascii) - 1] = '\0';
+ snprintf(buf, len, "%s", p.gpuNameString.ascii);
+ return 0;
+}
+
+NvU32 rm_query_mc_arch(struct rm_ctx *ctx, NV2080_CTRL_MC_ARCH_INFO_PARAMS *p)
+{
+ int ioctl_ret;
+
+ memset(p, 0, sizeof(*p));
+ return rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_MC_GET_ARCH_INFO, p, sizeof(*p),
+ &ioctl_ret);
+}
+
+NvU32 rm_query_pci(struct rm_ctx *ctx, NV2080_CTRL_BUS_GET_PCI_INFO_PARAMS *p)
+{
+ int ioctl_ret;
+
+ memset(p, 0, sizeof(*p));
+ return rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_BUS_GET_PCI_INFO, p, sizeof(*p),
+ &ioctl_ret);
+}
+
+NvU32 rm_query_fb(struct rm_ctx *ctx, const NvU32 *indices, NvU32 *values,
+ NvU32 n)
+{
+ NV2080_CTRL_FB_GET_INFO_V2_PARAMS p;
+ NvU32 status;
+ NvU32 i;
+ int ioctl_ret;
+
+ if (n > NV2080_CTRL_FB_INFO_MAX_LIST_SIZE)
+ return (NvU32)-1;
+ memset(&p, 0, sizeof(p));
+ p.fbInfoListSize = n;
+ for (i = 0; i < n; i++) {
+ p.fbInfoList[i].index = indices[i];
+ values[i] = 0;
+ }
+ status = rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_FB_GET_INFO_V2, &p, sizeof(p),
+ &ioctl_ret);
+ if (status != 0)
+ return status;
+ for (i = 0; i < n; i++) {
+ NvU32 j;
+
+ for (j = 0; j < p.fbInfoListSize && j < n; j++) {
+ if (p.fbInfoList[j].index == indices[i]) {
+ values[i] = p.fbInfoList[j].data;
+ break;
+ }
+ }
+ }
+ return 0;
+}
+
+NvU32 rm_query_engines(struct rm_ctx *ctx,
+ NV2080_CTRL_GPU_GET_ENGINES_V2_PARAMS *p)
+{
+ int ioctl_ret;
+
+ memset(p, 0, sizeof(*p));
+ return rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_GPU_GET_ENGINES_V2, p, sizeof(*p),
+ &ioctl_ret);
+}
+
+NvU32 rm_query_fifo_table(struct rm_ctx *ctx,
+ NV2080_FIFO_DEVICE_ENTRY *entries,
+ NvU32 max_entries, NvU32 *n_entries)
+{
+ NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS t;
+ NvU32 base = 0;
+ NvU32 total = 0;
+
+ *n_entries = 0;
+ do {
+ NvU32 status;
+ NvU32 i;
+ int ioctl_ret;
+
+ memset(&t, 0, sizeof(t));
+ t.baseIndex = base;
+ status = rm_control(&ctx->rm, ctx->rm.hSubdevice,
+ NV2080_CTRL_CMD_FIFO_GET_DEVICE_INFO_TABLE,
+ &t, sizeof(t), &ioctl_ret);
+ if (status != 0)
+ return status;
+ for (i = 0; i < t.numEntries && total < max_entries; i++)
+ entries[total++] = t.entries[i];
+ base += t.numEntries;
+ if (!t.bMore || t.numEntries == 0)
+ break;
+ } while (1);
+ *n_entries = total;
+ return 0;
+}
+
+const char *rm_arch_str(NvU32 architecture)
+{
+ switch (architecture) {
+ case 0xE0000023U:
+ return "T23X";
+ case 0x00000160U:
+ return "TU100";
+ case 0x00000170U:
+ return "GA100";
+ case 0x00000180U:
+ return "GH100";
+ case 0x00000190U:
+ return "AD100";
+ case 0x000001A0U:
+ return "GB100";
+ case 0x000001B0U:
+ return "GB200";
+ default:
+ return "unknown";
+ }
+}
+
+const char *rm_engine_type_name(NvU32 engine_type)
+{
+ static const struct {
+ NvU32 type;
+ const char *name;
+ } table[] = {
+ { 0x01, "gr" }, { 0x09, "ce0" }, { 0x0a, "ce1" },
+ { 0x0b, "ce2" }, { 0x0c, "ce3" }, { 0x0d, "ce4" },
+ { 0x0e, "ce5" }, { 0x0f, "ce6" }, { 0x10, "ce7" },
+ { 0x11, "ce8" }, { 0x12, "ce9" }, { 0x34, "ce10" },
+ { 0x35, "ce11" }, { 0x36, "ce12" }, { 0x37, "ce13" },
+ { 0x38, "ce14" }, { 0x39, "ce15" },
+ { 0x13, "nvdec0" }, { 0x14, "nvdec1" }, { 0x15, "nvdec2" },
+ { 0x16, "nvdec3" }, { 0x17, "nvdec4" }, { 0x18, "nvdec5" },
+ { 0x19, "nvdec6" }, { 0x1a, "nvdec7" },
+ { 0x1b, "nvenc0" }, { 0x1c, "nvenc1" }, { 0x1d, "nvenc2" },
+ { 0x3f, "nvenc3" },
+ { 0x2b, "nvjpg0" }, { 0x2c, "nvjpg1" }, { 0x2d, "nvjpg2" },
+ { 0x2e, "nvjpg3" }, { 0x2f, "nvjpg4" }, { 0x30, "nvjpg5" },
+ { 0x31, "nvjpg6" }, { 0x32, "nvjpg7" },
+ { 0x33, "ofa0" }, { 0x3e, "ofa1" },
+ { 0x24, "vic" }, { 0x26, "sec2" }, { 0x22, "sw" },
+ { 0x27, "host" }, { 0x29, "pmu" }, { 0x2a, "fbflcn" },
+ { 0x1e, "vp" }, { 0x1f, "me" }, { 0x20, "ppp" },
+ { 0x21, "mpeg" }, { 0x23, "cipher" }, { 0x25, "mp" },
+ { 0x28, "dpu" },
+ };
+ unsigned int i;
+
+ for (i = 0; i < sizeof(table) / sizeof(table[0]); i++) {
+ if (table[i].type == engine_type)
+ return table[i].name;
+ }
+ return NULL;
+}
+
+const char *rm_engine_name(const NV2080_FIFO_DEVICE_ENTRY *entries,
+ NvU32 n_entries, NvU32 engine_type)
+{
+ static char fallback[24];
+ const char *name;
+ NvU32 i;
+
+ for (i = 0; i < n_entries; i++) {
+ if (entries[i].engineName[0] == '\0')
+ continue;
+ if (entries[i].engineData[0] == engine_type)
+ return entries[i].engineName;
+ }
+ name = rm_engine_type_name(engine_type);
+ if (name != NULL)
+ return name;
+ snprintf(fallback, sizeof(fallback), "engine[0x%x]", engine_type);
+ return fallback;
+}
+
+int rm_apply_common_opt(struct rm_ctx *ctx, int opt, const char *arg)
+{
+ if (opt == 'd') {
+ char *end;
+ long minor = strtol(arg, &end, 0);
+
+ if (arg[0] != '\0' && *end == '\0') {
+ ctx->gpu_minor = (int)minor;
+ return 1;
+ }
+ if (strchr(arg, ':') != NULL) {
+ struct rm_gpu_desc gpus[RM_MAX_GPUS];
+ int n = rm_scan_gpus(gpus, RM_MAX_GPUS);
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (strcmp(gpus[i].bdf, arg) == 0) {
+ ctx->gpu_minor = gpus[i].minor;
+ return 1;
+ }
+ }
+ fprintf(stderr, "rmtool: no GPU with bus id %s\n", arg);
+ return -1;
+ }
+ fprintf(stderr, "rmtool: bad GPU selector '%s'\n", arg);
+ return -1;
+ }
+ if (opt == 'f') {
+ enum rm_format fmt = rm_format_parse(arg);
+
+ if ((int)fmt < 0) {
+ fprintf(stderr, "rmtool: bad format '%s' "
+ "(table|json|csv)\n", arg);
+ return -1;
+ }
+ ctx->format = fmt;
+ return 1;
+ }
+ if (opt == 1000) {
+ ctx->dev_path = arg;
+ return 1;
+ }
+ return 0;
+}