mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-26 10:53:25 +00:00
Implement VmIoOnce
for DmaCoherent
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
cda23937dd
commit
3deff2e842
@ -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() {
|
||||||
|
Reference in New Issue
Block a user