Introduce GpuMm as the centralized GPU memory manager. At this point in the series, GpuMm only owns the PRAMIN window for direct VRAM access; the buddy allocator and TLB manager are added later when those backing types become available.
This provides a clean ownership model where GpuMm provides accessor methods for its components that can be used for memory management operations, and lets follow-on patches (such as the PRAMIN aperture self-tests) reference `self.mm.pramin()` cleanly. Signed-off-by: Joel Fernandes <[email protected]> --- drivers/gpu/nova-core/gpu.rs | 22 +++++++++++++++++ drivers/gpu/nova-core/mm.rs | 46 ++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/nova-core/gpu.rs b/drivers/gpu/nova-core/gpu.rs index d9d1a7417a2e..38544c38d660 100644 --- a/drivers/gpu/nova-core/gpu.rs +++ b/drivers/gpu/nova-core/gpu.rs @@ -25,6 +25,10 @@ commands::GetGspStaticInfoReply, Gsp, // }, + mm::{ + GpuMm, + IntoVramRange, // + }, regs, }; @@ -261,6 +265,8 @@ pub(crate) struct Gpu { gsp_falcon: Falcon<GspFalcon>, /// SEC2 falcon instance, used for GSP boot up and cleanup. sec2_falcon: Falcon<Sec2Falcon>, + /// GPU memory manager owning memory management resources. + mm: Arc<GpuMm>, /// GSP runtime data. Temporarily an empty placeholder. #[pin] gsp: Gsp, @@ -306,6 +312,22 @@ pub(crate) fn new<'a>( ); })?, + // Create GPU memory manager owning memory management resources. + mm: { + // PRAMIN covers all physical VRAM (including GSP-reserved areas + // above the usable region, e.g. the BAR1 page directory). + let pramin_vram_region = (0..gsp_static_info.total_fb_end).into_vram_range(); + Arc::pin_init( + GpuMm::new( + devres_bar.clone(), + pdev.as_ref(), + spec.chipset, + pramin_vram_region, + )?, + GFP_KERNEL, + )? + }, + bar: devres_bar, }) } diff --git a/drivers/gpu/nova-core/mm.rs b/drivers/gpu/nova-core/mm.rs index f425467281d3..5c1941d20d1b 100644 --- a/drivers/gpu/nova-core/mm.rs +++ b/drivers/gpu/nova-core/mm.rs @@ -2,7 +2,7 @@ //! Memory management subsystems for nova-core. -#![expect(dead_code)] +#![allow(dead_code)] /// Implements `From` conversions between a frame-number type and `Bounded<u64, N>`. /// @@ -37,10 +37,52 @@ macro_rules! impl_pfn_bounded { use kernel::{ bitfield, + device, + devres::Devres, num::Bounded, - prelude::*, // + prelude::*, + sync::Arc, // }; +use crate::{ + driver::Bar0, + gpu::Chipset, // +}; + +/// GPU Memory Manager - owns all core MM components. +/// +/// Provides centralized ownership of memory management resources: +/// - [`pramin::Pramin`] for direct VRAM access. +#[pin_data] +pub(crate) struct GpuMm { + #[pin] + pramin: pramin::Pramin, +} + +impl GpuMm { + /// Create a pin-initializer for `GpuMm`. + /// + /// `pramin_vram_region` is the full physical VRAM range (including GSP-reserved + /// areas). PRAMIN window accesses are validated against this range. + pub(crate) fn new( + bar: Arc<Devres<Bar0>>, + dev: &device::Device<device::Bound>, + chipset: Chipset, + pramin_vram_region: Range<VramAddress>, + ) -> Result<impl PinInit<Self>> { + let pramin_init = pramin::Pramin::new(bar, dev, chipset, pramin_vram_region)?; + + Ok(pin_init!(Self { + pramin <- pramin_init, + })) + } + + /// Access the [`pramin::Pramin`]. + pub(crate) fn pramin(&self) -> &pramin::Pramin { + &self.pramin + } +} + bitfield! { /// Physical VRAM address in GPU video memory. pub(crate) struct VramAddress(u64) { -- 2.34.1
