diff options
| author | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-22 22:40:26 -0400 |
|---|---|---|
| committer | Arthur Hanson Rasmusson <arthur@vgpu.io> | 2026-09-22 22:40:26 -0400 |
| commit | f6d450a8be075fdc19a874826e7649ae0149b099 (patch) | |
| tree | 9f68bdb6ce1f120fb80531895ad4f265c001d65a /kernel | |
| parent | fcd603db457c0fb035df882abc55397bc854a1cd (diff) | |
| download | open-iov-f6d450a8be075fdc19a874826e7649ae0149b099.tar.gz open-iov-f6d450a8be075fdc19a874826e7649ae0149b099.zip | |
kernel: guest probe completes - nvidia-smi enumerates the emulated TU104
Root cause of the golden-image NV_ERR_NO_MEMORY: STATIC_KGR_GET_CONTEXT_
BUFFERS_INFO (0x20800a32) fell through to the generic zeroed reply, so
kgraphicsInitializeDeferredStaticData() stored a 0-byte main ctx buffer
size and kgrctxAllocMainCtxBuffer() did a 0-page allocation
(mem_desc.c:1353). Serve the TU104 per-engine ctx buffer table (26 engine
IDs x 8 GR engines; NV_U32_MAX = unsupported, which the client skips).
Second blocker after that: L2 cache-op and TLB-invalidate completion
registers. Turing reaches them through the virtual-register window
(GPU_VREG_* = BAR0 + sriovState.virtualRegPhysOffset + offset, 0xB80000
for a non-SRIOV virtual GPU): NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE
(0xB830B0, TRIGGER bit31) and the L2 invalidate/dirty-flush set
(0x70000-0x70014 and 0xB80F00/0xB80F04). The driver soft-locked spinning
in osDevReadReg032 on 0xB830B4 (kgmmuCheckPendingInvalidates_TU102) and
timed out in kmemsysDoCacheOp_GM107; auto-clear all of them (both the
plain and windowed aliases).
Third: re-probe failed with GspStatusQueueInit msgqRxLink timeout because
gsp_rm_emu_reset() was not called before a fresh boot, leaving rm->parsed
set so the new libos args were never parsed. Reset GSP-RM state on the
fresh FWSEC kick.
Verified: guest nvidia-smi and nvidia-smi -L both exit 0 (full
unload/reload cycle), GPU enumerated as "NVIDIA GeForce RTX 2080 SUPER"
with 256MB, no NO_MEMORY / timeouts / soft lockups in the guest.
Also add tools/rmq/grctx_oracle.c documenting that the host RM does not
expose the ctx-buffer table to userspace (the real values are probed from
the ctxsw ucode by GSP-RM), so the emulation serves synthesized sizes.
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/gsp_emulation.c | 72 | ||||
| -rw-r--r-- | kernel/gsp_emulation.h | 39 | ||||
| -rw-r--r-- | kernel/gsp_rm_emulation.c | 90 | ||||
| -rw-r--r-- | kernel/gsp_rm_tu104.h | 78 |
4 files changed, 253 insertions, 26 deletions
diff --git a/kernel/gsp_emulation.c b/kernel/gsp_emulation.c index 44facc1..0b6bba0 100644 --- a/kernel/gsp_emulation.c +++ b/kernel/gsp_emulation.c @@ -195,7 +195,6 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx) u32 gsp_cpuctl = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_GSP_CPUCTL); u32 sec2_cpuctl = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_SEC2_CPUCTL); u32 engine = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_GSP_ENGINE); - u32 mmu_inv = gsp_emu_shadow_read32(ctx, GSP_EMU_REG_MMU_INVALIDATE); u32 sw_vector; /* Software-interrupt trigger: the driver writes a vector to @@ -231,13 +230,63 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx) } /* TLB invalidate auto-complete: the driver sets TRIGGER then spins - * polling for it to clear (kgmmuCheckPendingInvalidates). Report - * instant completion or the driver wedges the open/init path. */ - if (mmu_inv & GSP_EMU_MMU_INVALIDATE_TRIGGER) { - gsp_emu_shadow_write32(ctx, GSP_EMU_REG_MMU_INVALIDATE, - mmu_inv & ~GSP_EMU_MMU_INVALIDATE_TRIGGER); - pr_info_ratelimited("GSP-BOOT: MMU_INVALIDATE trigger auto-cleared (val=0x%x)\n", - mmu_inv); + * polling for it to clear (kgmmuCheckPendingInvalidates_TU102 reads + * GPU_VREG_RD32(NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE) = + * BAR0 + 0xB80000 + 0x30B0; the physical path uses the plain alias). + * Report instant completion or the driver soft-locks spinning inside + * osDevReadReg032. */ + { + static const u32 tlb_inv_regs[] = { + GSP_EMU_REG_MMU_INVALIDATE, + GSP_EMU_REG_MMU_INVALIDATE_WIN, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(tlb_inv_regs); i++) { + u32 val = gsp_emu_shadow_read32(ctx, tlb_inv_regs[i]); + + if (!(val & GSP_EMU_MMU_INVALIDATE_TRIGGER)) + continue; + gsp_emu_shadow_write32(ctx, tlb_inv_regs[i], + val & ~GSP_EMU_MMU_INVALIDATE_TRIGGER); + pr_info_ratelimited("GSP-BOOT: MMU_INVALIDATE[0x%x] trigger auto-cleared (val=0x%x)\n", + tlb_inv_regs[i], val); + } + } + + /* L2 cache-op auto-complete: kmemsysDoCacheOp_GM107 writes PENDING + * (bit 0) into the NV_UFLUSH_* / VF L2 invalidate registers and spins + * until the polled bits read back 0 (FB flush, L2 sysmem/peermem + * invalidate, L2 clean, L2 flush-dirty, L2 wait-for-sys-reads). On + * Turing the sysmem/peermem invalidate registers go through the + * GPU_VREG_* window (BAR0 + 0xB80000 + NV_VIRTUAL_FUNCTION_PRIV_L2_*), + * so cover both the plain and windowed aliases. The emulated L2 has + * nothing to do, so clear them as soon as they are observed. */ + { + static const u32 uflush_regs[] = { + GSP_EMU_REG_UFLUSH_FB_FLUSH, + GSP_EMU_REG_UFLUSH_L2_SYSMEM_INV, + GSP_EMU_REG_UFLUSH_L2_PEERMEM_INV, + GSP_EMU_REG_UFLUSH_L2_CLEAN_COMPTAGS, + GSP_EMU_REG_UFLUSH_L2_FLUSH_DIRTY, + GSP_EMU_REG_UFLUSH_L2_WAIT_SYS_READS, + GSP_EMU_REG_VF_L2_SYSMEM_INV, + GSP_EMU_REG_VF_L2_PEERMEM_INV, + GSP_EMU_REG_VF_L2_SYSMEM_INV_WIN, + GSP_EMU_REG_VF_L2_PEERMEM_INV_WIN, + }; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(uflush_regs); i++) { + u32 val = gsp_emu_shadow_read32(ctx, + uflush_regs[i]); + + if (!val) + continue; + gsp_emu_shadow_write32(ctx, uflush_regs[i], 0); + pr_info_ratelimited("GSP-BOOT: UFLUSH[0x%x] 0x%x auto-cleared\n", + uflush_regs[i], val); + } } /* CrashCat wayfinder suppression: if the GSP falcon's DEBUGINFO @@ -312,6 +361,13 @@ static void gsp_emu_poll_boot(struct gsp_emu_context *ctx) */ if ((gsp_cpuctl & GSP_EMU_CPUCTL_STARTCPU) && ctx->boot_stage == GSP_BOOT_STAGE_IDLE) { + /* A fresh FWSEC kick means a new GSP boot: drop any GSP-RM + * queue state left from the previous probe (the driver has + * already torn down its old queue). Without this the next + * Booter completion would skip the chain re-parse + * (rm->parsed still set) and GspStatusQueueInit would time + * out on re-probe. */ + gsp_rm_emu_reset(ctx); gsp_emu_shadow_write32(ctx, GSP_EMU_REG_VBIOS_SCRATCH_0E, 0); gsp_emu_shadow_write32(ctx, GSP_EMU_REG_WPR2_ADDR_HI, 0x100000); gsp_emu_shadow_write32(ctx, GSP_EMU_REG_WPR2_ADDR_LO, diff --git a/kernel/gsp_emulation.h b/kernel/gsp_emulation.h index 801ea78..9a8f241 100644 --- a/kernel/gsp_emulation.h +++ b/kernel/gsp_emulation.h @@ -58,10 +58,42 @@ #define GSP_EMU_REG_SEC2_MAILBOX0 0x840040 #define GSP_EMU_REG_SEC2_ENGINE 0x8403c0 +/* Base of the virtual-function register window (NV_VIRTUAL_FUNCTION_FULL_PHYS_ + * OFFSET). The client RM reaches per-VF registers through GPU_VREG_* = + * BAR0 + sriovState.virtualRegPhysOffset + offset; for a non-SRIOV virtual GPU + * that offset is 0xB80000, and 0 for a VF, hence the plain + windowed aliases + * below. */ +#define GSP_EMU_REG_FULL_PHYS_OFFSET 0xB80000 + /* NV_VIRTUAL_FUNCTION_PRIV_MMU_INVALIDATE: driver sets TRIGGER(bit31) to - * start a TLB invalidate, then polls for bit31==0 (done). We auto-clear it. */ + * start a TLB invalidate, then polls for bit31==0 (done). We auto-clear it. + * The client RM reaches it through the GPU_VREG_* window (BAR0 + 0xB80000 + + * 0x30B0) and the physical path pokes the plain 0x30B0 alias, so watch both. */ #define GSP_EMU_REG_MMU_INVALIDATE 0x0030b0 #define GSP_EMU_MMU_INVALIDATE_TRIGGER (1U << 31) +#define GSP_EMU_REG_MMU_INVALIDATE_WIN (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x0030b0) + +/* L2 cache-op completion registers (NV_UFLUSH_*): the driver writes PENDING + * (bit 0) to issue FB flush / L2 invalidate / L2 clean+dirty flush and then + * spins in kmemsysDoCacheOp_GM107 until the polled bits read back 0. On real + * hardware the L2 clears them when the operation completes; the emulated L2 + * completes instantly, so auto-clear any pending bits. + * + * On Turing the sysmem/peermem invalidate registers are reached through the + * virtual-register window (GPU_VREG_*: BAR0 + sriovState.virtualRegPhysOffset + * + NV_VIRTUAL_FUNCTION_PRIV_L2_*); the offset is 0xB80000 for a non-SRIOV + * virtual GPU and 0 for a VF, so watch both the plain and windowed aliases. */ +#define GSP_EMU_REG_UFLUSH_BASE 0x070000 +#define GSP_EMU_REG_UFLUSH_FB_FLUSH (GSP_EMU_REG_UFLUSH_BASE + 0x00) +#define GSP_EMU_REG_UFLUSH_L2_SYSMEM_INV (GSP_EMU_REG_UFLUSH_BASE + 0x04) +#define GSP_EMU_REG_UFLUSH_L2_PEERMEM_INV (GSP_EMU_REG_UFLUSH_BASE + 0x08) +#define GSP_EMU_REG_UFLUSH_L2_CLEAN_COMPTAGS (GSP_EMU_REG_UFLUSH_BASE + 0x0c) +#define GSP_EMU_REG_UFLUSH_L2_FLUSH_DIRTY (GSP_EMU_REG_UFLUSH_BASE + 0x10) +#define GSP_EMU_REG_UFLUSH_L2_WAIT_SYS_READS (GSP_EMU_REG_UFLUSH_BASE + 0x14) + +/* NV_VIRTUAL_FUNCTION_PRIV_L2_{SYSMEM,PEERMEM}_INVALIDATE (dev_vm.h) */ +#define GSP_EMU_REG_VF_L2_SYSMEM_INV 0x000f00 +#define GSP_EMU_REG_VF_L2_PEERMEM_INV 0x000f04 /* NV_PFALCON_FALCON_DEBUGINFO (GSP falcon BAR0+0x110094): holds the CrashCat * wayfinder-L0 descriptor. If its low 16 bits == 0xdead (NV_CRASHCAT_SIGNATURE), @@ -80,11 +112,14 @@ * _osVerifyInterrupts (osVerifySystemEnvironment) fires a doorbell software * interrupt and waits for its ISR; if we don't set the pending state and * inject MSI-X, the ISR never runs and RmInitAdapter bails. */ -#define GSP_EMU_REG_FULL_PHYS_OFFSET 0xB80000 #define GSP_EMU_REG_CPU_INTR_LEAF_TRIGGER (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x1640) #define GSP_EMU_REG_CPU_INTR_LEAF_BASE (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x1000) #define GSP_EMU_REG_CPU_INTR_TOP_BASE (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x1600) +/* Windowed aliases of the VF L2 invalidate registers (GPU_VREG_* path). */ +#define GSP_EMU_REG_VF_L2_SYSMEM_INV_WIN (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x000f00) +#define GSP_EMU_REG_VF_L2_PEERMEM_INV_WIN (GSP_EMU_REG_FULL_PHYS_OFFSET + 0x000f04) + #define GSP_EMU_CPUCTL_STARTCPU 0x2 #define GSP_EMU_CPUCTL_HALTED 0x10 diff --git a/kernel/gsp_rm_emulation.c b/kernel/gsp_rm_emulation.c index 07ba807..f18d17c 100644 --- a/kernel/gsp_rm_emulation.c +++ b/kernel/gsp_rm_emulation.c @@ -1201,6 +1201,74 @@ static void gsp_rm_handle_kgr_get_floorsweeping_masks( m->gpcMask, TU104_TPC_PER_GPC); } +/* + * STATIC_KGR_GET_CONTEXT_BUFFERS_INFO (0x20800a32) + * + * kgraphicsInitializeDeferredStaticData() asks the physical RM (GSP-RM) for + * the per-engine context buffer sizes; kgrctxAllocMainCtxBuffer() then sizes + * the golden image ctx buffer from engine[GRAPHICS].size. The zeroed generic + * reply left size == 0 -> a 0-page allocation -> NV_ERR_NO_MEMORY at + * mem_desc.c:1353 (kgrctxAllocMainCtxBuffer -> kgraphicsCreateGoldenImageChannel). + * + * The real physical RM probes these from the ctxsw ucode + * (grSetupInitialCtxState -> grDiscoverCtxBufferSize) and reports NV_U32_MAX + * for unsupported engine IDs. The client skips NV_U32_MAX entries in + * kgraphicsCreateGoldenImageChannel's VA reservation, so the emulated layout + * below mirrors that: page-aligned scratch sizes for the buffers the client + * allocates, NV_U32_MAX for the engine IDs Turing does not support. + */ +static void gsp_rm_handle_kgr_get_context_buffers_info( + struct gsp_emu_context *ctx, + u32 sequence, + u32 *out_status, + u8 *out_params, + u32 *out_params_size) +{ + static const struct tu104_ctx_buffer_info sizes[TU104_CTX_ENGINE_ID_COUNT] = { + [TU104_CTX_ENG_GRAPHICS] = { TU104_CTX_SIZE_MAIN, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_ZCULL] = { TU104_CTX_SIZE_ZCULL, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PM] = { TU104_CTX_SIZE_PM, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PREEMPT] = { TU104_CTX_SIZE_PREEMPT, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_SPILL] = { TU104_CTX_SIZE_SPILL, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PAGEPOOL] = { TU104_CTX_SIZE_PAGEPOOL, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_BETACB] = { TU104_CTX_SIZE_BETACB, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_RTV] = { TU104_CTX_SIZE_RTV, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PATCH] = { TU104_CTX_SIZE_PATCH, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_BUNDLE_CB] = { TU104_CTX_SIZE_BUNDLE_CB, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PAGEPOOL_GLOBAL] = { TU104_CTX_SIZE_PAGEPOOL, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_ATTRIBUTE_CB] = { TU104_CTX_SIZE_ATTRIBUTE_CB, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_RTV_CB_GLOBAL] = { TU104_CTX_SIZE_RTV_CB_GLOBAL, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_FECS_EVENT] = { TU104_CTX_SIZE_FECS_EVENT, 0x1000 }, + [TU104_CTX_ENG_GRAPHICS_PRIV_ACCESS_MAP] = { TU104_CTX_SIZE_PRIV_ACCESS_MAP, 0x1000 }, + }; + struct tu104_gr_get_context_buffers_info_params *info = + (struct tu104_gr_get_context_buffers_info_params *)out_params; + u32 e, i; + + memset(out_params, 0, sizeof(*info)); + + for (e = 0; e < TU104_CTX_GPU_MAX_ENGINES; e++) { + for (i = 0; i < TU104_CTX_ENGINE_ID_COUNT; i++) { + /* engine IDs the chip does not support report + * NV_U32_MAX (the client skips those entries) */ + if (sizes[i].size == 0) { + info->engineContextBuffersInfo[e].engine[i].size = 0xFFFFFFFF; + info->engineContextBuffersInfo[e].engine[i].alignment = 0xFFFFFFFF; + continue; + } + info->engineContextBuffersInfo[e].engine[i].size = sizes[i].size; + info->engineContextBuffersInfo[e].engine[i].alignment = sizes[i].alignment; + } + } + + *out_params_size = sizeof(*info); + *out_status = 0; + + nv_vgpu_info(ctx->vgpu, "GSPRM: KGR_GET_CONTEXT_BUFFERS_INFO -> main ctx 0x%x, patch 0x%x, pm 0x%x (engines=%u x %u)", + TU104_CTX_SIZE_MAIN, TU104_CTX_SIZE_PATCH, TU104_CTX_SIZE_PM, + TU104_CTX_GPU_MAX_ENGINES, TU104_CTX_ENGINE_ID_COUNT); +} + static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, const u8 *elem, u32 sequence) { @@ -1301,6 +1369,12 @@ 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_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO: + gsp_rm_handle_kgr_get_context_buffers_info(ctx, sequence, + &out_status, + reply + GSP_RM_CTRL_HDR_SIZE, &out_params_size); + break; + case TU104_CTRL_STATIC_KGR_GET_FLOORSWEEPING_MASKS: gsp_rm_handle_kgr_get_floorsweeping_masks(ctx, sequence, &out_status, @@ -1360,22 +1434,6 @@ static void gsp_rm_handle_rm_control(struct gsp_emu_context *ctx, * complete well-formed record. (The poll match is function-only; the echo * keeps the post-poll result struct self-consistent.) */ -/* - sizeof(struct tu104_gr_floorsweeping_masks); - *out_status = 0; - - nv_vgpu_info(ctx->vgpu, "GSPRM: KGR_GET_FLOORSWEEPING_MASKS -> gpcMask=0x%x tpc/gpc=%u", - m->gpcMask, TU104_TPC_PER_GPC); -} - -/* - * GSP_RM_FREE (function 10) - NVOS00_PARAMETERS echo with status=NV_OK. - * - * rpc_gsp_free: { hRoot, hObjectParent, hObjectOld, status }. Echo the - * request's params back with status=0 so the driver's free rpc_message is a - * complete well-formed record. (The poll match is function-only; the echo - * keeps the post-poll result struct self-consistent.) - */ static void gsp_rm_handle_free(struct gsp_emu_context *ctx, const u8 *elem, u32 sequence) { diff --git a/kernel/gsp_rm_tu104.h b/kernel/gsp_rm_tu104.h index ff2a4a7..f40c77d 100644 --- a/kernel/gsp_rm_tu104.h +++ b/kernel/gsp_rm_tu104.h @@ -702,6 +702,84 @@ static const struct tu104_internal_device_info tu104_internal_device_table[] = { #define TU104_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE 0x20802a08 #define TU104_CTRL_STATIC_KGR_GET_GLOBAL_SM_ORDER 0x20800a22 #define TU104_CTRL_STATIC_KGR_GET_INFO 0x20800a2a +#define TU104_CTRL_STATIC_KGR_GET_CONTEXT_BUFFERS_INFO 0x20800a32 + +/* NV2080_CTRL_INTERNAL_ENGINE_CONTEXT_BUFFER_INFO (engine context buffer info) + * NV2080_CTRL_INTERNAL_STATIC_GR_CONTEXT_BUFFERS_INFO: engine[ENGINE_ID_COUNT] + * NV2080_CTRL_INTERNAL_STATIC_GR_GET_CONTEXT_BUFFERS_INFO_PARAMS: + * engineContextBuffersInfo[GR_MAX_ENGINES] + * + * The driver's kgraphicsInitializeDeferredStaticData() asks the physical RM + * (GSP-RM) for this table; kgrctxAllocMainCtxBuffer() then sizes the golden + * image ctx buffer from engine[GRAPHICS].size. A zeroed reply produces a + * 0-byte (0-page) allocation -> NV_ERR_NO_MEMORY (mem_desc.c:1353). + * + * The physical RM probes these sizes from the ctxsw ucode at GR init + * (grSetupInitialCtxState -> grDiscoverCtxBufferSize) and reports + * NV_U32_MAX for engine IDs the chip does not support. The values below are + * the emulated TU104 layout (own buffers, no real GR engine behind them): + * sizes are page-aligned scratch regions, NV_U32_MAX = "not supported". */ +#define TU104_CTX_ENGINE_ID_COUNT 26 /* _ENGINE_ID_COUNT (0x1a) */ +#define TU104_CTX_GPU_MAX_ENGINES 8 /* INTERNAL_GR_MAX_ENGINES */ + +/* NV0080_CTRL_FIFO_GET_ENGINE_CONTEXT_PROPERTIES_ENGINE_ID_* */ +#define TU104_CTX_ENG_GRAPHICS 0x00 +#define TU104_CTX_ENG_VLD 0x01 +#define TU104_CTX_ENG_VIDEO 0x02 +#define TU104_CTX_ENG_MPEG 0x03 +#define TU104_CTX_ENG_CAPTURE 0x04 +#define TU104_CTX_ENG_DISPLAY 0x05 +#define TU104_CTX_ENG_ENCRYPTION 0x06 +#define TU104_CTX_ENG_POSTPROCESS 0x07 +#define TU104_CTX_ENG_GRAPHICS_ZCULL 0x08 +#define TU104_CTX_ENG_GRAPHICS_PM 0x09 +#define TU104_CTX_ENG_COMPUTE_PREEMPT 0x0a +#define TU104_CTX_ENG_GRAPHICS_PREEMPT 0x0b +#define TU104_CTX_ENG_GRAPHICS_SPILL 0x0c +#define TU104_CTX_ENG_GRAPHICS_PAGEPOOL 0x0d +#define TU104_CTX_ENG_GRAPHICS_BETACB 0x0e +#define TU104_CTX_ENG_GRAPHICS_RTV 0x0f +#define TU104_CTX_ENG_GRAPHICS_PATCH 0x10 +#define TU104_CTX_ENG_GRAPHICS_BUNDLE_CB 0x11 +#define TU104_CTX_ENG_GRAPHICS_PAGEPOOL_GLOBAL 0x12 +#define TU104_CTX_ENG_GRAPHICS_ATTRIBUTE_CB 0x13 +#define TU104_CTX_ENG_GRAPHICS_RTV_CB_GLOBAL 0x14 +#define TU104_CTX_ENG_GRAPHICS_GFXP_POOL 0x15 +#define TU104_CTX_ENG_GRAPHICS_GFXP_CTRL_BLK 0x16 +#define TU104_CTX_ENG_GRAPHICS_FECS_EVENT 0x17 +#define TU104_CTX_ENG_GRAPHICS_PRIV_ACCESS_MAP 0x18 +#define TU104_CTX_ENG_GRAPHICS_SETUP 0x19 + +/* grabbag: emulated ctx buffer sizes (bytes) */ +#define TU104_CTX_SIZE_MAIN 0x200000 +#define TU104_CTX_SIZE_ZCULL 0x100000 +#define TU104_CTX_SIZE_PM 0x8000 +#define TU104_CTX_SIZE_PREEMPT 0x1000 +#define TU104_CTX_SIZE_SPILL 0x1000 +#define TU104_CTX_SIZE_PAGEPOOL 0x10000 +#define TU104_CTX_SIZE_BETACB 0x1000 +#define TU104_CTX_SIZE_RTV 0x1000 +#define TU104_CTX_SIZE_PATCH 0x2000 +#define TU104_CTX_SIZE_BUNDLE_CB 0x1000 +#define TU104_CTX_SIZE_ATTRIBUTE_CB 0x1000 +#define TU104_CTX_SIZE_RTV_CB_GLOBAL 0x1000 +#define TU104_CTX_SIZE_FECS_EVENT 0x1000 +#define TU104_CTX_SIZE_PRIV_ACCESS_MAP 0x1000 + +struct tu104_ctx_buffer_info { + u32 size; + u32 alignment; +}; + +struct tu104_gr_context_buffers_info { + struct tu104_ctx_buffer_info engine[TU104_CTX_ENGINE_ID_COUNT]; +}; + +struct tu104_gr_get_context_buffers_info_params { + struct tu104_gr_context_buffers_info + engineContextBuffersInfo[TU104_CTX_GPU_MAX_ENGINES]; +}; + /* NV0080_CTRL_GR_INFO entry + infoList indices (ctrl0080gr.h) */ struct tu104_gr_info_entry { |
