mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 16:53:20 -04:00
rust: dma: rename dma_handle to dma_address
The `dma_handle` naming is inherited from the C API, but what this really describes is the device DMA address; everything named `dma_handle` is actually a `dma_addr_t`. This naming introduces some confusion on the Rust API side, as handles are supposed to be opaque tokens, yet we were doing address computation on values returned by `dma_handle`. Rename `dma_handle` to `dma_address` while nova-core is still its only user. Suggested-by: John Hubbard <jhubbard@nvidia.com> Suggested-by: Danilo Krummrich <dakr@kernel.org> Link: https://lore.kernel.org/all/DK75LUA4NLGI.3P29AIZQE20V2@kernel.org/ Signed-off-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: Robin Murphy <robin.murphy@arm.com> Link: https://patch.msgid.link/20260805-falcon-dma-projections-v2-2-4cc9f3f13ee9@nvidia.com [ Rebase and fix up build failures due to newly introduced dma_handle() calls. - Danilo ] Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
committed by
Danilo Krummrich
parent
d1dc8faf11
commit
91645a52eb
@@ -499,7 +499,7 @@ pub(crate) fn pio_load<F: FalconFirmware<Target = E> + FalconPioLoadable>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Perform a DMA write according to `load_offsets` from `dma_handle` into the falcon's
|
||||
/// Perform a DMA write according to `load_offsets` from `dma_obj` into the falcon's
|
||||
/// `target_mem`.
|
||||
///
|
||||
/// `sec` is set if the loaded firmware is expected to run in secure mode.
|
||||
@@ -514,14 +514,14 @@ fn dma_wr(
|
||||
// For IMEM, we want to use the start offset as a virtual address tag for each page, since
|
||||
// code addresses in the firmware (and the boot vector) are virtual.
|
||||
//
|
||||
// For DMEM we can fold the start offset into the DMA handle.
|
||||
// For DMEM we can fold the start offset into the DMA address.
|
||||
let (src_start, dma_start) = match target_mem {
|
||||
FalconMem::ImemSecure | FalconMem::ImemNonSecure => {
|
||||
(load_offsets.src_start, dma_obj.dma_handle())
|
||||
(load_offsets.src_start, dma_obj.dma_address())
|
||||
}
|
||||
FalconMem::Dmem => (
|
||||
0,
|
||||
dma_obj.dma_handle() + DmaAddress::from(load_offsets.src_start),
|
||||
dma_obj.dma_address() + DmaAddress::from(load_offsets.src_start),
|
||||
),
|
||||
};
|
||||
if dma_start % DmaAddress::from(DMA_LEN) > 0 {
|
||||
|
||||
@@ -61,7 +61,7 @@ pub(crate) fn register(
|
||||
) -> Result<Self> {
|
||||
let page = CoherentHandle::alloc(dev, kernel::page::PAGE_SIZE, GFP_KERNEL)?;
|
||||
|
||||
hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_handle())?;
|
||||
hal::fb_hal(chipset).write_sysmem_flush_page(bar, page.dma_address())?;
|
||||
|
||||
Ok(Self {
|
||||
chipset,
|
||||
@@ -76,7 +76,7 @@ impl Drop for SysmemFlush<'_> {
|
||||
fn drop(&mut self) {
|
||||
let hal = hal::fb_hal(self.chipset);
|
||||
|
||||
if hal.read_sysmem_flush_page(self.bar) == self.page.dma_handle() {
|
||||
if hal.read_sysmem_flush_page(self.bar) == self.page.dma_address() {
|
||||
let _ = hal.write_sysmem_flush_page(self.bar, 0).inspect_err(|e| {
|
||||
dev_warn!(
|
||||
&self.device,
|
||||
|
||||
@@ -190,9 +190,11 @@ pub(crate) fn run<T>(
|
||||
) -> Result {
|
||||
sec2_falcon.reset()?;
|
||||
sec2_falcon.load(self)?;
|
||||
let wpr_handle = wpr_meta.dma_handle();
|
||||
let (mbox0, mbox1) =
|
||||
sec2_falcon.boot(Some(wpr_handle as u32), Some((wpr_handle >> 32) as u32))?;
|
||||
let wpr_dma_address = wpr_meta.dma_address();
|
||||
let (mbox0, mbox1) = sec2_falcon.boot(
|
||||
Some(wpr_dma_address as u32),
|
||||
Some((wpr_dma_address >> 32) as u32),
|
||||
)?;
|
||||
dev_dbg!(dev, "SEC2 MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
|
||||
|
||||
if mbox0 != 0 {
|
||||
|
||||
@@ -191,7 +191,7 @@ pub(crate) fn new(
|
||||
reserved: [0; 4],
|
||||
signature: [0; 4],
|
||||
ctx_dma: FALCON_DMAIDX_PHYS_SYS_NCOH,
|
||||
code_dma_base: firmware_dma.dma_handle(),
|
||||
code_dma_base: firmware_dma.dma_address(),
|
||||
// `dst_start` is also valid as the source offset since the firmware DMA object is
|
||||
// a mirror image of the target IMEM layout.
|
||||
non_sec_code_off: imem_ns.dst_start,
|
||||
@@ -203,7 +203,7 @@ pub(crate) fn new(
|
||||
code_entry_point: 0,
|
||||
// Start of data section is the added padding + the DMEM `src_start` field.
|
||||
data_dma_base: firmware_dma
|
||||
.dma_handle()
|
||||
.dma_address()
|
||||
.checked_add(u64::from_safe_cast(align_padding))
|
||||
.and_then(|offset| offset.checked_add(dmem.src_start.into()))
|
||||
.ok_or(EOVERFLOW)?,
|
||||
|
||||
@@ -140,9 +140,9 @@ pub(crate) fn new<'a>(
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the DMA handle of the radix3 level 0 page table.
|
||||
pub(crate) fn radix3_dma_handle(&self) -> DmaAddress {
|
||||
self.level0.dma_handle()
|
||||
/// Returns the DMA address of the radix3 level 0 page table.
|
||||
pub(crate) fn radix3_dma_address(&self) -> DmaAddress {
|
||||
self.level0.dma_address()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -296,12 +296,12 @@ fn new<'a>(
|
||||
.chain(move |msg| {
|
||||
msg.cot.version = version;
|
||||
msg.cot.size = size;
|
||||
msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_handle();
|
||||
msg.cot.gsp_fmc_sysmem_offset = fsp_fw.fmc_image.dma_address();
|
||||
msg.cot.frts_vidmem_offset = frts_vidmem_offset;
|
||||
msg.cot.frts_vidmem_size = frts_size;
|
||||
// frts_sysmem_* are left at zero because this path places FRTS in vidmem. The sysmem
|
||||
// fields point to an FRTS buffer in sysmem instead, for systems without VRAM.
|
||||
msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_handle();
|
||||
msg.cot.gsp_boot_args_sysmem_offset = args.fmc_boot_params.dma_address();
|
||||
msg.cot.sigs = *fsp_fw.fmc_sigs;
|
||||
|
||||
Ok(())
|
||||
@@ -362,7 +362,7 @@ pub(crate) fn new(
|
||||
libos: &'a Coherent<[LibosMemoryRegionInitArgument]>,
|
||||
resume: bool,
|
||||
) -> Result<Self> {
|
||||
let init = GspFmcBootParams::new(wpr_meta.dma_handle(), libos.dma_handle());
|
||||
let init = GspFmcBootParams::new(wpr_meta.dma_address(), libos.dma_address());
|
||||
|
||||
Ok(Self {
|
||||
chipset,
|
||||
|
||||
@@ -122,7 +122,7 @@ impl LogBuffer {
|
||||
fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
|
||||
let obj = Self(Coherent::zeroed(dev, GFP_KERNEL)?);
|
||||
|
||||
let start_addr = obj.0.dma_handle();
|
||||
let start_addr = obj.0.dma_address();
|
||||
|
||||
let pte_view = io_project!(
|
||||
obj.0,
|
||||
|
||||
@@ -243,7 +243,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
|
||||
gsp_mem.cpuq.rx = MsgqRxHeader::new();
|
||||
|
||||
let gsp_mem: Coherent<_> = gsp_mem.into();
|
||||
PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_handle())?;
|
||||
PteArray::init(io_project!(gsp_mem, .ptes), gsp_mem.dma_address())?;
|
||||
|
||||
Ok(Self(gsp_mem))
|
||||
}
|
||||
@@ -487,8 +487,8 @@ pub(crate) struct Cmdq {
|
||||
/// Inner mutex-protected state.
|
||||
#[pin]
|
||||
inner: Mutex<CmdqInner>,
|
||||
/// DMA handle of the command queue's shared memory region.
|
||||
pub(super) dma_handle: DmaAddress,
|
||||
/// DMA address of the command queue's shared memory region.
|
||||
pub(super) dma_addr: DmaAddress,
|
||||
}
|
||||
|
||||
impl Cmdq {
|
||||
@@ -517,7 +517,7 @@ pub(crate) fn new(dev: &device::Device<device::Bound>) -> impl PinInit<Self, Err
|
||||
let gsp_mem = DmaGspMem::new(dev)?;
|
||||
|
||||
Ok(try_pin_init!(Self {
|
||||
dma_handle: gsp_mem.0.dma_handle(),
|
||||
dma_addr: gsp_mem.0.dma_address(),
|
||||
inner <- new_mutex!(CmdqInner {
|
||||
dev: dev.into(),
|
||||
gsp_mem,
|
||||
|
||||
@@ -186,16 +186,16 @@ pub(crate) fn from_ranges<'a>(
|
||||
// CAST: we want to store the bits of `GSP_FW_WPR_META_MAGIC` unmodified.
|
||||
magic: bindings::GSP_FW_WPR_META_MAGIC as u64,
|
||||
revision: u64::from(bindings::GSP_FW_WPR_META_REVISION),
|
||||
sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_handle(),
|
||||
sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_address(),
|
||||
sizeOfRadix3Elf: u64::from_safe_cast(gsp_firmware.size),
|
||||
sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_handle(),
|
||||
sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_address(),
|
||||
sizeOfBootloader: u64::from_safe_cast(gsp_firmware.bootloader.ucode.size()),
|
||||
bootloaderCodeOffset: u64::from(gsp_firmware.bootloader.code_offset),
|
||||
bootloaderDataOffset: u64::from(gsp_firmware.bootloader.data_offset),
|
||||
bootloaderManifestOffset: u64::from(gsp_firmware.bootloader.manifest_offset),
|
||||
__bindgen_anon_1: GspFwWprMetaBootResumeInfo {
|
||||
__bindgen_anon_1: GspFwWprMetaBootInfo {
|
||||
sysmemAddrOfSignature: gsp_firmware.signatures.dma_handle(),
|
||||
sysmemAddrOfSignature: gsp_firmware.signatures.dma_address(),
|
||||
sizeOfSignature: u64::from_safe_cast(gsp_firmware.signatures.size()),
|
||||
},
|
||||
},
|
||||
@@ -241,16 +241,16 @@ pub(crate) fn from_sizes<'a>(
|
||||
// CAST: we want to store the bits of `GSP_FW_WPR_META_MAGIC` unmodified.
|
||||
magic: bindings::GSP_FW_WPR_META_MAGIC as u64,
|
||||
revision: u64::from(bindings::GSP_FW_WPR_META_REVISION),
|
||||
sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_handle(),
|
||||
sysmemAddrOfRadix3Elf: gsp_firmware.radix3_dma_address(),
|
||||
sizeOfRadix3Elf: u64::from_safe_cast(gsp_firmware.size),
|
||||
sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_handle(),
|
||||
sysmemAddrOfBootloader: gsp_firmware.bootloader.ucode.dma_address(),
|
||||
sizeOfBootloader: u64::from_safe_cast(gsp_firmware.bootloader.ucode.size()),
|
||||
bootloaderCodeOffset: u64::from(gsp_firmware.bootloader.code_offset),
|
||||
bootloaderDataOffset: u64::from(gsp_firmware.bootloader.data_offset),
|
||||
bootloaderManifestOffset: u64::from(gsp_firmware.bootloader.manifest_offset),
|
||||
__bindgen_anon_1: GspFwWprMetaBootResumeInfo {
|
||||
__bindgen_anon_1: GspFwWprMetaBootInfo {
|
||||
sysmemAddrOfSignature: gsp_firmware.signatures.dma_handle(),
|
||||
sysmemAddrOfSignature: gsp_firmware.signatures.dma_address(),
|
||||
sizeOfSignature: u64::from_safe_cast(gsp_firmware.signatures.size()),
|
||||
},
|
||||
},
|
||||
@@ -680,7 +680,7 @@ fn id8(name: &str) -> u64 {
|
||||
|
||||
let init_inner = init!(bindings::LibosMemoryRegionInitArgument {
|
||||
id8: id8(name),
|
||||
pa: obj.dma_handle(),
|
||||
pa: obj.dma_address(),
|
||||
size: num::usize_as_u64(obj.size()),
|
||||
kind: num::u32_into_u8::<
|
||||
{ bindings::LibosMemoryRegionKind_LIBOS_MEMORY_REGION_CONTIGUOUS },
|
||||
@@ -946,7 +946,7 @@ impl MessageQueueInitArguments {
|
||||
/// Creates a new init arguments structure for `cmdq`.
|
||||
fn new(cmdq: &Cmdq) -> impl Init<Self> + '_ {
|
||||
init!(MessageQueueInitArguments {
|
||||
sharedMemPhysAddr: cmdq.dma_handle,
|
||||
sharedMemPhysAddr: cmdq.dma_addr,
|
||||
pageTableEntryCount: num::usize_into_u32::<{ Cmdq::NUM_PTES }>(),
|
||||
cmdQueueOffset: num::usize_as_u64(Cmdq::CMDQ_OFFSET),
|
||||
statQueueOffset: num::usize_as_u64(Cmdq::STATQ_OFFSET),
|
||||
|
||||
@@ -64,7 +64,7 @@ fn lockdown_released_or_error(
|
||||
// boot. If the address is still there, keep polling rather than treating it as an error.
|
||||
// Any other non-zero mailbox0 value is a GSP-FMC error code.
|
||||
if self.mbox0 != 0 {
|
||||
return self.combined_addr() != fmc_boot_params.dma_handle();
|
||||
return self.combined_addr() != fmc_boot_params.dma_address();
|
||||
}
|
||||
|
||||
!gsp_falcon.riscv_branch_privilege_lockdown()
|
||||
|
||||
@@ -294,9 +294,11 @@ fn boot(
|
||||
}
|
||||
|
||||
gsp_falcon.reset()?;
|
||||
let libos_handle = gsp.libos.dma_handle();
|
||||
let (mbox0, mbox1) =
|
||||
gsp_falcon.boot(Some(libos_handle as u32), Some((libos_handle >> 32) as u32))?;
|
||||
let libos_dma_address = gsp.libos.dma_address();
|
||||
let (mbox0, mbox1) = gsp_falcon.boot(
|
||||
Some(libos_dma_address as u32),
|
||||
Some((libos_dma_address >> 32) as u32),
|
||||
)?;
|
||||
dev_dbg!(dev, "GSP MBOX0: {:#x}, MBOX1: {:#x}\n", mbox0, mbox1);
|
||||
|
||||
dev_dbg!(
|
||||
|
||||
@@ -234,12 +234,12 @@ fn run(&self, seq: &GspSequencer<'_>) -> Result {
|
||||
// Reset the GSP to prepare it for resuming.
|
||||
seq.gsp_falcon.reset()?;
|
||||
|
||||
let libos_dma_handle = seq.libos.dma_handle();
|
||||
let libos_dma_address = seq.libos.dma_address();
|
||||
|
||||
// Write the libOS DMA handle to GSP mailboxes.
|
||||
// Write the libOS DMA address to GSP mailboxes.
|
||||
seq.gsp_falcon.write_mailboxes(
|
||||
Some(libos_dma_handle as u32),
|
||||
Some((libos_dma_handle >> 32) as u32),
|
||||
Some(libos_dma_address as u32),
|
||||
Some((libos_dma_address >> 32) as u32),
|
||||
);
|
||||
|
||||
// Start the SEC2 falcon which will trigger GSP-RM to resume on the GSP.
|
||||
|
||||
@@ -585,7 +585,7 @@ fn from(value: CoherentBox<T>) -> Self {
|
||||
/// # Invariants
|
||||
///
|
||||
/// - For the lifetime of an instance of [`Coherent`], the `cpu_addr` is a valid pointer
|
||||
/// to an allocated region of coherent memory and `dma_handle` is the DMA address base of the
|
||||
/// to an allocated region of coherent memory and `dma_addr` is the DMA address base of the
|
||||
/// region.
|
||||
/// - The size in bytes of the allocation is equal to size information via pointer.
|
||||
// TODO
|
||||
@@ -602,7 +602,7 @@ fn from(value: CoherentBox<T>) -> Self {
|
||||
// entire `Coherent` including the allocated memory itself.
|
||||
pub struct Coherent<T: KnownSize + ?Sized> {
|
||||
dev: ARef<device::Device>,
|
||||
dma_handle: DmaAddress,
|
||||
dma_addr: DmaAddress,
|
||||
cpu_addr: NonNull<T>,
|
||||
dma_attrs: Attrs,
|
||||
}
|
||||
@@ -627,11 +627,10 @@ pub fn as_mut_ptr(&self) -> *mut T {
|
||||
self.cpu_addr.as_ptr()
|
||||
}
|
||||
|
||||
/// Returns a DMA handle which may be given to the device as the DMA address base of
|
||||
/// the region.
|
||||
/// Returns a DMA address which may be given to the device as the base of the region.
|
||||
#[inline]
|
||||
pub fn dma_handle(&self) -> DmaAddress {
|
||||
self.dma_handle
|
||||
pub fn dma_address(&self) -> DmaAddress {
|
||||
self.dma_addr
|
||||
}
|
||||
|
||||
/// Returns a reference to the data in the region.
|
||||
@@ -678,13 +677,13 @@ fn alloc_with_attrs(
|
||||
);
|
||||
}
|
||||
|
||||
let mut dma_handle = 0;
|
||||
let mut dma_addr = 0;
|
||||
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
|
||||
let addr = unsafe {
|
||||
bindings::dma_alloc_attrs(
|
||||
dev.as_raw(),
|
||||
core::mem::size_of::<T>(),
|
||||
&mut dma_handle,
|
||||
&mut dma_addr,
|
||||
gfp_flags.as_raw(),
|
||||
dma_attrs.as_raw(),
|
||||
)
|
||||
@@ -696,7 +695,7 @@ fn alloc_with_attrs(
|
||||
// - We also hold a refcounted reference to the device.
|
||||
Ok(Self {
|
||||
dev: dev.into(),
|
||||
dma_handle,
|
||||
dma_addr,
|
||||
cpu_addr,
|
||||
dma_attrs,
|
||||
})
|
||||
@@ -795,13 +794,13 @@ fn alloc_slice_with_attrs(
|
||||
}
|
||||
|
||||
let size = core::mem::size_of::<T>().checked_mul(len).ok_or(ENOMEM)?;
|
||||
let mut dma_handle = 0;
|
||||
let mut dma_addr = 0;
|
||||
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
|
||||
let addr = unsafe {
|
||||
bindings::dma_alloc_attrs(
|
||||
dev.as_raw(),
|
||||
size,
|
||||
&mut dma_handle,
|
||||
&mut dma_addr,
|
||||
gfp_flags.as_raw(),
|
||||
dma_attrs.as_raw(),
|
||||
)
|
||||
@@ -813,7 +812,7 @@ fn alloc_slice_with_attrs(
|
||||
// - We also hold a refcounted reference to the device.
|
||||
Ok(Coherent {
|
||||
dev: dev.into(),
|
||||
dma_handle,
|
||||
dma_addr,
|
||||
cpu_addr,
|
||||
dma_attrs,
|
||||
})
|
||||
@@ -927,14 +926,14 @@ impl<T: KnownSize + ?Sized> Drop for Coherent<T> {
|
||||
fn drop(&mut self) {
|
||||
let size = T::size(self.cpu_addr.as_ptr());
|
||||
// SAFETY: Device pointer is guaranteed as valid by the type invariant on `Device`.
|
||||
// The cpu address, and the dma handle are valid due to the type invariants on
|
||||
// The cpu address, and the dma address are valid due to the type invariants on
|
||||
// `Coherent`.
|
||||
unsafe {
|
||||
bindings::dma_free_attrs(
|
||||
self.dev.as_raw(),
|
||||
size,
|
||||
self.cpu_addr.as_ptr().cast(),
|
||||
self.dma_handle,
|
||||
self.dma_addr,
|
||||
self.dma_attrs.as_raw(),
|
||||
)
|
||||
}
|
||||
@@ -989,13 +988,13 @@ fn write_to_slice(
|
||||
///
|
||||
/// - `cpu_handle` holds the opaque handle returned by `dma_alloc_attrs` with
|
||||
/// `DMA_ATTR_NO_KERNEL_MAPPING` set, and is only valid for passing back to `dma_free_attrs`.
|
||||
/// - `dma_handle` is the corresponding bus address for device DMA.
|
||||
/// - `dma_addr` is the corresponding bus address for device DMA.
|
||||
/// - `size` is the allocation size in bytes as passed to `dma_alloc_attrs`.
|
||||
/// - `dma_attrs` contains the attributes used for the allocation, always including
|
||||
/// `DMA_ATTR_NO_KERNEL_MAPPING`.
|
||||
pub struct CoherentHandle {
|
||||
dev: ARef<device::Device>,
|
||||
dma_handle: DmaAddress,
|
||||
dma_addr: DmaAddress,
|
||||
cpu_handle: NonNull<c_void>,
|
||||
size: usize,
|
||||
dma_attrs: Attrs,
|
||||
@@ -1019,13 +1018,13 @@ pub fn alloc_with_attrs(
|
||||
}
|
||||
|
||||
let dma_attrs = dma_attrs | Attrs(bindings::DMA_ATTR_NO_KERNEL_MAPPING);
|
||||
let mut dma_handle = 0;
|
||||
let mut dma_addr = 0;
|
||||
// SAFETY: `dev.as_raw()` is valid by the type invariant on `device::Device`.
|
||||
let cpu_handle = unsafe {
|
||||
bindings::dma_alloc_attrs(
|
||||
dev.as_raw(),
|
||||
size,
|
||||
&mut dma_handle,
|
||||
&mut dma_addr,
|
||||
gfp_flags.as_raw(),
|
||||
dma_attrs.as_raw(),
|
||||
)
|
||||
@@ -1034,11 +1033,11 @@ pub fn alloc_with_attrs(
|
||||
let cpu_handle = NonNull::new(cpu_handle).ok_or(ENOMEM)?;
|
||||
|
||||
// INVARIANT: `cpu_handle` is the opaque handle from a successful `dma_alloc_attrs` call
|
||||
// with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_handle` is the corresponding DMA address,
|
||||
// with `DMA_ATTR_NO_KERNEL_MAPPING`, `dma_addr` is the corresponding DMA address,
|
||||
// and we hold a refcounted reference to the device.
|
||||
Ok(Self {
|
||||
dev: dev.into(),
|
||||
dma_handle,
|
||||
dma_addr,
|
||||
cpu_handle,
|
||||
size,
|
||||
dma_attrs,
|
||||
@@ -1055,12 +1054,12 @@ pub fn alloc(
|
||||
Self::alloc_with_attrs(dev, size, gfp_flags, Attrs(0))
|
||||
}
|
||||
|
||||
/// Returns the DMA handle for this allocation.
|
||||
/// Returns the DMA address for this allocation.
|
||||
///
|
||||
/// This address can be programmed into device hardware for DMA access.
|
||||
#[inline]
|
||||
pub fn dma_handle(&self) -> DmaAddress {
|
||||
self.dma_handle
|
||||
pub fn dma_address(&self) -> DmaAddress {
|
||||
self.dma_addr
|
||||
}
|
||||
|
||||
/// Returns the size in bytes of this allocation.
|
||||
@@ -1079,28 +1078,29 @@ fn drop(&mut self) {
|
||||
self.dev.as_raw(),
|
||||
self.size,
|
||||
self.cpu_handle.as_ptr(),
|
||||
self.dma_handle,
|
||||
self.dma_addr,
|
||||
self.dma_attrs.as_raw(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// SAFETY: `CoherentHandle` only holds a device reference, a DMA handle, an opaque CPU handle,
|
||||
// SAFETY: `CoherentHandle` only holds a device reference, a DMA address, an opaque CPU handle,
|
||||
// and a size. None of these are tied to a specific thread.
|
||||
unsafe impl Send for CoherentHandle {}
|
||||
|
||||
// SAFETY: `CoherentHandle` provides no CPU access to the underlying allocation. The only
|
||||
// operations on `&CoherentHandle` are reading the DMA handle and size, both of which are
|
||||
// operations on `&CoherentHandle` are reading the DMA address and size, both of which are
|
||||
// plain `Copy` values.
|
||||
unsafe impl Sync for CoherentHandle {}
|
||||
|
||||
/// View type for `Coherent`.
|
||||
///
|
||||
/// This is same as [`SysMem`] but with additional information that allows handing out a DMA handle.
|
||||
/// This is same as [`SysMem`] but with additional information that allows handing out a DMA
|
||||
/// address.
|
||||
pub struct CoherentView<'a, T: ?Sized> {
|
||||
cpu_addr: SysMem<'a, T>,
|
||||
dma_handle: DmaAddress,
|
||||
dma_addr: DmaAddress,
|
||||
}
|
||||
|
||||
impl<T: ?Sized> Copy for CoherentView<'_, T> {}
|
||||
@@ -1112,16 +1112,16 @@ fn clone(&self) -> Self {
|
||||
}
|
||||
|
||||
impl<'a, T: ?Sized> CoherentView<'a, T> {
|
||||
/// Erase the DMA handle information and obtain a [`SysMem`] view of the same memory region.
|
||||
/// Erase the DMA address information and obtain a [`SysMem`] view of the same memory region.
|
||||
#[inline]
|
||||
pub fn as_sys_mem(self) -> SysMem<'a, T> {
|
||||
self.cpu_addr
|
||||
}
|
||||
|
||||
/// Returns a DMA handle which may be given to the device as the DMA address base of the region.
|
||||
/// Returns the DMA address which may be given to the device as base of the region.
|
||||
#[inline]
|
||||
pub fn dma_handle(self) -> DmaAddress {
|
||||
self.dma_handle
|
||||
pub fn dma_address(self) -> DmaAddress {
|
||||
self.dma_addr
|
||||
}
|
||||
|
||||
/// Returns a reference to the data in the region.
|
||||
@@ -1174,9 +1174,9 @@ unsafe fn project_view<'a, T: ?Sized + KnownSize, U: ?Sized + KnownSize>(
|
||||
) -> Self::View<'a, U> {
|
||||
let offset = ptr.addr() - view.cpu_addr.as_ptr().addr();
|
||||
// CAST: The offset DMA address can never overflow.
|
||||
let dma_handle = view.dma_handle + offset as DmaAddress;
|
||||
let dma_addr = view.dma_addr + offset as DmaAddress;
|
||||
CoherentView {
|
||||
dma_handle,
|
||||
dma_addr,
|
||||
// SAFETY: Per safety requirement.
|
||||
cpu_addr: unsafe { SysMemBackend::project_view(view.cpu_addr, ptr) },
|
||||
}
|
||||
@@ -1241,7 +1241,7 @@ fn as_view(self) -> CoherentView<'a, Self::Target> {
|
||||
CoherentView {
|
||||
// SAFETY: `cpu_addr` is valid and aligned kernel accessible memory.
|
||||
cpu_addr: unsafe { SysMem::new(self.cpu_addr.as_ptr()) },
|
||||
dma_handle: self.dma_handle,
|
||||
dma_addr: self.dma_addr,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user