diff options
| -rw-r--r-- | drivers/gpu/nova-core/gsp.rs | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index a045c4189989..04e3976127cc 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -3,6 +3,7 @@ mod boot; use kernel::{ + debugfs, device, dma::{ Coherent, @@ -106,17 +107,23 @@ impl LogBuffer { } } -/// GSP runtime data. -#[pin_data] -pub(crate) struct Gsp { - /// Libos arguments. - pub(crate) libos: Coherent<[LibosMemoryRegionInitArgument]>, +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: Coherent<[LibosMemoryRegionInitArgument]>, + /// Log buffers, optionally exposed via debugfs. + #[pin] + logs: debugfs::Scope<LogBuffers>, /// Command queue. #[pin] pub(crate) cmdq: Cmdq, @@ -130,13 +137,14 @@ impl Gsp { pin_init::pin_init_scope(move || { let dev = pdev.as_ref(); + let loginit = LogBuffer::new(dev)?; + let logintr = LogBuffer::new(dev)?; + let logrm = LogBuffer::new(dev)?; + // Initialise the logging structures. The OpenRM equivalents are in: // _kgspInitLibosLoggingStructures (allocates memory for buffers) // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) Ok(try_pin_init!(Self { - loginit: LogBuffer::new(dev)?, - logintr: LogBuffer::new(dev)?, - logrm: LogBuffer::new(dev)?, cmdq <- Cmdq::new(dev), rmargs: Coherent::init(dev, GFP_KERNEL, GspArgumentsPadded::new(&cmdq))?, libos: { @@ -153,6 +161,29 @@ impl Gsp { libos.into() }, + logs <- { + let log_buffers = LogBuffers { + loginit, + logintr, + logrm, + }; + + #[allow(static_mut_refs)] + // SAFETY: `DEBUGFS_ROOT` is created before driver registration and cleared + // after driver unregistration, so no probe() can race with its modification. + // + // PANIC: `DEBUGFS_ROOT` cannot be `None` here. It is set before driver + // registration and cleared after driver unregistration, so it is always + // `Some` for the entire lifetime that probe() can be called. + let log_parent: &debugfs::Dir = unsafe { crate::DEBUGFS_ROOT.as_ref() } + .expect("DEBUGFS_ROOT not initialized"); + + log_parent.scope(log_buffers, dev.name(), |logs, dir| { + dir.read_binary_file(c"loginit", &logs.loginit.0); + dir.read_binary_file(c"logintr", &logs.logintr.0); + dir.read_binary_file(c"logrm", &logs.logrm.0); + }) + }, })) }) } |
