Extend Safeptr to support DmaStream

This commit is contained in:
Jianfeng Jiang
2024-04-28 10:41:18 +00:00
committed by Tate, Hongliang Tian
parent 345ab8f838
commit 2256f6ae8a
2 changed files with 27 additions and 46 deletions

View File

@ -13,7 +13,7 @@ use aster_frame::{
offset_of, offset_of,
sync::{RwLock, SpinLock}, sync::{RwLock, SpinLock},
trap::TrapFrame, trap::TrapFrame,
vm::{Daddr, DmaDirection, DmaStream, HasDaddr, VmAllocOptions, VmIo, VmReader, PAGE_SIZE}, vm::{DmaDirection, DmaStream, HasDaddr, VmAllocOptions, VmIo, PAGE_SIZE},
}; };
use aster_input::{ use aster_input::{
key::{Key, KeyStatus}, key::{Key, KeyStatus},
@ -153,9 +153,9 @@ impl InputDevice {
// one interrupt may contain several input events, so it should loop // one interrupt may contain several input events, so it should loop
while let Ok((token, _)) = event_queue.pop_used() { while let Ok((token, _)) = event_queue.pop_used() {
debug_assert!(token < QUEUE_SIZE); debug_assert!(token < QUEUE_SIZE);
let event_buf = self.event_table.get(token as usize); let ptr = self.event_table.get(token as usize);
let res = handle_event(&event_buf); let res = handle_event(&ptr);
let new_token = event_queue.add_dma_buf(&[], &[&event_buf]).unwrap(); let new_token = event_queue.add_dma_buf(&[], &[&ptr]).unwrap();
// This only works because nothing happen between `pop_used` and `add` that affects // This only works because nothing happen between `pop_used` and `add` that affects
// the list of free descriptors in the queue, so `add` reuses the descriptor which // the list of free descriptors in the queue, so `add` reuses the descriptor which
// was just freed by `pop_used`. // was just freed by `pop_used`.
@ -190,10 +190,8 @@ impl InputDevice {
let callbacks = self.callbacks.read_irq_disabled(); let callbacks = self.callbacks.read_irq_disabled();
// Returns ture if there may be more events to handle // Returns ture if there may be more events to handle
let handle_event = |event: &EventBuf| -> bool { let handle_event = |event: &EventBuf| -> bool {
let event: VirtioInputEvent = { event.sync().unwrap();
let mut reader = event.reader(); let event: VirtioInputEvent = event.read().unwrap();
reader.read_val()
};
match event.event_type { match event.event_type {
0 => return false, 0 => return false,
@ -244,7 +242,7 @@ impl EventTable {
let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap(); let vm_segment = VmAllocOptions::new(1).alloc_contiguous().unwrap();
let default_event = VirtioInputEvent::default(); let default_event = VirtioInputEvent::default();
let iter = iter::repeat(&default_event); let iter = iter::repeat(&default_event).take(EVENT_SIZE);
let nr_written = vm_segment.write_vals(0, iter, 0).unwrap(); let nr_written = vm_segment.write_vals(0, iter, 0).unwrap();
assert_eq!(nr_written, EVENT_SIZE); assert_eq!(nr_written, EVENT_SIZE);
@ -252,15 +250,11 @@ impl EventTable {
Self { stream, num_events } Self { stream, num_events }
} }
fn get(&self, idx: usize) -> EventBuf<'_> { fn get(&self, idx: usize) -> EventBuf {
assert!(idx < self.num_events); assert!(idx < self.num_events);
let offset = idx * EVENT_SIZE; let offset = idx * EVENT_SIZE;
EventBuf { SafePtr::new(self.stream.clone(), offset)
event_table: self,
offset,
size: EVENT_SIZE,
}
} }
const fn num_events(&self) -> usize { const fn num_events(&self) -> usize {
@ -269,38 +263,11 @@ impl EventTable {
} }
const EVENT_SIZE: usize = core::mem::size_of::<VirtioInputEvent>(); const EVENT_SIZE: usize = core::mem::size_of::<VirtioInputEvent>();
type EventBuf = SafePtr<VirtioInputEvent, DmaStream>;
/// A buffer stores exact one `VirtioInputEvent` impl<T, M: HasDaddr> DmaBuf for SafePtr<T, M> {
struct EventBuf<'a> {
event_table: &'a EventTable,
offset: usize,
size: usize,
}
impl<'a> HasDaddr for EventBuf<'a> {
fn daddr(&self) -> Daddr {
self.event_table.stream.daddr() + self.offset
}
}
impl<'a> DmaBuf for EventBuf<'a> {
fn len(&self) -> usize { fn len(&self) -> usize {
self.size core::mem::size_of::<T>()
}
}
impl<'a> EventBuf<'a> {
fn reader(&self) -> VmReader<'a> {
self.event_table
.stream
.sync(self.offset..self.offset + self.size)
.unwrap();
self.event_table
.stream
.reader()
.unwrap()
.skip(self.offset)
.limit(self.size)
} }
} }

View File

@ -3,7 +3,7 @@
use core::{fmt::Debug, marker::PhantomData}; use core::{fmt::Debug, marker::PhantomData};
use aster_frame::{ use aster_frame::{
vm::{HasPaddr, Paddr, VmIo}, vm::{Daddr, DmaStream, HasDaddr, HasPaddr, Paddr, VmIo},
Result, Result,
}; };
use aster_rights::{Dup, Exec, Full, Read, Signal, TRightSet, TRights, Write}; use aster_rights::{Dup, Exec, Full, Read, Signal, TRightSet, TRights, Write};
@ -323,6 +323,20 @@ impl<T: Pod, M: VmIo, R: TRights> SafePtr<T, M, TRightSet<R>> {
} }
} }
impl<T, M: HasDaddr, R> HasDaddr for SafePtr<T, M, R> {
fn daddr(&self) -> Daddr {
self.offset + self.vm_obj.daddr()
}
}
impl<T, R> SafePtr<T, DmaStream, R> {
/// Synchronize the object in the streaming DMA mapping
pub fn sync(&self) -> Result<()> {
self.vm_obj
.sync(self.offset..self.offset + core::mem::size_of::<T>())
}
}
#[require(R > Dup)] #[require(R > Dup)]
impl<T, M: Clone, R: TRights> Clone for SafePtr<T, M, TRightSet<R>> { impl<T, M: Clone, R: TRights> Clone for SafePtr<T, M, TRightSet<R>> {
fn clone(&self) -> Self { fn clone(&self) -> Self {