From f909a5f822c5c4a4e9526b861d4171f8925f5113 Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Fri, 2 Oct 2026 10:58:21 -0400 Subject: 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 --- tools/rmtool/include/rm_api.h | 297 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) create mode 100644 tools/rmtool/include/rm_api.h (limited to 'tools/rmtool/include/rm_api.h') diff --git a/tools/rmtool/include/rm_api.h b/tools/rmtool/include/rm_api.h new file mode 100644 index 0000000..5d7f8cf --- /dev/null +++ b/tools/rmtool/include/rm_api.h @@ -0,0 +1,297 @@ +/* rm_api.h - minimal self-contained NVIDIA RM userspace client. + * + * ABI and control IDs mirror the NV570 SDK (nvos.h, ctrl2080*.h) but the + * definitions live here so the tools build with no external SDK dependency. + * This is the shared layer used by rmtool and rmtop; it is read-only by + * design: it only allocates an RM client/device/subdevice and issues + * read-only NV2080/NV0080 control queries. + */ +#ifndef RM_API_H +#define RM_API_H + +#include + +typedef uint8_t NvU8; +typedef uint16_t NvU16; +typedef uint32_t NvU32; +typedef uint64_t NvU64; +typedef uint32_t NvHandle; +typedef uint64_t NvP64; +typedef uint32_t NvV32; + +/* NVIDIA escape 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 NV_ESC_CHECK_VERSION_STR (NV_IOCTL_BASE + 10) +#define NV_ESC_WAIT_OPEN_COMPLETE (NV_IOCTL_BASE + 18) + +/* RM classes used by the client ladder */ +#define NV01_ROOT 0x00000000U +#define NV01_ROOT_CLIENT 0x00000041U +#define NV01_DEVICE_0 0x00000080U +#define NV20_SUBDEVICE_0 0x00002080U + +/* NVOS21/NVOS64 match the running driver ABI (NV570 kernel nvos.h): both + * carry paramsSize. The userspace SDK snapshot in-tree has an older layout; + * using it results in the kernel rejecting the ioctl with EINVAL. + */ +typedef struct { + NvHandle hRoot; + NvHandle hObjectParent; + NvHandle hObjectNew; + NvV32 hClass; + NvP64 pAllocParms __attribute__((aligned(8))); + NvU32 paramsSize; + NvV32 status; +} NVOS21_PARAMETERS; + +#define NVOS64_FLAGS_NONE 0x00000000U +#define NVOS64_FLAGS_FINN_SERIALIZED 0x00000001U + +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; + +/* NVOS54 (NV04_CONTROL), standard nvos.h layout: sizeof = 32 */ +typedef struct { + NvHandle hClient; + NvHandle hObject; + NvV32 cmd; + NvU32 flags; + NvP64 params __attribute__((aligned(8))); + NvU32 paramsSize; + NvV32 status; +} NVOS54_PARAMETERS; + +#define NV_RM_API_VERSION_STRING_LENGTH 64 +#define NV_RM_API_VERSION_CMD_QUERY '2' +#define NV_RM_API_VERSION_REPLY_RECOGNIZED 1U + +typedef struct { + NvU32 cmd; + NvU32 reply; + char versionString[NV_RM_API_VERSION_STRING_LENGTH]; +} nv_ioctl_rm_api_version_t; + +typedef struct { + int rc; + NvU32 adapterStatus; +} nv_ioctl_wait_open_complete_t; + +typedef struct { + NvU32 deviceId; + NvHandle hClientShare; + NvHandle hTargetClient; + NvHandle hTargetDevice; + NvV32 flags; + NvU64 vaSpaceSize __attribute__((aligned(8))); + NvU64 vaStartInternal __attribute__((aligned(8))); + NvU64 vaLimitInternal __attribute__((aligned(8))); + NvV32 vaMode; +} NV0080_ALLOC_PARAMETERS; + +typedef struct { + NvU32 subDeviceId; +} NV2080_ALLOC_PARAMETERS; + +#define NV_IOCTL_RM_ALLOC21 \ + _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_ALLOC, NVOS21_PARAMETERS) +#define NV_IOCTL_RM_ALLOC64 \ + _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_ALLOC, NVOS64_PARAMETERS) +#define NV_IOCTL_RM_CONTROL \ + _IOWR(NV_IOCTL_MAGIC, NV_ESC_RM_CONTROL, NVOS54_PARAMETERS) +#define NV_IOCTL_CHECK_VERSION \ + _IOWR(NV_IOCTL_MAGIC, NV_ESC_CHECK_VERSION_STR, \ + nv_ioctl_rm_api_version_t) +#define NV_IOCTL_WAIT_OPEN_COMPLETE \ + _IOWR(NV_IOCTL_MAGIC, NV_ESC_WAIT_OPEN_COMPLETE, \ + nv_ioctl_wait_open_complete_t) + +/* ------------------------------------------------------------------ */ +/* Read-only NV2080/NV0080 controls used by the tools. */ +/* ------------------------------------------------------------------ */ + +/* NV2080_CTRL_CMD_GPU_GET_INFO_V2 (subdevice, no embedded pointers) */ +#define NV2080_CTRL_CMD_GPU_GET_INFO_V2 0x20800102U +#define NV2080_CTRL_CMD_GPU_GET_NAME_STRING 0x20800110U +#define NV2080_CTRL_CMD_GPU_QUERY_MODE 0x20800128U +#define NV2080_CTRL_CMD_GPU_GET_ID 0x20800142U +#define NV2080_CTRL_CMD_GPU_GET_ENGINES_V2 0x20800170U +#define NV2080_CTRL_CMD_MC_GET_ARCH_INFO 0x20801701U +#define NV2080_CTRL_CMD_FB_GET_INFO_V2 0x20801303U +#define NV2080_CTRL_CMD_BUS_GET_PCI_INFO 0x20801801U +#define NV2080_CTRL_CMD_TIMER_GET_TIME 0x20800403U +#define NV2080_CTRL_CMD_FIFO_GET_DEVICE_INFO_TABLE 0x20801112U +#define NV0080_CTRL_CMD_GPU_GET_CLASSLIST_V2 0x00000292U + +#define NV2080_CTRL_GPU_INFO_MAX_LIST_SIZE 0x41U +#define NV2080_CTRL_GPU_INFO_INDEX_SYSMEM_ACCESS 0x1fU +#define NV2080_CTRL_GPU_INFO_INDEX_GPU_SM_VERSION 0x2cU +#define NV2080_CTRL_GPU_INFO_INDEX_GPU_FLA_CAPABILITY 0x2dU +#define NV2080_CTRL_GPU_INFO_INDEX_4K_PAGE_ISOLATION_REQUIRED 0x33U +#define NV2080_CTRL_GPU_INFO_INDEX_DISPLAY_ENABLED 0x34U +#define NV2080_CTRL_GPU_INFO_INDEX_GPU_PROFILING_CAPABILITY 0x36U +#define NV2080_CTRL_GPU_INFO_INDEX_GPU_DEBUGGING_CAPABILITY 0x37U +#define NV2080_CTRL_GPU_INFO_INDEX_CMP_SKU 0x3cU +#define NV2080_CTRL_GPU_INFO_INDEX_DMABUF_CAPABILITY 0x3dU + +typedef struct { + NvU32 index; + NvU32 data; +} NV2080_CTRL_GPU_INFO; + +typedef struct { + NvU32 gpuInfoListSize; + NV2080_CTRL_GPU_INFO gpuInfoList[NV2080_CTRL_GPU_INFO_MAX_LIST_SIZE]; +} NV2080_CTRL_GPU_GET_INFO_V2_PARAMS; + +#define NV2080_GPU_MAX_NAME_STRING_LENGTH 0x40U + +typedef struct { + NvU32 gpuNameStringFlags; + union { + NvU8 ascii[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + NvU16 unicode[NV2080_GPU_MAX_NAME_STRING_LENGTH]; + } gpuNameString; +} NV2080_CTRL_GPU_GET_NAME_STRING_PARAMS; + +typedef struct { + NvU32 gpuId; +} NV2080_CTRL_GPU_GET_ID_PARAMS; + +typedef struct { + NvU32 mode; +} NV2080_CTRL_GPU_QUERY_MODE_PARAMS; + +#define NV2080_GPU_MAX_ENGINES_LIST_SIZE 0x54U + +typedef struct { + NvU32 engineCount; + NvU32 engineList[NV2080_GPU_MAX_ENGINES_LIST_SIZE]; +} NV2080_CTRL_GPU_GET_ENGINES_V2_PARAMS; + +typedef struct { + NvU32 architecture; + NvU32 implementation; + NvU32 revision; + NvU8 subRevision; +} NV2080_CTRL_MC_ARCH_INFO_PARAMS; + +#define NV2080_CTRL_FB_INFO_MAX_LIST_SIZE 0x39U +#define NV2080_CTRL_FB_INFO_INDEX_TOTAL_RAM_SIZE 0x08U +#define NV2080_CTRL_FB_INFO_INDEX_HEAP_SIZE 0x09U +#define NV2080_CTRL_FB_INFO_INDEX_LARGEST_FREE_REGION_SIZE_KB 0x12U +#define NV2080_CTRL_FB_INFO_INDEX_HEAP_FREE 0x16U +#define NV2080_CTRL_FB_INFO_INDEX_BAR1_SIZE 0x05U +#define NV2080_CTRL_FB_INFO_INDEX_BAR1_AVAIL_SIZE 0x1dU +#define NV2080_CTRL_FB_INFO_INDEX_USABLE_RAM_SIZE 0x20U + +typedef struct { + NvU32 index; + NvU32 data; +} NV2080_CTRL_FB_INFO; + +typedef struct { + NvU32 fbInfoListSize; + NV2080_CTRL_FB_INFO fbInfoList[NV2080_CTRL_FB_INFO_MAX_LIST_SIZE]; +} NV2080_CTRL_FB_GET_INFO_V2_PARAMS; + +typedef struct { + NvU32 pciDeviceId; + NvU32 pciSubSystemId; + NvU32 pciRevisionId; + NvU32 pciExtDeviceId; +} NV2080_CTRL_BUS_GET_PCI_INFO_PARAMS; + +typedef struct { + NvU64 time_nsec __attribute__((aligned(8))); +} NV2080_CTRL_TIMER_GET_TIME_PARAMS; + +/* NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE: static engine table with names. + * Sizes match tools/rmq/rmq.c, which has produced ground-truth on TU104. + */ +typedef struct { + NvU32 engineData[16]; + NvU32 pbdmaIds[2]; + NvU32 pbdmaFaultIds[2]; + NvU32 numPbdmas; + char engineName[16]; +} NV2080_FIFO_DEVICE_ENTRY; + +typedef struct { + NvU32 baseIndex; + NvU32 numEntries; + NvU32 bMore; + NV2080_FIFO_DEVICE_ENTRY entries[32]; +} NV2080_CTRL_FIFO_GET_DEVICE_INFO_TABLE_PARAMS; + +#define NV0080_CTRL_GPU_CLASSLIST_MAX_SIZE 100U + +typedef struct { + NvU32 numClasses; + NvU32 classList[NV0080_CTRL_GPU_CLASSLIST_MAX_SIZE]; +} NV0080_CTRL_GPU_GET_CLASSLIST_V2_PARAMS; + +/* ------------------------------------------------------------------ */ +/* Client + GPU discovery */ +/* ------------------------------------------------------------------ */ + +struct rm_client { + int fd; /* /dev/nvidiactl control fd */ + int gpu_fd; /* /dev/nvidiaN device fd (open-complete) */ + NvU32 hClient; + NvU32 hDevice; + NvU32 hSubdevice; + int gpu_minor; +}; + +#define RM_MAX_GPUS 32 +#define RM_BDF_LEN 32 +#define RM_NAME_LEN 128 +#define RM_UUID_LEN 96 +#define RM_VBIOS_LEN 64 + +struct rm_gpu_desc { + int minor; + char bdf[RM_BDF_LEN]; + char model[RM_NAME_LEN]; + char uuid[RM_UUID_LEN]; + char vbios[RM_VBIOS_LEN]; + int irq; +}; + +/* Open /dev/nvidiactl, bind a GPU (gpu_minor; <0 means 0), alloc the + * root-client -> device -> subdevice ladder, and keep the matching + * /dev/nvidiaN device fd open for the lifetime of the client. + * dev_path (may be NULL) overrides the GPU device node. + * Returns 0 on success, negative errno, or an RM status. + */ +int rm_client_open(struct rm_client *c, int gpu_minor, const char *dev_path); +void rm_client_close(struct rm_client *c); + +/* Issue a control on hObject; returns the raw NV_STATUS (0 = NV_OK) and + * stores -1 in *ioctl_ret on transport failure (NULL allowed). */ +NvU32 rm_control(struct rm_client *c, NvU32 hObject, NvU32 cmd, + void *params, NvU32 size, int *ioctl_ret); + +/* Scan the per-GPU information files under /proc/driver/nvidia (read-only, + * no device access). + */ +int rm_scan_gpus(struct rm_gpu_desc *out, int max); + +/* True if cmd is on the read-only allowlist (see nv2080.c). */ +int rm_control_is_readonly(NvU32 cmd); + +const char *rm_status_str(NvU32 status); + +#endif /* RM_API_H */ -- cgit v1.2.3