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) {
|
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();
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue