Create read-only debugfs entries for LOGINIT, LOGRM, and LOGINTR, which are the three primary printf logging buffers from GSP-RM. LOGPMU will be added at a later date, as it requires it support for its RPC message first.
This patch uses the `pin_init_scope` feature to create the entries. `pin_init_scope` solves the lifetime issue over the `DEBUGFS_ROOT` reference by delaying its acquisition until the time the entry is actually initialized. Co-developed-by: Alexandre Courbot <[email protected]> Signed-off-by: Alexandre Courbot <[email protected]> Signed-off-by: Timur Tabi <[email protected]> --- drivers/gpu/nova-core/gsp.rs | 42 +++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index 860674dac31e..409ff80f55e6 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -3,6 +3,7 @@ mod boot; use kernel::{ + c_str, debugfs, device, dma::{ @@ -101,17 +102,24 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> { } } -/// GSP runtime data. -#[pin_data] -pub(crate) struct Gsp { - /// Libos arguments. - pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>, +/// Log buffers used by GSP-RM for debug logging. +struct LogBuffers { /// Init log buffer. loginit: LogBuffer, /// Interrupts log buffer. logintr: LogBuffer, /// RM log buffer. logrm: LogBuffer, +} + +/// GSP runtime data. +#[pin_data] +pub(crate) struct Gsp { + /// Libos arguments. + pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>, + /// Log buffers, optionally exposed via debugfs. + #[pin] + logs: debugfs::Scope<LogBuffers>, /// Command queue. pub(crate) cmdq: Cmdq, /// RM arguments. @@ -143,7 +151,9 @@ unsafe impl Sync for LogBuffer {} impl Gsp { // Creates an in-place initializer for a `Gsp` manager for `pdev`. - pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> Result<impl PinInit<Self, Error>> { + pub(crate) fn new<'a>( + pdev: &'a pci::Device<device::Bound>, + ) -> Result<impl PinInit<Self, Error> + 'a> { let dev = pdev.as_ref(); let libos = CoherentAllocation::<LibosMemoryRegionInitArgument>::alloc_coherent( dev, @@ -173,11 +183,27 @@ pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> Result<impl PinInit<Self dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?; dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?; - Ok(try_pin_init!(Self { - libos, + let log_buffers = LogBuffers { loginit, logintr, logrm, + }; + + // Look up nova_core debugfs directory - only create entries if it exists. + // If nova_core doesn't exist, debugfs_dir will be empty and file creation + // becomes a no-op (data is still stored, just not exposed via debugfs). + let debugfs_dir = debugfs::Dir::lookup(c_str!("nova_core"), None) + .unwrap_or_else(debugfs::Dir::empty); + + let logs = debugfs_dir.scope(log_buffers, pdev.name(), |logs, dir| { + dir.read_binary_file(c_str!("loginit"), &logs.loginit); + dir.read_binary_file(c_str!("logintr"), &logs.logintr); + dir.read_binary_file(c_str!("logrm"), &logs.logrm); + }); + + Ok(try_pin_init!(Self { + libos, + logs <- logs, rmargs, cmdq, })) -- 2.52.0
