[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