Skip to content

Commit

Permalink
implement desc/avail/used in queue and header
Browse files Browse the repository at this point in the history
  • Loading branch information
yodalee committed May 9, 2023
1 parent f97da1f commit 5d25148
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 3 deletions.
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(alloc_error_handler)]
#![feature(ptr_metadata)] // from_raw_parts in kvm.rs
#![feature(try_trait_v2)]
#![feature(strict_provenance)] // NonNull.addr
#![no_main]
#![no_std]

Expand Down
8 changes: 7 additions & 1 deletion src/virtio/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,16 @@ impl VirtioHeader {
}

/// set queue num
pub fn set_queue(&mut self, idx: u32, size: u16) {
pub fn set_queue(&mut self, idx: u32, size: u16, desc: u64, avail: u64, used: u64) {
unsafe {
self.queue_sel.write(idx);
self.queue_num.write(size as u32);
self.queue_desc_low.write(desc as u32);
self.queue_desc_high.write((desc >> 32) as u32);
self.queue_driver_low.write(avail as u32);
self.queue_driver_high.write((avail >> 32) as u32);
self.queue_device_low.write(used as u32);
self.queue_device_high.write((used >> 32) as u32);
}
}

Expand Down
42 changes: 40 additions & 2 deletions src/virtio/queue.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
use crate::kalloc::kalloc;

use super::header::VirtioHeader;
use super::Error;
use bitflags::bitflags;

use core::ptr::NonNull;

pub const MAX_QUEUE_SIZE: usize = 32768;

pub struct VirtioQueue {
Expand All @@ -10,13 +14,25 @@ pub struct VirtioQueue {

/// size of the queue
size: u16,

/// address of descriptor
desc: NonNull<Descriptor>,

/// address of available ring
avail: NonNull<AvailRing>,

/// address of used ring
used: NonNull<UsedRing>,
}

impl VirtioQueue {
pub fn new(header: &mut VirtioHeader, idx: u32, size: u16) -> Result<Self, Error> {
// ensure queue is not in used
if header.queue_used(idx) {
return Err(Error::AlreadyUsed);
}

// check maximum queue size
let max = header.max_queue_size();
if max == 0 {
return Err(Error::NotAvailable);
Expand All @@ -25,9 +41,31 @@ impl VirtioQueue {
return Err(Error::InvalidArguments);
}

header.set_queue(idx, size);
// allocate and zero queue memory.
// note that kalloc will fill memory with 0 for us
let desc = NonNull::new(kalloc() as *mut _).ok_or(Error::NoMemory)?;
let avail = NonNull::new(kalloc() as *mut _).ok_or(Error::NoMemory)?;
let used = NonNull::new(kalloc() as *mut _).ok_or(Error::NoMemory)?;

// write physical address
header.set_queue(
idx,
size,
desc.addr().get() as u64,
avail.addr().get() as u64,
used.addr().get() as u64,
);

// set queue ready
header.set_queue_ready(/*ready=*/ true);

Ok(Self { idx, size })
Ok(Self {
idx,
size,
desc,
avail,
used,
})
}
}

Expand Down

0 comments on commit 5d25148

Please sign in to comment.