[PATCH v2 22/31] gpu: nova-core: gsp: add the GMC boot event dispatcher

John Hubbard <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The r000 GSP boot protocol sends its two load-and-execute events as GMC
commands, each identified by a command id.

Nova-core has a handler for each of the two events, but nothing that
reads a command id and selects between them.

Add the dispatcher, keyed on the two command ids from the r000 bindings.

Assisted-by: Cursor:claude-opus-5
Reviewed-by: Timur Tabi <[email protected]>
Reviewed-by: Zhi Wang <[email protected]>
Signed-off-by: John Hubbard <[email protected]>
---
 drivers/gpu/nova-core/gsp/boot.rs | 62 +++++++++++++++++++++++++++++--
 drivers/gpu/nova-core/gsp/fw.rs   | 10 +++++
 2 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index b7079970e049..9afc95e534a3 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -37,7 +37,11 @@
     },
     gsp::{
         cmdq::Cmdq,
-        commands, //
+        commands,
+        fw::{
+            GMCAPI_CMD_EXEC_GENERIC_BOOTLOADER,
+            GMCAPI_CMD_EXEC_HS_BINARY, //
+        }, //
     },
     regs, //
 };
@@ -163,6 +167,60 @@ fn core_resume(
         Ok(())
     }
 
+    /// Dispatch one GMC boot event to its load-and-execute handler.
+    ///
+    /// LIBOS2 chipsets send `GMCAPI_CMD_EXEC_GENERIC_BOOTLOADER` and LIBOS3 chipsets send
+    /// `GMCAPI_CMD_EXEC_HS_BINARY`, so a given GPU only ever reaches one of the two handlers.
+    ///
+    /// # Errors
+    ///
+    /// - `EINVAL` if `command_id` is not a load-and-execute command.
+    ///
+    /// Errors from the handlers are propagated as-is.
+    #[expect(dead_code)]
+    #[expect(clippy::too_many_arguments)]
+    fn dispatch_gmc_boot_event(
+        command_id: u32,
+        payload: &[u8],
+        bootloader: &GenericBootloader,
+        gsp_falcon: &Falcon<'_, Gsp>,
+        sec2_falcon: &Falcon<'_, Sec2>,
+        bar: Bar0<'_>,
+        dev: &device::Device,
+        bootloader_app_version: u32,
+        libos_dma_handle: u64,
+    ) -> Result {
+        match command_id {
+            GMCAPI_CMD_EXEC_GENERIC_BOOTLOADER => Self::handle_load_exec_bootloader(
+                payload,
+                bootloader,
+                gsp_falcon,
+                sec2_falcon,
+                bar,
+                dev,
+                bootloader_app_version,
+                libos_dma_handle,
+            ),
+            GMCAPI_CMD_EXEC_HS_BINARY => Self::handle_load_exec_hs_binary(
+                payload,
+                gsp_falcon,
+                sec2_falcon,
+                bar,
+                dev,
+                bootloader_app_version,
+                libos_dma_handle,
+            ),
+            _ => {
+                dev_err!(
+                    dev,
+                    "Unexpected GMC boot event: command_id={:#010x}\n",
+                    command_id
+                );
+                Err(EINVAL)
+            }
+        }
+    }
+
     /// Handle a `GSP_LOAD_EXEC_GENERIC_BOOTLOADER` event.
     ///
     /// The driver does not copy the image the GSP asks for. It writes the descriptor the event
@@ -177,7 +235,6 @@ fn core_resume(
     ///   size this driver mirrors, or the event names a context DMA slot or an aperture that does
     ///   not exist.
     /// - `ETIMEDOUT` if the GSP does not suspend, or the image does not halt, in time.
-    #[expect(dead_code)]
     #[expect(clippy::too_many_arguments)]
     fn handle_load_exec_bootloader(
         payload: &[u8],
@@ -269,7 +326,6 @@ fn handle_load_exec_bootloader(
     /// - `EINVAL` if the payload is shorter than the parameter block, or the ucode id does not
     ///   fit the BROM register field.
     /// - `ETIMEDOUT` if the GSP does not suspend, or the binary does not halt, in time.
-    #[expect(dead_code)]
     fn handle_load_exec_hs_binary(
         payload: &[u8],
         gsp_falcon: &Falcon<'_, Gsp>,
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index 31c0e6351fdc..89482d2648f5 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -1012,6 +1012,16 @@ pub(crate) struct GmcApiHeader {
 /// `GMCAPI_HEADER_COMMAND_ID_MASK`. The remaining byte carries flags.
 const GMCAPI_COMMAND_ID_MASK: u32 = 0x00ff_ffff;
 
+/// GMC command asking the driver to run the generic falcon bootloader against a descriptor the
+/// GSP supplies.
+pub(crate) const GMCAPI_CMD_EXEC_GENERIC_BOOTLOADER: u32 =
+    r000_00::GMCAPI_COMMANDS_GMCAPI_CMD_EXEC_GENERIC_BOOTLOADER;
+
+/// GMC command asking the driver to run a high-security binary the GSP has placed in the
+/// framebuffer.
+pub(crate) const GMCAPI_CMD_EXEC_HS_BINARY: u32 =
+    r000_00::GMCAPI_COMMANDS_GMCAPI_CMD_EXEC_HS_BINARY;
+
 static_assert!(size_of::<GmcApiHeader>() == size_of::<r000_00::GMCAPI_HEADER>());
 static_assert!(
     core::mem::offset_of!(GmcApiHeader, command)
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.