summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.h
blob: 0902830c46917553fb36caff0ba74fd0f556f49a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef GSP_PHYS_BOOTER_H
#define GSP_PHYS_BOOTER_H

#include <linux/types.h>
#include <linux/pci.h>
#include <linux/io.h>

#include "gsp_phys_boot.h"

/*
 * Real-GSP boot stages 3d/3e: Booter Load on SEC2, RISC-V reset and libos
 * arguments, FALCON_OS, RISC-V-active check (3d), then the status-queue poll
 * for the GSP-RM init event (3e).
 *
 * Stage 3d runs only after a successful FWSEC run (WPR2 up) in the same
 * claim. Its host-side staging - FMC copy, radix3 page tables for the GSP-RM
 * ELF, signature copy, message queues and the libos/GSP arguments - runs
 * first; gsp_phys_boot_dryrun prepares exactly that staging with no BAR0
 * writes and no falcon kicks.
 */

bool gsp_phys_boot_enabled(void);
bool gsp_phys_boot_dryrun_enabled(void);

/* True when either boot parameter is set (forces the stage-3b layout). */
bool gsp_phys_boot_requested(void);

/* Views into the staged GSP firmware ELF (set by gsp_phys_gpu.c). */
struct gsp_phys_boot_sources {
	const u8 *fw_image;		/* .fwimage section of the GSP-RM ELF */
	u64 fw_image_size;
	const u8 *fw_signature;		/* .fwsignature_tu10x section */
	u64 fw_signature_size;
};

/*
 * Stage 3d host-memory staging: allocate/copy every sysmem buffer the Booter
 * Load ucode DMAs from, fill the message queues / libos arguments / GSP
 * arguments, update the WPR metadata sysmem addresses and run the placement
 * self-checks. The only device access is the bounded read-only state log.
 * With dryrun=true nothing device-visible is written and no falcon is
 * touched. Staging stays allocated until gsp_phys_boot_quiesce() /
 * gsp_phys_boot_staging_free() on release.
 */
int gsp_phys_boot_prime(struct gsp_phys_boot *boot, struct pci_dev *pdev,
			void __iomem *bar0,
			const struct gsp_phys_boot_sources *src, bool dryrun);

/*
 * Stage 3d device sequence: requires primed staging and WPR2 up. Resets the
 * GSP falcon into RISC-V, programs the libos args mailbox, runs Booter Load
 * on SEC2 with the WPR metadata address, writes FALCON_OS and verifies the
 * RISC-V core is active.
 */
int gsp_phys_boot_run(struct gsp_phys_boot *boot, struct pci_dev *pdev,
		      void __iomem *bar0);

/*
 * Stage 3e: bounded status-queue poll for the GSP-RM init event (function
 * 0x1001, rpc_result 0). When GSP-RM asks the host to execute an inline CPU
 * sequencer command buffer first (function 0x1002,
 * NV_VGPU_MSG_EVENT_GSP_RUN_CPU_SEQUENCER), the buffer is executed against
 * the claimed BAR0 (register operations bounded and validated against
 * bar0_len) and the poll then continues. Non-fatal: a timeout or a sequencer
 * validation/execution failure leaves the successful 3d boot and the release
 * teardown valid.
 */
void gsp_phys_boot_rmwait(struct gsp_phys_boot *boot, void __iomem *bar0,
			  resource_size_t bar0_len);

/*
 * Release sequence, in this order (gsp_phys_gpu_release):
 *   0. gsp_phys_boot_rm_unload(): if stage 3d ran, the GSP-RM init-done
 *      event (function 0x1001 with rpc_result 0) was observed, and the
 *      UNLOADING_GUEST_DRIVER RPC has not been submitted yet, submit it once
 *      (bounded) and wait for the GSP-RM processor suspend so the scratch14
 *      handoff bit the Booter Unload gate needs can be set; a no-op when
 *      stage 3d did not run, init-done was never seen (an RPC before
 *      init-done can be dropped) or the RPC was already sent in this boot;
 *   1. gsp_phys_boot_quiesce(): if a Booter Load kick was issued, reset the
 *      GSP falcon (stops RISC-V/GSP-RM) BEFORE the FWSEC teardown runs; no
 *      device access when bar0 is NULL (unresponsive-board abort);
 *   2. the existing gsp_phys_fwsec_release() teardown (FWSEC-SB + booter
 *      unload);
 *   3. gsp_phys_boot_staging_free(): release every host buffer. Called after
 *      both falcons have been reset so no ucode can still DMA from it.
 */
void gsp_phys_boot_quiesce(void __iomem *bar0);
void gsp_phys_boot_staging_free(struct pci_dev *pdev);

/*
 * Command-queue TX: build a msgq record with the 570.144 element/rpc header
 * layout, splitting it into 1..16 4 KB elements when it does not fit one
 * (reference elemCount = ceil((48 + rpc.length) / 4096), each element copied
 * to its own slot, checksum folded over the whole record up to the
 * 8-byte-aligned length), validate the peer command read pointer
 * (status+rxHdrOff when the status header carries MSGQ_FLAGS_SWAP_RX, else
 * cmd+rxHdrOff) and the peer-derived free space, copy the record into the
 * next command-queue slot(s), publish the new writePtr under wmb() and ring
 * the GSP queue-head doorbell. Requires the stage-3d command-queue staging;
 * bounded and refuses (with a log) when the TX header does not match what was
 * staged or the ring cannot hold elemCount free elements. Does not touch WPR2
 * or the falcons.
 */
int gsp_phys_queue_tx_submit(void __iomem *bar0, u32 function,
			     const void *payload, u32 payload_len);

/*
 * Send NV_VGPU_MSG_FUNCTION_UNLOADING_GUEST_DRIVER (function 47) with a normal
 * unload payload (bInPMTransition=0, bGc6Entering=0, newLevel=0), then wait
 * (bounded, 10 s) for the GSP-RM processor to suspend the way
 * kgspWaitForProcessorSuspend_TU102 does: GSP falcon MAILBOX0 == 0x80000000.
 * Sends at most once per boot (tracked across release and the debugfs
 * trigger). Returns 0 only when the suspend was observed and all four
 * scratch14 handoff bits (24..27) read DONE, -EALREADY if already sent,
 * -EINVAL when stage 3d did not run or GSP-RM init-done (function 0x1001,
 * rpc_result 0) was never observed (an RPC before init-done can be dropped),
 * -ETIMEDOUT on the suspend bound and -EIO when the handoff bits are not all
 * DONE after the suspend. Never writes WPR2.
 */
int gsp_phys_boot_rm_unload(void __iomem *bar0);

/*
 * Module-owned debugfs files (dir "open-iov-vfio"), registered by
 * nv_vgpu_init() and removed by nv_vgpu_exit(). All file_operations carry
 * .owner = THIS_MODULE so an open fd pins the module:
 *   - "gsp-phys-unload-rpc" (write-only, mode 0200): writing "1" runs
 *     gsp_phys_boot_rm_unload() on a live claim; every other value or state
 *     (parameter off, GPU unclaimed, stage 3d not run, init-done not
 *     observed, already submitted) is a logged no-op.
 *   - "gsp-phys-rm-probe" (write-only, mode 0200): writing "1" runs one host
 *     RM probe cycle on a live, init-done claim: GET_GSP_STATIC_INFO
 *     (function 65, 4-byte request), and when no reply arrives,
 *     SET_GUEST_SYSTEM_INFO (function 1, 792-byte version payload) once
 *     followed by one GET_GSP_STATIC_INFO retry. Serialised with the unload
 *     trigger by the same mutex and bounded by the per-wait timeouts; never
 *     sends when init-done was not observed and never touches WPR2. The
 *     static-info reply is decoded into dmesg (internal handles, split-VA
 *     flag, BAR1/2 PDE bases, FB geometry, engine caps, SRIOV/board fields).
 *   - "gsp-phys-rm-call" (write-only, mode 0200): writing N (1..4) runs the
 *     host RM client ladder cumulatively through stage N on a live, init-done
 *     claim and remembers the reached stage for the rest of the session:
 *     stage 1 allocates NV01_ROOT -> NV01_DEVICE_0 -> NV20_SUBDEVICE_0
 *     (function 103); stage 2 allocates and registers the nine DMA buffers
 *     (function 4, NV01_MEMORY_LIST_SYSTEM with real PFNs); stage 3 allocates
 *     KEPLER_CHANNEL_GROUP_A (COPY0) and TURING_CHANNEL_GPFIFO_A with the
 *     physical instance/userd/ramfc/mthdbuf descriptors then requests the
 *     work-submit token (function 76); stage 4 schedules the channel, writes
 *     the CE method block plus GPFIFO entry and USERD GP_PUT, rings the PF
 *     channel doorbell and polls the sysmem semaphore for a real 4 KB
 *     sysmem-to-sysmem copy (function 76 + the CE doorbell path). Writing 5
 *     is the alternative stage-1 path: it adopts the
 *     hInternalClient/hInternalDevice/hInternalSubdevice handles from the
 *     session's decoded GspStaticConfigInfo (running the fn1+fn65 probe cycle
 *     inline first when needed), marks stage 1 satisfied, and a following
 *     write of 4 runs stages 2-4 against the adopted handles. On a failed
 *     reply (rpc_result != 0, e.g. the fn103 NV01_ROOT rejection) the RPC
 *     helper logs the payload words at +0/+16/+32 and the first 64 payload
 *     bytes in bounded hex. Serialised with the other triggers by
 *     gsp_phys_rm_lock, per-RPC bounded (2000 ms), aborts at the first
 *     failure with no object teardown (UNLOAD + rmmod is the fail-safe),
 *     never touches WPR2, and is inert until the file is written. Ladder
 *     buffers are freed by gsp_phys_boot_staging_free() on release.
 *   - "gsp-phys-log-dump" (read-only, mode 0444): dumps the LOGINIT and
 *     LOGRM libos task-log host buffers allocated at stage-3d prime. Per
 *     buffer: a one-line header (name, allocated size, kernel VA, DMA
 *     address), the raw content as "%08x: %08x ..." hex lines (bounded to
 *     the allocated size and 64 KB per buffer; authoritative for offline
 *     decoding with the evidence tree's decode_logs.py) and a decoded view
 *     derived from the known libos record format (word[0]=put pointer,
 *     records {args..., metadata_ptr, timestamp}, last <=60 timestamp-like
 *     records). Read-only: no buffer byte is modified.
 *   - "gsp-phys-state" (read-only, mode 0444): seq_file snapshot of the
 *     claimed/booted state (falcon registers, scratch14, both queue TX
 *     headers, a bounded read-only status-ring walk, the stage flags and the
 *     last RM probe result). It returns a one-line status instead of
 *     touching hardware when the device is not claimed or the stage-3d
 *     staging is not primed, never writes and never advances the host
 *     status-queue readPtr (no consumption).
 */
int gsp_phys_boot_debugfs_init(void);
void gsp_phys_boot_debugfs_fini(void);

#endif /* GSP_PHYS_BOOTER_H */