summaryrefslogtreecommitdiffstats
path: root/kernel/gsp_phys_booter.h
blob: a669bf32f95d01e1c144d26e6ac01c9a3ad5ffd1 (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
/* 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 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 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 single-element msgq record with the 570.144
 * element/rpc header layout, compute the XOR-fold checksum, copy it into the
 * next command-queue slot, publish the new writePtr with a DMA barrier 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. 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, -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 trigger (dir "open-iov-vfio", file
 * "gsp-phys-unload-rpc", write-only). 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, already submitted) is a
 * logged no-op. Registered by nv_vgpu_init() and removed by nv_vgpu_exit().
 */
int gsp_phys_boot_debugfs_init(void);
void gsp_phys_boot_debugfs_fini(void);

#endif /* GSP_PHYS_BOOTER_H */