Store ahci hba and pci device header as mut references

This commit is contained in:
Drew Galbraith 2025-01-31 21:38:06 -08:00
parent 04effd44f8
commit 017367c4de
3 changed files with 38 additions and 59 deletions

View File

@ -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) { pub fn map_physical_and_leak(size: u64) -> (u64, u64) {
let (mem_cap, paddr) = syscall::memory_object_contiguous_physical(size).unwrap(); let (mem_cap, paddr) = syscall::memory_object_contiguous_physical(size).unwrap();
let vaddr = syscall::address_space_map(&mem_cap).unwrap(); let vaddr = syscall::address_space_map(&mem_cap).unwrap();

View File

@ -1,7 +1,9 @@
use core::ops::DerefMut; use core::ops::DerefMut;
use core::ptr::addr_of_mut;
use alloc::boxed::Box; use alloc::boxed::Box;
use alloc::sync::Arc; use alloc::sync::Arc;
use mammoth::cap::Capability;
use mammoth::sync::Mutex; use mammoth::sync::Mutex;
use mammoth::{mem, thread}; use mammoth::{mem, thread};
@ -46,26 +48,21 @@ pub struct PciDeviceHeader {
} }
pub struct AhciController { pub struct AhciController {
pci_memory: MemoryRegion, pci_header: &'static mut PciDeviceHeader,
hba_memory: MemoryRegion, hba: &'static mut AhciHba,
ports: [Option<PortController>; 32], ports: [Option<PortController>; 32],
} }
impl AhciController { impl AhciController {
pub fn new(pci_memory: MemoryRegion) -> Self { pub fn new(pci_memory: Capability) -> Self {
let pci_device_header = unsafe { let pci_vaddr = mem::map_cap_and_leak(pci_memory);
pci_memory let pci_header = unsafe { (pci_vaddr as *mut PciDeviceHeader).as_mut().unwrap() };
.mut_slice::<u8>()
.as_mut_ptr() let hba_vaddr = mem::map_direct_physical_and_leak(pci_header.abar as u64, 0x1100);
.cast::<PciDeviceHeader>() let hba = unsafe { (hba_vaddr as *mut AhciHba).as_mut().unwrap() };
.as_mut()
.unwrap()
};
let hba_memory =
MemoryRegion::direct_physical(pci_device_header.abar as u64, 0x1100).unwrap();
let mut controller = Self { let mut controller = Self {
pci_memory, pci_header,
hba_memory, hba,
ports: [const { None }; 32], ports: [const { None }; 32],
}; };
controller.init(); controller.init();
@ -73,31 +70,31 @@ impl AhciController {
} }
fn init(&mut self) { fn init(&mut self) {
self.ahci_hba().init(); self.hba.init();
self.init_ports().unwrap(); self.init_ports().unwrap();
} }
fn irq_num(&self) -> u64 { fn irq_num(&self) -> u64 {
match self.pci_header().interrupt_pin { match self.pci_header.interrupt_pin {
1 => mammoth::zion::kZIrqPci1, 1 => mammoth::zion::kZIrqPci1,
2 => mammoth::zion::kZIrqPci2, 2 => mammoth::zion::kZIrqPci2,
3 => mammoth::zion::kZIrqPci3, 3 => mammoth::zion::kZIrqPci3,
4 => mammoth::zion::kZIrqPci4, 4 => mammoth::zion::kZIrqPci4,
_ => panic!( _ => panic!(
"Unrecognized pci interrupt pin {}", "Unrecognized pci interrupt pin {}",
self.pci_header().interrupt_pin self.pci_header.interrupt_pin
), ),
} }
} }
fn handle_irq(&mut self) { 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; 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] { if let Some(port) = &mut self.ports[i as usize] {
port.handle_interrupt(); port.handle_interrupt();
self.ahci_hba().interrupt_status.update(|is| { self.hba.interrupt_status.update(|is| {
*is &= !int_offset; *is &= !int_offset;
}); });
} }
@ -106,20 +103,16 @@ impl AhciController {
} }
fn init_ports(&mut self) -> Result<(), ZError> { 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; 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); mammoth::debug!("Skipping port {}, not implemented", i);
continue; continue;
} }
let port_offset: usize = 0x100 + (0x80 * i); let port_offset: usize = 0x100 + (0x80 * i);
let port_size = size_of::<AhciPortHba>();
let port_limit = port_offset + port_size;
let port = unsafe { let port = unsafe {
self.hba_memory.mut_slice::<u8>()[port_offset..port_limit] (((self.hba as *mut _ as usize) + port_offset) as *mut AhciPortHba)
.as_mut_ptr()
.cast::<AhciPortHba>()
.as_mut() .as_mut()
.unwrap() .unwrap()
}; };
@ -142,28 +135,6 @@ impl AhciController {
} }
Ok(()) Ok(())
} }
pub fn pci_header(&self) -> &mut PciDeviceHeader {
unsafe {
self.pci_memory
.mut_slice::<u8>()
.as_mut_ptr()
.cast::<PciDeviceHeader>()
.as_mut()
.unwrap()
}
}
pub fn ahci_hba(&self) -> &mut AhciHba {
unsafe {
self.hba_memory
.mut_slice::<u8>()
.as_mut_ptr()
.cast::<AhciHba>()
.as_mut()
.unwrap()
}
}
} }
pub fn spawn_irq_thread(controller: Arc<Mutex<AhciController>>) -> thread::JoinHandle { pub fn spawn_irq_thread(controller: Arc<Mutex<AhciController>>) -> thread::JoinHandle {
@ -171,13 +142,9 @@ pub fn spawn_irq_thread(controller: Arc<Mutex<AhciController>>) -> thread::JoinH
let irq_num = controller.lock().irq_num(); let irq_num = controller.lock().irq_num();
let irq_port = let irq_port =
mammoth::port::PortServer::from_cap(mammoth::syscall::register_irq(irq_num).unwrap()); mammoth::port::PortServer::from_cap(mammoth::syscall::register_irq(irq_num).unwrap());
controller controller.lock().hba.global_host_control.update(|ghc| {
.lock() ghc.set_interrupt_enable(true);
.ahci_hba() });
.global_host_control
.update(|ghc| {
ghc.set_interrupt_enable(true);
});
loop { loop {
irq_port.recv_null().unwrap(); irq_port.recv_null().unwrap();
controller.lock().handle_irq(); controller.lock().handle_irq();

View File

@ -21,8 +21,7 @@ extern "C" fn main() -> z_err_t {
.expect("Failed to get ahci info"); .expect("Failed to get ahci info");
let ahci_controller = Arc::new(Mutex::new(AhciController::new( let ahci_controller = Arc::new(Mutex::new(AhciController::new(
mammoth::mem::MemoryRegion::from_cap(mammoth::cap::Capability::take(ahci_info.ahci_region)) mammoth::cap::Capability::take(ahci_info.ahci_region),
.unwrap(),
))); )));
let thread = spawn_irq_thread(ahci_controller.clone()); let thread = spawn_irq_thread(ahci_controller.clone());