Move Ahci Port Controller to hold raw references.
This commit is contained in:
parent
0024e38412
commit
04effd44f8
|
@ -152,3 +152,10 @@ where
|
|||
write!(f, "{:?}", self.read())
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
mem_cap.release();
|
||||
(vaddr, paddr)
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ use core::ops::DerefMut;
|
|||
use alloc::boxed::Box;
|
||||
use alloc::sync::Arc;
|
||||
use mammoth::sync::Mutex;
|
||||
use mammoth::thread;
|
||||
use mammoth::{mem, thread};
|
||||
|
||||
use mammoth::{mem::MemoryRegion, zion::ZError};
|
||||
|
||||
|
@ -15,10 +15,7 @@ use crate::ahci::port::{
|
|||
use super::command::{
|
||||
CommandList, CommandTable, HostToDeviceRegisterFis, ReceivedFis, SataCommand,
|
||||
};
|
||||
use super::{
|
||||
hba::AhciHba,
|
||||
port::{AhciPortHba, AhciPortInterruptEnable, AhciSataError},
|
||||
};
|
||||
use super::{hba::AhciHba, port::AhciPortHba};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[repr(C, packed)]
|
||||
|
@ -51,7 +48,7 @@ pub struct PciDeviceHeader {
|
|||
pub struct AhciController {
|
||||
pci_memory: MemoryRegion,
|
||||
hba_memory: MemoryRegion,
|
||||
ports: [Option<PortController<'static>>; 32],
|
||||
ports: [Option<PortController>; 32],
|
||||
}
|
||||
|
||||
impl AhciController {
|
||||
|
@ -140,7 +137,7 @@ impl AhciController {
|
|||
continue;
|
||||
}
|
||||
|
||||
self.ports[i] = Some(PortController::new(port)?);
|
||||
self.ports[i] = Some(PortController::new(port));
|
||||
self.ports[i].as_mut().unwrap().identify()?;
|
||||
}
|
||||
Ok(())
|
||||
|
@ -226,36 +223,51 @@ impl From<&Command> for HostToDeviceRegisterFis {
|
|||
}
|
||||
}
|
||||
|
||||
struct PortController<'a> {
|
||||
ahci_port_hba: &'a mut AhciPortHba,
|
||||
struct PortController {
|
||||
ahci_port_hba: &'static mut AhciPortHba,
|
||||
command_list: &'static mut CommandList,
|
||||
received_fis: &'static mut ReceivedFis,
|
||||
command_tables: &'static mut [CommandTable; 32],
|
||||
|
||||
command_slots: [Option<Arc<Command>>; 32],
|
||||
command_structures: MemoryRegion,
|
||||
|
||||
// FIXME: These should probably be something like a OnceCell (or OnceLock).
|
||||
sector_size: Arc<Mutex<Option<u64>>>,
|
||||
sector_cnt: Arc<Mutex<Option<u64>>>,
|
||||
}
|
||||
|
||||
impl<'a> PortController<'a> {
|
||||
fn new(ahci_port_hba: &'a mut AhciPortHba) -> Result<Self, ZError> {
|
||||
let (command_structures, command_paddr) = MemoryRegion::contiguous_physical(0x2500)?;
|
||||
impl PortController {
|
||||
fn new(ahci_port_hba: &'static mut AhciPortHba) -> Self {
|
||||
let (command_vaddr, command_paddr) = mem::map_physical_and_leak(0x2500);
|
||||
ahci_port_hba.init(command_paddr, command_paddr + 0x400);
|
||||
|
||||
let mut controller = Self {
|
||||
ahci_port_hba,
|
||||
command_slots: [const { None }; 32],
|
||||
command_structures,
|
||||
sector_size: Arc::new(Mutex::new(None)),
|
||||
sector_cnt: Arc::new(Mutex::new(None)),
|
||||
let command_list = unsafe { (command_vaddr as *mut CommandList).as_mut().unwrap() };
|
||||
let received_fis = unsafe {
|
||||
((command_vaddr + 0x400) as *mut ReceivedFis)
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
};
|
||||
let command_tables = unsafe {
|
||||
((command_vaddr + 0x500) as *mut [CommandTable; 32])
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
// This leaves space for 8 prdt entries.
|
||||
for i in 0..32 {
|
||||
controller.command_list()[i].command_table_base_addr =
|
||||
command_list[i].command_table_base_addr =
|
||||
(command_paddr + 0x500) + (0x100 * (i as u64));
|
||||
}
|
||||
|
||||
Ok(controller)
|
||||
Self {
|
||||
ahci_port_hba,
|
||||
command_list,
|
||||
received_fis,
|
||||
command_tables,
|
||||
command_slots: [const { None }; 32],
|
||||
sector_size: Arc::new(Mutex::new(None)),
|
||||
sector_cnt: Arc::new(Mutex::new(None)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn identify(&mut self) -> Result<(), ZError> {
|
||||
|
@ -300,16 +312,15 @@ impl<'a> PortController<'a> {
|
|||
let slot = self.select_slot()?;
|
||||
self.command_slots[slot] = Some(command.clone());
|
||||
|
||||
self.command_tables()[slot].command_fis.host_to_device = command.clone().as_ref().into();
|
||||
self.command_tables[slot].command_fis.host_to_device = command.clone().as_ref().into();
|
||||
|
||||
self.command_tables()[slot].prdt[0].region_address = command.paddr;
|
||||
self.command_tables()[slot].prdt[0].byte_count = 512 * (command.sector_cnt as u32);
|
||||
self.command_tables[slot].prdt[0].region_address = command.paddr;
|
||||
self.command_tables[slot].prdt[0].byte_count = 512 * (command.sector_cnt as u32);
|
||||
|
||||
self.command_list()[slot].prd_table_length = 1;
|
||||
self.command_list[slot].prd_table_length = 1;
|
||||
|
||||
self.command_list()[slot].command =
|
||||
(size_of::<HostToDeviceRegisterFis>() as u16 / 4) & 0x1F;
|
||||
self.command_list()[slot].command |= 1 << 7;
|
||||
self.command_list[slot].command = (size_of::<HostToDeviceRegisterFis>() as u16 / 4) & 0x1F;
|
||||
self.command_list[slot].command |= 1 << 7;
|
||||
self.ahci_port_hba.issue_command(slot);
|
||||
Ok(())
|
||||
}
|
||||
|
@ -324,53 +335,22 @@ impl<'a> PortController<'a> {
|
|||
return Err(ZError::EXHAUSTED);
|
||||
}
|
||||
|
||||
fn command_list(&mut self) -> &mut CommandList {
|
||||
unsafe {
|
||||
self.command_structures
|
||||
.mut_slice::<u8>()
|
||||
.as_mut_ptr()
|
||||
.cast::<CommandList>()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn recieved_fis(&mut self) -> &mut ReceivedFis {
|
||||
unsafe {
|
||||
self.command_structures.mut_slice::<u8>()[0x400..]
|
||||
.as_mut_ptr()
|
||||
.cast::<ReceivedFis>()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn command_tables(&mut self) -> &mut [CommandTable; 32] {
|
||||
unsafe {
|
||||
self.command_structures.mut_slice::<u8>()[0x500..]
|
||||
.as_mut_ptr()
|
||||
.cast::<[CommandTable; 32]>()
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_interrupt(&mut self) {
|
||||
let int_status = self.ahci_port_hba.interrupt_status.read();
|
||||
if int_status.device_to_host_register_fis_interrupt() {
|
||||
assert_eq!(
|
||||
self.recieved_fis().device_to_host_register_fis.fis_type as u8,
|
||||
self.received_fis.device_to_host_register_fis.fis_type as u8,
|
||||
FisType::RegisterDeviceToHost as u8
|
||||
);
|
||||
if self.recieved_fis().device_to_host_register_fis.error != 0 {
|
||||
if self.received_fis.device_to_host_register_fis.error != 0 {
|
||||
mammoth::debug!(
|
||||
"D2H err: {:#0x}",
|
||||
self.recieved_fis().device_to_host_register_fis.error
|
||||
self.received_fis.device_to_host_register_fis.error
|
||||
);
|
||||
|
||||
mammoth::debug!(
|
||||
"Status: {:#0x}",
|
||||
self.recieved_fis().device_to_host_register_fis.status
|
||||
self.received_fis.device_to_host_register_fis.status
|
||||
);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue