diff --git a/rust/lib/mammoth/src/mem.rs b/rust/lib/mammoth/src/mem.rs index 3b634af..ea4a070 100644 --- a/rust/lib/mammoth/src/mem.rs +++ b/rust/lib/mammoth/src/mem.rs @@ -153,6 +153,19 @@ where } } +pub fn map_cap_and_leak(mem_cap: Capability) -> u64 { + let vaddr = syscall::address_space_map(&mem_cap).unwrap(); + mem_cap.release(); + vaddr +} + +pub fn map_direct_physical_and_leak(paddr: u64, size: u64) -> u64 { + let mem_cap = syscall::memory_object_direct_physical(paddr, size).unwrap(); + let vaddr = syscall::address_space_map(&mem_cap).unwrap(); + mem_cap.release(); + vaddr +} + pub fn map_physical_and_leak(size: u64) -> (u64, u64) { let (mem_cap, paddr) = syscall::memory_object_contiguous_physical(size).unwrap(); let vaddr = syscall::address_space_map(&mem_cap).unwrap(); diff --git a/rust/sys/denali/src/ahci/controller.rs b/rust/sys/denali/src/ahci/controller.rs index 20dda6e..6ccd32e 100644 --- a/rust/sys/denali/src/ahci/controller.rs +++ b/rust/sys/denali/src/ahci/controller.rs @@ -1,7 +1,9 @@ use core::ops::DerefMut; +use core::ptr::addr_of_mut; use alloc::boxed::Box; use alloc::sync::Arc; +use mammoth::cap::Capability; use mammoth::sync::Mutex; use mammoth::{mem, thread}; @@ -46,26 +48,21 @@ pub struct PciDeviceHeader { } pub struct AhciController { - pci_memory: MemoryRegion, - hba_memory: MemoryRegion, + pci_header: &'static mut PciDeviceHeader, + hba: &'static mut AhciHba, ports: [Option; 32], } impl AhciController { - pub fn new(pci_memory: MemoryRegion) -> Self { - let pci_device_header = unsafe { - pci_memory - .mut_slice::() - .as_mut_ptr() - .cast::() - .as_mut() - .unwrap() - }; - let hba_memory = - MemoryRegion::direct_physical(pci_device_header.abar as u64, 0x1100).unwrap(); + pub fn new(pci_memory: Capability) -> Self { + let pci_vaddr = mem::map_cap_and_leak(pci_memory); + let pci_header = unsafe { (pci_vaddr as *mut PciDeviceHeader).as_mut().unwrap() }; + + let hba_vaddr = mem::map_direct_physical_and_leak(pci_header.abar as u64, 0x1100); + let hba = unsafe { (hba_vaddr as *mut AhciHba).as_mut().unwrap() }; let mut controller = Self { - pci_memory, - hba_memory, + pci_header, + hba, ports: [const { None }; 32], }; controller.init(); @@ -73,31 +70,31 @@ impl AhciController { } fn init(&mut self) { - self.ahci_hba().init(); + self.hba.init(); self.init_ports().unwrap(); } fn irq_num(&self) -> u64 { - match self.pci_header().interrupt_pin { + match self.pci_header.interrupt_pin { 1 => mammoth::zion::kZIrqPci1, 2 => mammoth::zion::kZIrqPci2, 3 => mammoth::zion::kZIrqPci3, 4 => mammoth::zion::kZIrqPci4, _ => panic!( "Unrecognized pci interrupt pin {}", - self.pci_header().interrupt_pin + self.pci_header.interrupt_pin ), } } fn handle_irq(&mut self) { - for i in 0..self.ahci_hba().capabilities.read().num_ports() { + for i in 0..self.hba.capabilities.read().num_ports() { let int_offset = 1 << i; - if (self.ahci_hba().interrupt_status.read() & int_offset) == int_offset { + if (self.hba.interrupt_status.read() & int_offset) == int_offset { if let Some(port) = &mut self.ports[i as usize] { port.handle_interrupt(); - self.ahci_hba().interrupt_status.update(|is| { + self.hba.interrupt_status.update(|is| { *is &= !int_offset; }); } @@ -106,20 +103,16 @@ impl AhciController { } fn init_ports(&mut self) -> Result<(), ZError> { - for i in 0..(self.ahci_hba().capabilities.read().num_ports() as usize) { + for i in 0..(self.hba.capabilities.read().num_ports() as usize) { let port_index = 1 << i; - if (self.ahci_hba().port_implemented.read() & port_index) != port_index { + if (self.hba.port_implemented.read() & port_index) != port_index { mammoth::debug!("Skipping port {}, not implemented", i); continue; } let port_offset: usize = 0x100 + (0x80 * i); - let port_size = size_of::(); - let port_limit = port_offset + port_size; let port = unsafe { - self.hba_memory.mut_slice::()[port_offset..port_limit] - .as_mut_ptr() - .cast::() + (((self.hba as *mut _ as usize) + port_offset) as *mut AhciPortHba) .as_mut() .unwrap() }; @@ -142,28 +135,6 @@ impl AhciController { } Ok(()) } - - pub fn pci_header(&self) -> &mut PciDeviceHeader { - unsafe { - self.pci_memory - .mut_slice::() - .as_mut_ptr() - .cast::() - .as_mut() - .unwrap() - } - } - - pub fn ahci_hba(&self) -> &mut AhciHba { - unsafe { - self.hba_memory - .mut_slice::() - .as_mut_ptr() - .cast::() - .as_mut() - .unwrap() - } - } } pub fn spawn_irq_thread(controller: Arc>) -> thread::JoinHandle { @@ -171,13 +142,9 @@ pub fn spawn_irq_thread(controller: Arc>) -> thread::JoinH let irq_num = controller.lock().irq_num(); let irq_port = mammoth::port::PortServer::from_cap(mammoth::syscall::register_irq(irq_num).unwrap()); - controller - .lock() - .ahci_hba() - .global_host_control - .update(|ghc| { - ghc.set_interrupt_enable(true); - }); + controller.lock().hba.global_host_control.update(|ghc| { + ghc.set_interrupt_enable(true); + }); loop { irq_port.recv_null().unwrap(); controller.lock().handle_irq(); diff --git a/rust/sys/denali/src/bin/denali.rs b/rust/sys/denali/src/bin/denali.rs index a5f0e68..a25a8fd 100644 --- a/rust/sys/denali/src/bin/denali.rs +++ b/rust/sys/denali/src/bin/denali.rs @@ -21,8 +21,7 @@ extern "C" fn main() -> z_err_t { .expect("Failed to get ahci info"); let ahci_controller = Arc::new(Mutex::new(AhciController::new( - mammoth::mem::MemoryRegion::from_cap(mammoth::cap::Capability::take(ahci_info.ahci_region)) - .unwrap(), + mammoth::cap::Capability::take(ahci_info.ahci_region), ))); let thread = spawn_irq_thread(ahci_controller.clone());