1 // 导出 ahci 相关的 module 2 pub mod ahci_inode; 3 pub mod ahcidisk; 4 pub mod hba; 5 6 use crate::arch::MMArch; 7 use crate::driver::base::block::disk_info::BLK_GF_AHCI; 8 use crate::driver::block::cache::cached_block_device::BlockCache; 9 // 依赖的rust工具包 10 use crate::driver::pci::pci::{ 11 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, 12 }; 13 use crate::filesystem::devfs::devfs_register; 14 15 use crate::driver::disk::ahci::{ 16 ahcidisk::LockedAhciDisk, 17 hba::HbaMem, 18 hba::{HbaPort, HbaPortType}, 19 }; 20 use crate::libs::rwlock::RwLockWriteGuard; 21 use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 22 use crate::mm::{MemoryManagementArch, VirtAddr}; 23 use ahci_inode::LockedAhciInode; 24 use alloc::{boxed::Box, collections::LinkedList, format, string::String, sync::Arc, vec::Vec}; 25 use core::sync::atomic::compiler_fence; 26 use log::{debug, error}; 27 use system_error::SystemError; 28 29 // 仅module内可见 全局数据区 hbr_port, disks 30 static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new()); 31 static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new()); 32 33 const AHCI_CLASS: u8 = 0x1; 34 const AHCI_SUBCLASS: u8 = 0x6; 35 36 /* TFES - Task File Error Status */ 37 #[allow(non_upper_case_globals)] 38 pub const HBA_PxIS_TFES: u32 = 1 << 30; 39 40 /// @brief 寻找所有的ahci设备 41 /// @param list 链表的写锁 42 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err 43 fn ahci_device_search<'a>( 44 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 45 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> { 46 let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS); 47 48 if result.is_empty() { 49 return Err(SystemError::ENODEV); 50 } 51 52 return Ok(result); 53 } 54 55 /// @brief: 初始化 ahci 56 pub fn ahci_init() -> Result<(), SystemError> { 57 let mut list = PCI_DEVICE_LINKEDLIST.write(); 58 let ahci_device = ahci_device_search(&mut list)?; 59 // 全局数据 - 列表 60 let mut disks_list = LOCKED_DISKS_LIST.lock(); 61 62 for device in ahci_device { 63 let standard_device = device.as_standard_device_mut().unwrap(); 64 standard_device.bar_ioremap(); 65 // 对于每一个ahci控制器分配一块空间 66 let ahci_port_base_vaddr = 67 Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize; 68 let virtaddr = standard_device 69 .bar() 70 .ok_or(SystemError::EACCES)? 71 .get_bar(5) 72 .or(Err(SystemError::EACCES))? 73 .virtual_address() 74 .unwrap(); 75 // 最后把这个引用列表放入到全局列表 76 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 77 //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度 78 let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }; 79 hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }); 80 let pi = volatile_read!(hba_mem.pi); 81 let hba_mem_index = hba_mem_list.len() - 1; 82 drop(hba_mem_list); 83 // 初始化所有的port 84 let mut id = 0; 85 for j in 0..32 { 86 if (pi >> j) & 1 > 0 { 87 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 88 let hba_mem_port = &mut hba_mem.ports[j]; 89 let tp = hba_mem_port.check_type(); 90 match tp { 91 HbaPortType::None => { 92 debug!("<ahci_rust_init> Find a None type Disk."); 93 } 94 HbaPortType::Unknown(err) => { 95 debug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err); 96 } 97 _ => { 98 debug!("<ahci_rust_init> Find a {:?} type Disk.", tp); 99 100 // 计算地址 101 let fb = unsafe { 102 MMArch::virt_2_phys(VirtAddr::new( 103 ahci_port_base_vaddr + (32 << 10) + (j << 8), 104 )) 105 } 106 .unwrap() 107 .data(); 108 let clb = unsafe { 109 MMArch::virt_2_phys(VirtAddr::new(ahci_port_base_vaddr + (j << 10))) 110 .unwrap() 111 .data() 112 }; 113 let ctbas = (0..32) 114 .map(|x| unsafe { 115 MMArch::virt_2_phys(VirtAddr::new( 116 ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8), 117 )) 118 .unwrap() 119 .data() as u64 120 }) 121 .collect::<Vec<_>>(); 122 123 // 初始化 port 124 hba_mem_port.init(clb as u64, fb as u64, &ctbas); 125 drop(hba_mem_list); 126 compiler_fence(core::sync::atomic::Ordering::SeqCst); 127 // 创建 disk 128 disks_list.push(LockedAhciDisk::new( 129 format!("ahci_disk_{}", id), 130 BLK_GF_AHCI, 131 hba_mem_index as u8, 132 j as u8, 133 )?); 134 id += 1; // ID 从0开始 135 136 debug!("start register ahci device"); 137 138 // 挂载到devfs上面去 139 let ret = devfs_register( 140 format!("ahci_{}", id).as_str(), 141 LockedAhciInode::new(disks_list.last().unwrap().clone()), 142 ); 143 if let Err(err) = ret { 144 error!( 145 "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}", 146 id, 147 hba_mem_index as u8, 148 j, 149 err 150 ); 151 } 152 } 153 } 154 } 155 } 156 BlockCache::init(); 157 } 158 159 compiler_fence(core::sync::atomic::Ordering::SeqCst); 160 return Ok(()); 161 } 162 163 /// @brief: 获取所有的 disk 164 #[allow(dead_code)] 165 pub fn disks() -> Vec<Arc<LockedAhciDisk>> { 166 let disks_list = LOCKED_DISKS_LIST.lock(); 167 return disks_list.clone(); 168 } 169 170 /// @brief: 通过 name 获取 disk 171 pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> { 172 let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock(); 173 let result = disks_list 174 .iter() 175 .find(|x| x.0.lock().name == name) 176 .ok_or(SystemError::ENXIO)? 177 .clone(); 178 return Ok(result); 179 } 180 181 /// @brief: 通过 ctrl_num 和 port_num 获取 port 182 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { 183 let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock(); 184 let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize]; 185 186 return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() }; 187 } 188