/* SPDX-License-Identifier: BSD-3-Clause */ /* Copyright (c) 2026 Open-IOV contributors */ /* query.c - shared read-only RM queries used by rmtool and rmtop. */ #include #include #include #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; }