summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_rm_emulation.c
diff options
context:
space:
mode:
authorArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-07 18:44:21 -0500
committerArthur Hanson Rasmusson <arthur@vgpu.io>2026-11-07 18:44:21 -0500
commit035d033c5a047e395a7b06bceea1dc5b594c3b90 (patch)
treeec772c209376abf0fa65fb1cea5c1527d4ce1fbe /kernel/gsp_rm_emulation.c
parent22ca5d04f2fdd91500ff82b6e5154a7e5efb50d4 (diff)
downloadopen-iov-035d033c5a047e395a7b06bceea1dc5b594c3b90.tar.gz
open-iov-035d033c5a047e395a7b06bceea1dc5b594c3b90.zip
vgsp-disp: host-side EVO display engine (channels, push buffer, notifier, raster)
The guest nvidia-modeset drives the display through per-channel NV-DMA push buffers kicked via the BAR0 UDISP control windows. Emulate that engine contract host-side, unmodified guest: - channel registration: display-channel RM objects (core 0xc57d, window 0xc57e, cursor 0xc57b, 0xc57a) are noted from the alloc stream, and the internal control NV2080_CTRL_CMD_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER (0x20800a58) records each push buffer (guest PA, size, class, instance, validity); - PUT polling + GET publication in the channel control pages (core 0x680000, window 0x690000+n*0x1000, cursor 0x6D8000+n*0x1000); - NV-DMA method parser (METHOD/ONE_INC/NONINC/JUMP/SET_SUBDEVICE_MASK) with the wrap-JUMP follow; - completion: SET_CONTEXT_DMA_NOTIFIER / SET_NOTIFIER_CONTROL tracking, exact notifier-surface resolution through the display instance hash table (no heuristic writes), NV_DISP_NOTIFIER FINISHED on UPDATE (0x200), and the channel completion event post; - free-running 1080p60 raster line for NVC57E_GET_LINE. All effects are behind independent knobs (disp_engine, disp_finish, disp_vblank, disp_events, disp_notifier_pa) with verbose diagnostics (disp_dbg, disp_dump), so the previous behaviour stays one load away.
Diffstat (limited to 'kernel/gsp_rm_emulation.c')
-rw-r--r--kernel/gsp_rm_emulation.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c
index 48e91dd..bb74767 100644
--- a/kernel/gsp_rm_emulation.c
+++ b/kernel/gsp_rm_emulation.c
@@ -19,6 +19,7 @@
#include "gsp_sema_service.h"
#include "gsp_phys_booter.h"
#include "gsp_phys_gpu.h"
+#include "gsp_display_engine.h"
/* ============================================================
* Guest-memory access ("virtual DMA" on behalf of the device)
@@ -3423,6 +3424,22 @@ static void gsp_rm_handle_rm_alloc(struct gsp_emu_context *ctx,
gsp_rm_register_channel(ctx, ho, params, params_size);
/*
+ * r1621: display channel objects (core 0xc57d, window 0xc57e, cursor
+ * 0xc57b, cursor-PIO base 0xc57a). Record class+instance -> hObject
+ * so the display engine can post the completion event the driver
+ * registered on the channel and name the channel in diagnostics.
+ * instance is the first u32 of both the DMA and PIO alloc params.
+ */
+ if ((class_id == 0xc57d || class_id == 0xc57e ||
+ class_id == 0xc57b || class_id == 0xc57a) &&
+ params_size >= 4) {
+ u32 inst = 0;
+
+ memcpy(&inst, params, 4);
+ gsp_disp_engine_note_object(ctx->vgpu, class_id, inst, ho);
+ }
+
+ /*
* NV01_EVENT (params are NV0005_ALLOC_PARAMETERS {hParentClient,
* hSrcResource, hClass, notifyIndex, data}). The driver allocates one
* per channel and waits for the GPU to post the event before it
@@ -4372,6 +4389,41 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx,
reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size);
break;
+ case TU104_CTRL_INTERNAL_DISPLAY_CHANNEL_PUSHBUFFER: {
+ /*
+ * r1621: the kernel RM programs each display channel's push
+ * buffer through this internal control right after the channel
+ * object is allocated. It carries the guest-physical push-
+ * buffer address, its size and the display class/instance - the
+ * exact inputs the host-side EVO engine needs (see
+ * gsp_display_engine.c). The reply stays a verbatim echo.
+ */
+ const u8 *pp = req_data + GSP_RM_CTRL_HDR_SIZE;
+ u8 *rp = reply + GSP_RM_CTRL_HDR_SIZE;
+
+ if (req.paramsSize >= 52 &&
+ req.paramsSize + GSP_RM_CTRL_HDR_SIZE <=
+ GSPRM_MAX_SINGLE_ELEM_DATA) {
+ u32 address_space = 0, hclass = 0, instance = 0;
+ u32 valid = 0;
+ u64 pa = 0, limit = 0;
+
+ memcpy(&address_space, pp + 0, 4);
+ memcpy(&pa, pp + 8, 8);
+ memcpy(&limit, pp + 16, 8);
+ memcpy(&hclass, pp + 28, 4);
+ memcpy(&instance, pp + 32, 4);
+ memcpy(&valid, pp + 36, 4);
+ memcpy(rp, pp, req.paramsSize);
+ gsp_disp_engine_channel_add(ctx->vgpu, hclass, instance,
+ pa, limit, address_space,
+ valid != 0);
+ }
+ out_status = 0;
+ out_params_size = req.paramsSize;
+ break;
+ }
+
case 0x801707: /* NV0080_CTRL_CMD_FIFO_GET_ENGINE_CONTEXT_PROPERTIES */
gsp_rm_handle_fifo_engine_ctx_props(ctx,
req_data + GSP_RM_CTRL_HDR_SIZE, req.paramsSize,