Store ahci hba and pci device header as mut references
This commit is contained in:
parent
04effd44f8
commit
017367c4de
|
@ -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();
|
||||
|
|
|
@ -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<PortController>; 32],
|
||||
}
|
||||
|
||||
impl AhciController {
|
||||
pub fn new(pci_memory: MemoryRegion) -> Self {
|
||||
let pci_device_header = unsafe {
|
||||
pci_memory
|
||||
.mut_slice::<u8>()
|
||||
.as_mut_ptr()
|
||||
.cast::<PciDeviceHeader>()
|
||||
.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::<AhciPortHba>();
|
||||
let port_limit = port_offset + port_size;
|
||||
let port = unsafe {
|
||||
self.hba_memory.mut_slice::<u8>()[port_offset..port_limit]
|
||||
.as_mut_ptr()
|
||||
.cast::<AhciPortHba>()
|
||||
(((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::<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 {
|
||||
|
@ -171,11 +142,7 @@ pub fn spawn_irq_thread(controller: Arc<Mutex<AhciController>>) -> 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| {
|
||||
controller.lock().hba.global_host_control.update(|ghc| {
|
||||
ghc.set_interrupt_enable(true);
|
||||
});
|
||||
loop {
|
||||
|
|
|
@ -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());
|
||||
|
|
Loading…
Reference in New Issue