From 5f372957a5fd0dd7ca7d4b5f06e959cce92dd49e Mon Sep 17 00:00:00 2001 From: Arthur Hanson Rasmusson Date: Thu, 1 Oct 2026 10:07:14 -0400 Subject: gsp-phys: real GSP boot stages 3d/3e and the GSP-RM run-sequencer event Stage 3d stages the GSP-RM boot from host sysmem (FMC, radix3 over the GSP-RM ELF, signature, message queues, libos LOGINIT/LOGRM/RMARGS and GSP arguments) and runs Booter Load on SEC2: GSP RISC-V reset, libos mailbox, IMEM/DMEM direct load, BOOTVEC=0, M0==0, FALCON_OS, RISC-V active. Stage 3e links the status queue and polls for GSP-RM events; it now also executes the inline run-sequencer command buffer (event 0x1002) against BAR0 (REG_WRITE/MODIFY/POLL, DELAY, STORE, CORE_* including CORE_RESUME) and then waits for GSP_INIT_DONE 0x1001. Gated by gsp_phys_boot / gsp_phys_boot_dryrun (default off; the normal load path writes nothing). gsp_phys_fwsec=1 without gsp_phys_boot=1 is refused: a FWSEC-only carve cannot pass the booter-unload handoff gate. Release quiesces the GSP, runs the existing FWSEC-SB/booter-unload teardown and frees all staging. tools/gen_gsp_bindata.py decodes the public generated archives into the Booter Load image (prod signature patched at 0x8700) and the GSP-RM boot (FMC) image; both are self-checked at build time. --- kernel/gsp_phys_booter.h | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 kernel/gsp_phys_booter.h (limited to 'kernel/gsp_phys_booter.h') diff --git a/kernel/gsp_phys_booter.h b/kernel/gsp_phys_booter.h new file mode 100644 index 0000000..d76439d --- /dev/null +++ b/kernel/gsp_phys_booter.h @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef GSP_PHYS_BOOTER_H +#define GSP_PHYS_BOOTER_H + +#include +#include +#include + +#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): + * 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); + +#endif /* GSP_PHYS_BOOTER_H */ -- cgit v1.2.3