Rust XHCI Implementation.

This commit is contained in:
Drew 2025-12-05 22:01:13 -08:00
parent da2eb4fda3
commit c1ab41bbad
19 changed files with 933 additions and 110 deletions

View file

@ -78,6 +78,10 @@ impl MemoryRegion {
})
}
pub fn vaddr(&self) -> usize {
self.virt_addr as usize
}
pub fn slice<T>(&self) -> &[T] {
unsafe {
slice::from_raw_parts(
@ -246,11 +250,12 @@ pub fn map_cap_and_leak(mem_cap: Capability) -> u64 {
vaddr
}
pub fn map_direct_physical_and_leak(paddr: u64, size: u64) -> u64 {
let mem_cap = syscall::memory_object_direct_physical(paddr, size).unwrap();
pub fn map_direct_physical_and_leak<T>(paddr: usize, size: usize) -> NonNull<T> {
let mem_cap = syscall::memory_object_direct_physical(paddr as u64, size as u64).unwrap();
let vaddr = syscall::address_space_map(&mem_cap).unwrap();
mem_cap.release();
vaddr
// UNWRAP: The kernel guarantees this is valid.
NonNull::new(vaddr as *mut T).unwrap()
}
pub fn map_physical_and_leak(size: u64) -> (u64, u64) {

View file

@ -4,17 +4,34 @@ use core::{
ptr::NonNull,
};
use alloc::{slice, vec::Vec};
use alloc::{boxed::Box, slice, vec::Vec};
use crate::mem::MemoryRegion;
pub struct PhysicalBox<T: ?Sized> {
data: NonNull<T>,
#[allow(dead_code)]
region: MemoryRegion,
physical_address: usize,
_marker: PhantomData<T>,
}
impl<T> PhysicalBox<T> {
pub fn new(data: T) -> Self {
let (memory_region, paddr) =
MemoryRegion::contiguous_physical(size_of::<T>() as u64).expect("Failed to allocate");
// UNWRAP: We know this isn't null.
let ptr = NonNull::new(memory_region.mut_ptr_at_offset(0)).unwrap();
unsafe { ptr.write(data) };
Self {
data: ptr,
region: memory_region,
physical_address: paddr as usize,
_marker: PhantomData,
}
}
}
impl<T: ?Sized> PhysicalBox<T> {
pub fn physical_address(&self) -> usize {
self.physical_address
@ -50,7 +67,7 @@ impl<T> PhysicalBox<[T]> {
{
let layout = core::alloc::Layout::array::<T>(len).expect("Layout overflow");
// TODO: Implement a function like alloc that takes a layout. let (memory_region, paddr) =
// TODO: Implement a function like alloc that takes a layout.
let (memory_region, paddr) =
MemoryRegion::contiguous_physical(layout.size() as u64).expect("Failed to allocate");
@ -122,6 +139,13 @@ where
}
}
/// SAFETY: We are the only owner of this pointer.
unsafe impl<T: ?Sized> Send for PhysicalBox<T> where Box<T>: Send {}
/// SAFETY: You must have a mutable reference to this
/// type to modify the data at the pointer.
unsafe impl<T: ?Sized> Sync for PhysicalBox<T> where Box<T>: Sync {}
impl<T: ?Sized> Drop for PhysicalBox<T> {
fn drop(&mut self) {
// SAFETY:

View file

@ -125,6 +125,7 @@ impl Executor {
}
}
#[derive(Clone)]
pub struct Spawner {
tasks: Arc<Mutex<BTreeMap<TaskId, Task>>>,
task_queue: Arc<Mutex<VecDeque<TaskId>>>,

View file

@ -72,15 +72,15 @@ impl PciDevice {
control.capable_address_64(),
"We don't handle the non-64bit case for MSI yet."
);
assert!(
control.multi_message_capable() == 0,
"We don't yet handle multi-message capable devices."
);
if control.multi_message_capable() != 0 {
mammoth::debug!("WARN: We don't yet handle multi-message capable devices.");
}
// FIXME: These probably need to be volatile writes.
let header: &mut PciDeviceHeader = self.memory_region.as_mut();
header.command = header.command.with_interrupt_disable(true);
msi_cap.msi_control = control.with_msi_enable(true);
msi_cap.msi_control = control.with_msi_enable(true).with_multi_message_enable(0);
// For setting addr and data field, see intel ref
// Vol 3. Section 11.11