mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-22 08:53:29 +00:00
Extend Safeptr to support DmaStream
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
345ab8f838
commit
2256f6ae8a
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
Reference in New Issue
Block a user