virtio-gpu: start working on the scheme
Signed-off-by: Anhad Singh <andypython@protonmail.com>
This commit is contained in:
@@ -12,7 +12,7 @@ use syscall::{Io, PHYSMAP_NO_CACHE, PHYSMAP_WRITE};
|
||||
|
||||
use crate::spec::*;
|
||||
use crate::transport::{Error, StandardTransport};
|
||||
use crate::utils::{VolatileCell, align_down};
|
||||
use crate::utils::{align_down, VolatileCell};
|
||||
|
||||
pub struct Device<'a> {
|
||||
pub transport: Arc<StandardTransport<'a>>,
|
||||
@@ -186,11 +186,7 @@ pub fn probe_device<'a>(pcid_handle: &mut PcidServerHandle) -> Result<Device<'a>
|
||||
|
||||
let size = offset + capability.length as usize;
|
||||
|
||||
let addr = syscall::physmap(
|
||||
aligned_addr,
|
||||
size,
|
||||
PHYSMAP_WRITE | PHYSMAP_NO_CACHE,
|
||||
)?;
|
||||
let addr = syscall::physmap(aligned_addr, size, PHYSMAP_WRITE | PHYSMAP_NO_CACHE)?;
|
||||
|
||||
addr + offset
|
||||
};
|
||||
|
||||
@@ -86,6 +86,12 @@ impl<'a> Future for PendingRequest<'a> {
|
||||
.insert(self.first_descriptor, cx.waker().clone());
|
||||
|
||||
let used_head = self.queue.used.head_index();
|
||||
|
||||
if used_head == self.queue.used_head.load(Ordering::SeqCst) {
|
||||
// No new requests have been completed.
|
||||
return Poll::Pending;
|
||||
}
|
||||
|
||||
let used_element = self.queue.used.get_element_at((used_head - 1) as usize);
|
||||
let written = used_element.written.get();
|
||||
|
||||
@@ -109,6 +115,8 @@ impl<'a> Future for PendingRequest<'a> {
|
||||
.lock()
|
||||
.unwrap()
|
||||
.remove(&self.first_descriptor);
|
||||
|
||||
self.queue.used_head.store(used_head, Ordering::SeqCst);
|
||||
return Poll::Ready(written);
|
||||
} else {
|
||||
return Poll::Pending;
|
||||
@@ -122,6 +130,7 @@ pub struct Queue<'a> {
|
||||
pub used: Used<'a>,
|
||||
pub descriptor: Dma<[Descriptor]>,
|
||||
pub available: Available<'a>,
|
||||
pub used_head: AtomicU16,
|
||||
|
||||
notification_bell: &'a mut AtomicU16,
|
||||
descriptor_stack: crossbeam_queue::SegQueue<u16>,
|
||||
@@ -148,6 +157,7 @@ impl<'a> Queue<'a> {
|
||||
waker: Mutex::new(std::collections::HashMap::new()),
|
||||
queue_index,
|
||||
descriptor_stack,
|
||||
used_head: AtomicU16::new(0),
|
||||
sref: sref.clone(),
|
||||
})
|
||||
}
|
||||
@@ -190,8 +200,6 @@ impl<'a> Queue<'a> {
|
||||
self.notification_bell
|
||||
.store(self.queue_index, Ordering::SeqCst);
|
||||
|
||||
assert_eq!(self.used.flags(), 0);
|
||||
|
||||
PendingRequest {
|
||||
queue: self.sref.upgrade().unwrap(),
|
||||
first_descriptor: first_descriptor as u32,
|
||||
@@ -470,6 +478,7 @@ impl<'a> StandardTransport<'a> {
|
||||
|
||||
event_queue
|
||||
.add(irq_fd, move |_| -> Result<Option<usize>, std::io::Error> {
|
||||
// Wake up the tasks waiting on the queue.
|
||||
for (_, task) in queue_copy.waker.lock().unwrap().iter() {
|
||||
task.wake_by_ref();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use core::cell::UnsafeCell;
|
||||
use core::fmt::Debug;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C)]
|
||||
pub struct VolatileCell<T> {
|
||||
value: UnsafeCell<T>,
|
||||
@@ -28,6 +28,17 @@ impl<T: Copy> VolatileCell<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Debug for VolatileCell<T>
|
||||
where
|
||||
T: Debug + Copy,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("VolatileCell")
|
||||
.field("value", &self.get())
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<T> Sync for VolatileCell<T> {}
|
||||
|
||||
#[repr(C)]
|
||||
|
||||
Reference in New Issue
Block a user