Implement VmIoOnce for DmaCoherent

This commit is contained in:
Ruihan Li
2024-08-06 00:05:20 +10:00
committed by Tate, Hongliang Tian
parent cda23937dd
commit 3deff2e842

View File

@ -13,10 +13,12 @@ use crate::{
arch::{iommu, mm::tlb_flush_addr_range}, arch::{iommu, mm::tlb_flush_addr_range},
mm::{ mm::{
dma::{dma_type, Daddr, DmaType}, dma::{dma_type, Daddr, DmaType},
io::VmIoOnce,
kspace::{paddr_to_vaddr, KERNEL_PAGE_TABLE}, kspace::{paddr_to_vaddr, KERNEL_PAGE_TABLE},
page_prop::CachePolicy, page_prop::CachePolicy,
HasPaddr, Paddr, Segment, VmIo, VmReader, VmWriter, PAGE_SIZE, HasPaddr, Paddr, PodOnce, Segment, VmIo, VmReader, VmWriter, PAGE_SIZE,
}, },
prelude::*,
}; };
/// A coherent (or consistent) DMA mapping, /// A coherent (or consistent) DMA mapping,
@ -47,7 +49,10 @@ impl DmaCoherent {
/// ///
/// The method fails if any part of the given `vm_segment` /// The method fails if any part of the given `vm_segment`
/// already belongs to a DMA mapping. /// already belongs to a DMA mapping.
pub fn map(vm_segment: Segment, is_cache_coherent: bool) -> Result<Self, DmaError> { pub fn map(
vm_segment: Segment,
is_cache_coherent: bool,
) -> core::result::Result<Self, DmaError> {
let frame_count = vm_segment.nframes(); let frame_count = vm_segment.nframes();
let start_paddr = vm_segment.start_paddr(); let start_paddr = vm_segment.start_paddr();
if !check_and_insert_dma_mapping(start_paddr, frame_count) { if !check_and_insert_dma_mapping(start_paddr, frame_count) {
@ -160,15 +165,29 @@ impl Drop for DmaCoherentInner {
} }
impl VmIo for DmaCoherent { impl VmIo for DmaCoherent {
fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> crate::prelude::Result<()> { fn read_bytes(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
self.inner.vm_segment.read_bytes(offset, buf) self.inner.vm_segment.read_bytes(offset, buf)
} }
fn write_bytes(&self, offset: usize, buf: &[u8]) -> crate::prelude::Result<()> { fn write_bytes(&self, offset: usize, buf: &[u8]) -> Result<()> {
self.inner.vm_segment.write_bytes(offset, buf) self.inner.vm_segment.write_bytes(offset, buf)
} }
} }
impl VmIoOnce for DmaCoherent {
fn read_once<T: PodOnce>(&self, offset: usize) -> Result<T> {
self.inner.vm_segment.reader().skip(offset).read_once()
}
fn write_once<T: PodOnce>(&self, offset: usize, new_val: &T) -> Result<()> {
self.inner
.vm_segment
.writer()
.skip(offset)
.write_once(new_val)
}
}
impl<'a> DmaCoherent { impl<'a> DmaCoherent {
/// Returns a reader to read data from it. /// Returns a reader to read data from it.
pub fn reader(&'a self) -> VmReader<'a> { pub fn reader(&'a self) -> VmReader<'a> {
@ -192,7 +211,7 @@ mod test {
use alloc::vec; use alloc::vec;
use super::*; use super::*;
use crate::{mm::FrameAllocOptions, prelude::*}; use crate::mm::FrameAllocOptions;
#[ktest] #[ktest]
fn map_with_coherent_device() { fn map_with_coherent_device() {