Skip to content

Commit

Permalink
crates/examples/sel4cp/http-server: Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
nspin committed Aug 23, 2023
1 parent 02475c9 commit a9e4f6f
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 84 deletions.
154 changes: 76 additions & 78 deletions crates/examples/sel4cp/http-server/helpers/virtio-hal-impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,73 +4,94 @@
#![feature(strict_provenance)]

use core::alloc::Layout;
use core::ops::Range;
use core::ptr::{self, NonNull};

use virtio_drivers::{BufferDirection, Hal, PhysAddr, PAGE_SIZE};

use sel4_bounce_buffer_allocator::{Basic, BounceBufferAllocator};
use sel4_externally_shared::{ExternallySharedPtr, ExternallySharedRef};
use sel4_externally_shared::ExternallySharedRef;
use sel4_immediate_sync_once_cell::ImmediateSyncOnceCell;
use sel4_sync::{GenericMutex, PanickingMutexSyncOps};

const MAX_ALIGNMENT: usize = 4096;
static GLOBAL_STATE: ImmediateSyncOnceCell<GenericMutex<PanickingMutexSyncOps, State>> =
ImmediateSyncOnceCell::new();

static DMA_REGION_VADDR_RANGE: ImmediateSyncOnceCell<Range<usize>> = ImmediateSyncOnceCell::new();
struct State {
dma_region: ExternallySharedRef<'static, [u8]>,
dma_region_paddr: usize,
bounce_buffer_allocator: BounceBufferAllocator<Basic>,
}

static DMA_REGION_PADDR: ImmediateSyncOnceCell<usize> = ImmediateSyncOnceCell::new();
impl State {
fn offset_to_paddr(&self, offset: usize) -> PhysAddr {
self.dma_region_paddr.checked_add(offset).unwrap()
}

static BOUNCE_BUFFER_ALLOCATOR: GenericMutex<
PanickingMutexSyncOps,
Option<BounceBufferAllocator<Basic>>,
> = GenericMutex::new(PanickingMutexSyncOps::new(), None);
fn paddr_to_offset(&self, paddr: PhysAddr) -> usize {
paddr.checked_sub(self.dma_region_paddr).unwrap()
}
}

pub struct HalImpl;

impl HalImpl {
pub fn init(dma_region_size: usize, dma_region_vaddr: usize, dma_region_paddr: usize) {
DMA_REGION_VADDR_RANGE
.set(dma_region_vaddr..(dma_region_vaddr + dma_region_size))
let dma_region_ptr = NonNull::new(ptr::from_raw_parts_mut(
ptr::from_exposed_addr_mut(dma_region_vaddr),
dma_region_size,
))
.unwrap();

let dma_region = unsafe { ExternallySharedRef::new(dma_region_ptr) };

let max_alignment = 1
<< dma_region_vaddr
.trailing_zeros()
.min(dma_region_paddr.trailing_zeros());

let bounce_buffer_allocator =
BounceBufferAllocator::new(Basic::new(dma_region_size), max_alignment);

GLOBAL_STATE
.set(GenericMutex::new(
PanickingMutexSyncOps::new(),
State {
dma_region,
dma_region_paddr,
bounce_buffer_allocator,
},
))
.ok()
.unwrap();

DMA_REGION_PADDR.set(dma_region_paddr).unwrap();

{
let mut lock = BOUNCE_BUFFER_ALLOCATOR.lock();
*lock = Some(BounceBufferAllocator::new(
Basic::new(dma_region_size),
MAX_ALIGNMENT,
));
}
}
}

unsafe impl Hal for HalImpl {
fn dma_alloc(pages: usize, _direction: BufferDirection) -> (PhysAddr, NonNull<u8>) {
let mut state = GLOBAL_STATE.get().unwrap().lock();
assert!(pages > 0);
let layout = Layout::from_size_align(pages * PAGE_SIZE, PAGE_SIZE).unwrap();
let buffer = {
let mut lock = BOUNCE_BUFFER_ALLOCATOR.lock();
lock.as_mut().unwrap().allocate(layout).unwrap()
};
let vaddr = with_bounce_buffer_ptr(buffer.clone(), |ptr| {
ptr.fill(0);
ptr.as_raw_ptr().as_non_null_ptr()
});
let paddr = offset_to_paddr(buffer.start);
let bounce_buffer_range = state.bounce_buffer_allocator.allocate(layout).unwrap();
let bounce_buffer_ptr = state
.dma_region
.as_mut_ptr()
.index(bounce_buffer_range.clone());
bounce_buffer_ptr.fill(0);
let vaddr = bounce_buffer_ptr.as_raw_ptr().as_non_null_ptr();
let paddr = state.offset_to_paddr(bounce_buffer_range.start);
(paddr, vaddr)
}

unsafe fn dma_dealloc(paddr: PhysAddr, _vaddr: NonNull<u8>, pages: usize) -> i32 {
let buffer = {
let start = paddr_to_offset(paddr);
let mut state = GLOBAL_STATE.get().unwrap().lock();
let bounce_buffer_range = {
let start = state.paddr_to_offset(paddr);
let size = pages * PAGE_SIZE;
start..(start + size)
};
{
let mut lock = BOUNCE_BUFFER_ALLOCATOR.lock();
lock.as_mut().unwrap().deallocate(buffer);
}
state
.bounce_buffer_allocator
.deallocate(bounce_buffer_range);
0
}

Expand All @@ -79,57 +100,34 @@ unsafe impl Hal for HalImpl {
}

unsafe fn share(buffer: NonNull<[u8]>, _direction: BufferDirection) -> PhysAddr {
let mut state = GLOBAL_STATE.get().unwrap().lock();
assert!(buffer.len() > 0);
let layout = Layout::from_size_align(buffer.len(), 1).unwrap();
let bounce_buffer = {
let mut lock = BOUNCE_BUFFER_ALLOCATOR.lock();
lock.as_mut().unwrap().allocate(layout).unwrap()
};
with_bounce_buffer_ptr(bounce_buffer.clone(), |ptr| {
ptr.copy_from_slice(buffer.as_ref());
});
let paddr = offset_to_paddr(bounce_buffer.start);
let bounce_buffer_range = state.bounce_buffer_allocator.allocate(layout).unwrap();
state
.dma_region
.as_mut_ptr()
.index(bounce_buffer_range.clone())
.copy_from_slice(buffer.as_ref());
let paddr = state.offset_to_paddr(bounce_buffer_range.start);
paddr
}

unsafe fn unshare(paddr: PhysAddr, mut buffer: NonNull<[u8]>, direction: BufferDirection) {
let bounce_buffer = {
let start = paddr_to_offset(paddr);
let mut state = GLOBAL_STATE.get().unwrap().lock();
let bounce_buffer_range = {
let start = state.paddr_to_offset(paddr);
start..(start + buffer.len())
};
if direction != BufferDirection::DriverToDevice {
with_bounce_buffer_ptr(bounce_buffer.clone(), |ptr| {
ptr.copy_into_slice(buffer.as_mut());
});
}
{
let mut lock = BOUNCE_BUFFER_ALLOCATOR.lock();
lock.as_mut().unwrap().deallocate(bounce_buffer);
state
.dma_region
.as_mut_ptr()
.index(bounce_buffer_range.clone())
.copy_into_slice(buffer.as_mut());
}
state
.bounce_buffer_allocator
.deallocate(bounce_buffer_range);
}
}

fn with_bounce_buffer_ptr<F, R>(bounce_buffer: Range<usize>, f: F) -> R
where
F: FnOnce(ExternallySharedPtr<'_, [u8]>) -> R,
{
f(dma_region().as_mut_ptr().index(bounce_buffer))
}

fn dma_region() -> ExternallySharedRef<'static, [u8]> {
let vaddr_range = DMA_REGION_VADDR_RANGE.get().unwrap();
let ptr = NonNull::new(ptr::from_raw_parts_mut(
ptr::from_exposed_addr_mut(vaddr_range.start),
vaddr_range.len(),
))
.unwrap();
unsafe { ExternallySharedRef::new(ptr) }
}

fn offset_to_paddr(offset: usize) -> PhysAddr {
DMA_REGION_PADDR.get().unwrap() + offset
}

fn paddr_to_offset(paddr: PhysAddr) -> usize {
paddr.checked_sub(*DMA_REGION_PADDR.get().unwrap()).unwrap()
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![no_std]
#![no_main]
#![feature(never_type)]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(strict_provenance)]

extern crate alloc;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
#![no_std]
#![no_main]
#![feature(ptr_metadata)]
#![feature(slice_ptr_get)]
#![feature(never_type)]
#![feature(strict_provenance)]

use core::ptr::NonNull;

Expand Down

0 comments on commit a9e4f6f

Please sign in to comment.