/* Copyright 2024 Joshua Bakita
* SPDX-License-Identifier: MIT
*
* File outline:
* - Runlist, preemption, and channel control (FIFO)
* - Basic GPU information (MC)
* - Detailed GPU information (PTOP, FUSE, and CE)
* - PRAMIN, BAR1/2, and page table status
* - Helper functions for nvdebug
*
* This function should not depend on any Linux-internal headers, and may be
* included outside of nvdebug.
*
* Style: This file uses up to 82-character lines to accomodate 2-character
* indented quotes from open-gpu-doc without reflowing.
*/
#include <linux/types.h>
// Fully defined in include/nvgpu/gk20a.h. We only pass around pointers to
// this, so declare as incomplete type to avoid pulling in the nvgpu headers.
struct gk20a;
/* Runlist Channel
A timeslice group (TSG) is composed of channels. Each channel is a FIFO queue
of GPU commands. These commands are typically queued from userspace.
Prior to Volta, channels could also exist independent of a TSG. These are
called "bare channels" in the Jetson nvgpu driver.
`INST_PTR` points to a GPU Instance Block which contains FIFO states, virtual
address space configuration for this context, and a pointer to the page
tables. All channels in a TSG point to the same GPU Instance Block (?).
"RUNQUEUE_SELECTOR determines to which runqueue the channel belongs, and
thereby which PBDMA will run the channel. Increasing values select
increasingly numbered PBDMA IDs serving the runlist. If the selector value
exceeds the number of PBDMAs on the runlist, the hardware will silently
reassign the channel to run on the first PBDMA as though RUNQUEUE_SELECTOR had
been set to 0. (In current hardware, this is used by SCG on the graphics
runlist only to determine which FE pipe should service a given channel. A
value of 0 targets the first FE pipe, which can process all FE driven engines:
Graphics, Compute, Inline2Memory, and TwoD. A value of 1 targets the second
FE pipe, which can only process Compute work. Note that GRCE work is allowed
on either runqueue." (NVIDIA) Note that it appears runqueue 1 is the default
for CUDA work on the Jetson Xavier.
ENTRY_TYPE (T) : type of this entry: ENTRY_TYPE_CHAN
CHID (ID) : identifier of the channel to run (overlays ENTRY_ID)
RUNQUEUE_SELECTOR (Q) : selects which PBDMA should run this channel if
more than one PBDMA is supported by the runlist,
additionally, "A value of 0 targets the first FE
pipe, which can process all FE driven engines:
Graphics, Compute, Inline2Memory, and TwoD. A value
of 1 targets the second FE pipe, which can only
process Compute work. Note that GRCE work is allowed
on either runqueue.)"
INST_PTR_LO : lower 20 bits of the 4k-aligned instance block pointer
INST_PTR_HI : upper 32 bits of instance block pointer
INST_TARGET (TGI) : aperture of the instance block
USERD_PTR_LO : upper 24 bits of the low 32 bits, of the 512-byte-aligned USERD pointer
USERD_PTR_HI : upper 32 bits of USERD pointer
USERD_TARGET (TGU) : aperture of the USERD data structure
Channels were around since at least Fermi, but were rearranged with Volta to
add a USERD pointer, a longer INST pointer, and a runqueue selector flag.
*/
enum ENTRY_TYPE {ENTRY_TYPE_CHAN = 0, ENTRY_TYPE_TSG = 1};
enum INST_TARGET {TARGET_VID_MEM = 0, TARGET_INVALID = 1, TARGET_SYS_MEM_COHERENT = 2, TARGET_SYS_MEM_NONCOHERENT = 3};
static inline const char *target_to_text(enum INST_TARGET t) {
switch (t) {
case TARGET_VID_MEM:
return "VID_MEM";
case TARGET_SYS_MEM_COHERENT:
return "SYS_MEM_COHERENT";
case TARGET_SYS_MEM_NONCOHERENT:
return "SYS_MEM_NO
|