Migrate to CoherentArray and CoherentObject. This enables removing a few unwrap()s.
Signed-off-by: Eliot Courtney <[email protected]> --- drivers/gpu/nova-core/gsp.rs | 46 ++++++++++++++++++++------------------- drivers/gpu/nova-core/gsp/boot.rs | 10 ++++----- drivers/gpu/nova-core/gsp/cmdq.rs | 24 ++++++++++---------- drivers/gpu/nova-core/gsp/fw.rs | 12 +++------- 4 files changed, 43 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs index 43bc35fd3b55..2513822d43fb 100644 --- a/drivers/gpu/nova-core/gsp.rs +++ b/drivers/gpu/nova-core/gsp.rs @@ -5,13 +5,15 @@ use kernel::{ device, dma::{ - CoherentAllocation, + CoherentArray, + CoherentObject, + CoherentSlice, DmaAddress, // }, + dma_write, pci, prelude::*, - transmute::AsBytes, - try_dma_write, // + transmute::AsBytes, // }; pub(crate) mod cmdq; @@ -74,14 +76,14 @@ fn new(start: DmaAddress) -> Result<Self> { /// then pp points to index into the buffer where the next logging entry will /// be written. Therefore, the logging data is valid if: /// 1 <= pp < sizeof(buffer)/sizeof(u64) -struct LogBuffer(CoherentAllocation<u8>); +struct LogBuffer(CoherentSlice<u8>); impl LogBuffer { /// Creates a new `LogBuffer` mapped on `dev`. fn new(dev: &device::Device<device::Bound>) -> Result<Self> { const NUM_PAGES: usize = RM_LOG_BUFFER_NUM_PAGES; - let mut obj = Self(CoherentAllocation::<u8>::alloc_coherent( + let mut obj = Self(CoherentSlice::<u8>::alloc_coherent( dev, NUM_PAGES * GSP_PAGE_SIZE, GFP_KERNEL | __GFP_ZERO, @@ -100,11 +102,14 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> { } } +/// Number of `LibosMemoryRegionInitArgument` entries that fit in a GSP page. +const LIBOS_REGION_SIZE: usize = GSP_PAGE_SIZE / size_of::<LibosMemoryRegionInitArgument>(); + /// GSP runtime data. #[pin_data] pub(crate) struct Gsp { /// Libos arguments. - pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>, + pub(crate) libos: CoherentArray<LibosMemoryRegionInitArgument, LIBOS_REGION_SIZE>, /// Init log buffer. loginit: LogBuffer, /// Interrupts log buffer. @@ -114,40 +119,37 @@ pub(crate) struct Gsp { /// Command queue. pub(crate) cmdq: Cmdq, /// RM arguments. - rmargs: CoherentAllocation<GspArgumentsCached>, + rmargs: CoherentObject<GspArgumentsCached>, } 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>> { let dev = pdev.as_ref(); - let libos = CoherentAllocation::<LibosMemoryRegionInitArgument>::alloc_coherent( - dev, - GSP_PAGE_SIZE / size_of::<LibosMemoryRegionInitArgument>(), - GFP_KERNEL | __GFP_ZERO, - )?; + let libos = + CoherentArray::<LibosMemoryRegionInitArgument, LIBOS_REGION_SIZE>::alloc_coherent( + dev, + GFP_KERNEL | __GFP_ZERO, + )?; // Initialise the logging structures. The OpenRM equivalents are in: // _kgspInitLibosLoggingStructures (allocates memory for buffers) // kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array) let loginit = LogBuffer::new(dev)?; - try_dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0))?; + dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0)); let logintr = LogBuffer::new(dev)?; - try_dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0))?; + dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0)); let logrm = LogBuffer::new(dev)?; - try_dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?; + dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0)); let cmdq = Cmdq::new(dev)?; - let rmargs = CoherentAllocation::<GspArgumentsCached>::alloc_coherent( - dev, - 1, - GFP_KERNEL | __GFP_ZERO, - )?; - try_dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?; - try_dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?; + let rmargs = + CoherentObject::<GspArgumentsCached>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?; + dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq)); + dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs)); Ok(try_pin_init!(Self { libos, diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs index 69e2fb064220..7888a39356f3 100644 --- a/drivers/gpu/nova-core/gsp/boot.rs +++ b/drivers/gpu/nova-core/gsp/boot.rs @@ -2,12 +2,12 @@ use kernel::{ device, - dma::CoherentAllocation, + dma::CoherentObject, + dma_write, io::poll::read_poll_timeout, pci, prelude::*, - time::Delta, - try_dma_write, // + time::Delta, // }; use crate::{ @@ -159,8 +159,8 @@ pub(crate) fn boot( )?; let wpr_meta = - CoherentAllocation::<GspFwWprMeta>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; - try_dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?; + CoherentObject::<GspFwWprMeta>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?; + dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout)); self.cmdq .send_command(bar, commands::SetSystemInfo::new(pdev))?; diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs index 9c94f4c6ff6d..845c9e176b93 100644 --- a/drivers/gpu/nova-core/gsp/cmdq.rs +++ b/drivers/gpu/nova-core/gsp/cmdq.rs @@ -12,9 +12,10 @@ use kernel::{ device, dma::{ - CoherentAllocation, + CoherentObject, DmaAddress, // }, + dma_write, io::poll::read_poll_timeout, prelude::*, sync::aref::ARef, @@ -22,8 +23,7 @@ transmute::{ AsBytes, FromBytes, // - }, - try_dma_write, // + }, // }; use crate::{ @@ -191,7 +191,7 @@ unsafe impl FromBytes for GspMem {} /// pointer and the GSP read pointer. This region is returned by [`Self::driver_write_area`]. /// * The driver owns (i.e. can read from) the part of the GSP message queue between the CPU read /// pointer and the GSP write pointer. This region is returned by [`Self::driver_read_area`]. -struct DmaGspMem(CoherentAllocation<GspMem>); +struct DmaGspMem(CoherentObject<GspMem>); impl DmaGspMem { /// Allocate a new instance and map it for `dev`. @@ -199,13 +199,11 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> { const MSGQ_SIZE: u32 = num::usize_into_u32::<{ size_of::<Msgq>() }>(); const RX_HDR_OFF: u32 = num::usize_into_u32::<{ mem::offset_of!(Msgq, rx) }>(); - let gsp_mem = - CoherentAllocation::<GspMem>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?; - try_dma_write!(gsp_mem[0].ptes = PteArray::new(gsp_mem.dma_handle())?)?; - try_dma_write!( - gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES) - )?; - try_dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new())?; + let gsp_mem = CoherentObject::<GspMem>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?; + let ptes = PteArray::new(gsp_mem.dma_handle())?; + dma_write!(gsp_mem[0].ptes = ptes); + dma_write!(gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES)); + dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new()); Ok(Self(gsp_mem)) } @@ -223,7 +221,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> { // - The `CoherentAllocation` contains exactly one object. // - We will only access the driver-owned part of the shared memory. // - Per the safety statement of the function, no concurrent access will be performed. - let gsp_mem = &mut unsafe { self.0.try_as_slice_mut(0, 1) }.unwrap()[0]; + let gsp_mem = &mut unsafe { self.0.as_slice_mut::<0, 1>() }[0]; // PANIC: per the invariant of `cpu_write_ptr`, `tx` is `<= MSGQ_NUM_PAGES`. let (before_tx, after_tx) = gsp_mem.cpuq.msgq.data.split_at_mut(tx); @@ -258,7 +256,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> { // - The `CoherentAllocation` contains exactly one object. // - We will only access the driver-owned part of the shared memory. // - Per the safety statement of the function, no concurrent access will be performed. - let gsp_mem = &unsafe { self.0.try_as_slice(0, 1) }.unwrap()[0]; + let gsp_mem = &unsafe { self.0.as_slice::<0, 1>() }[0]; // PANIC: per the invariant of `cpu_read_ptr`, `xx` is `<= MSGQ_NUM_PAGES`. let (before_rx, after_rx) = gsp_mem.gspq.msgq.data.split_at(rx); diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs index caeb0d251fe5..1877b727cc22 100644 --- a/drivers/gpu/nova-core/gsp/fw.rs +++ b/drivers/gpu/nova-core/gsp/fw.rs @@ -9,17 +9,14 @@ use core::ops::Range; use kernel::{ - dma::CoherentAllocation, + dma::CoherentSlice, fmt, prelude::*, ptr::{ Alignable, Alignment, // }, - sizes::{ - SZ_128K, - SZ_1M, // - }, + sizes::{SZ_128K, SZ_1M}, transmute::{ AsBytes, FromBytes, // @@ -652,10 +649,7 @@ unsafe impl AsBytes for LibosMemoryRegionInitArgument {} unsafe impl FromBytes for LibosMemoryRegionInitArgument {} impl LibosMemoryRegionInitArgument { - pub(crate) fn new<A: AsBytes + FromBytes>( - name: &'static str, - obj: &CoherentAllocation<A>, - ) -> Self { + pub(crate) fn new<A: AsBytes + FromBytes>(name: &'static str, obj: &CoherentSlice<A>) -> Self { /// Generates the `ID8` identifier required for some GSP objects. fn id8(name: &str) -> u64 { let mut bytes = [0u8; core::mem::size_of::<u64>()]; -- 2.52.0
