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::manager::block_dev_manager; 8 use crate::driver::block::cache::cached_block_device::BlockCache; 9 use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk; 10 use crate::driver::pci::pci::{ 11 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, 12 }; 13 14 use crate::driver::disk::ahci::{ 15 hba::HbaMem, 16 hba::{HbaPort, HbaPortType}, 17 }; 18 use crate::libs::rwlock::RwLockWriteGuard; 19 use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 20 use crate::mm::{MemoryManagementArch, VirtAddr}; 21 use alloc::{boxed::Box, collections::LinkedList, vec::Vec}; 22 use core::sync::atomic::compiler_fence; 23 use log::debug; 24 use system_error::SystemError; 25 26 // 仅module内可见 全局数据区 hbr_port, disks 27 static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new()); 28 29 const AHCI_CLASS: u8 = 0x1; 30 const AHCI_SUBCLASS: u8 = 0x6; 31 32 /* TFES - Task File Error Status */ 33 #[allow(non_upper_case_globals)] 34 pub const HBA_PxIS_TFES: u32 = 1 << 30; 35 36 /// @brief 寻找所有的ahci设备 37 /// @param list 链表的写锁 38 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err 39 fn ahci_device_search<'a>( 40 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 41 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> { 42 let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS); 43 44 if result.is_empty() { 45 return Err(SystemError::ENODEV); 46 } 47 48 return Ok(result); 49 } 50 51 /// @brief: 初始化 ahci 52 pub fn ahci_init() -> Result<(), SystemError> { 53 let mut list = PCI_DEVICE_LINKEDLIST.write(); 54 let ahci_device = ahci_device_search(&mut list)?; 55 56 for device in ahci_device { 57 let standard_device = device.as_standard_device_mut().unwrap(); 58 standard_device.bar_ioremap(); 59 // 对于每一个ahci控制器分配一块空间 60 let ahci_port_base_vaddr = 61 Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize; 62 let virtaddr = standard_device 63 .bar() 64 .ok_or(SystemError::EACCES)? 65 .get_bar(5) 66 .or(Err(SystemError::EACCES))? 67 .virtual_address() 68 .unwrap(); 69 // 最后把这个引用列表放入到全局列表 70 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 71 //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度 72 let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }; 73 hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }); 74 let pi = volatile_read!(hba_mem.pi); 75 let hba_mem_index = hba_mem_list.len() - 1; 76 drop(hba_mem_list); 77 // 初始化所有的port 78 for j in 0..32 { 79 if (pi >> j) & 1 > 0 { 80 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 81 let hba_mem_port = &mut hba_mem.ports[j]; 82 let tp = hba_mem_port.check_type(); 83 match tp { 84 HbaPortType::None => { 85 debug!("<ahci_rust_init> Find a None type Disk."); 86 } 87 HbaPortType::Unknown(err) => { 88 debug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err); 89 } 90 _ => { 91 debug!("<ahci_rust_init> Find a {:?} type Disk.", tp); 92 93 // 计算地址 94 let fb = unsafe { 95 MMArch::virt_2_phys(VirtAddr::new( 96 ahci_port_base_vaddr + (32 << 10) + (j << 8), 97 )) 98 } 99 .unwrap() 100 .data(); 101 let clb = unsafe { 102 MMArch::virt_2_phys(VirtAddr::new(ahci_port_base_vaddr + (j << 10))) 103 .unwrap() 104 .data() 105 }; 106 let ctbas = (0..32) 107 .map(|x| unsafe { 108 MMArch::virt_2_phys(VirtAddr::new( 109 ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8), 110 )) 111 .unwrap() 112 .data() as u64 113 }) 114 .collect::<Vec<_>>(); 115 116 // 初始化 port 117 hba_mem_port.init(clb as u64, fb as u64, &ctbas); 118 drop(hba_mem_list); 119 compiler_fence(core::sync::atomic::Ordering::SeqCst); 120 let ahci_disk = LockedAhciDisk::new(hba_mem_index as u8, j as u8)?; 121 block_dev_manager() 122 .register(ahci_disk) 123 .expect("register ahci disk failed"); 124 125 debug!("start register ahci device"); 126 } 127 } 128 } 129 } 130 BlockCache::init(); 131 } 132 133 compiler_fence(core::sync::atomic::Ordering::SeqCst); 134 return Ok(()); 135 } 136 137 /// @brief: 通过 ctrl_num 和 port_num 获取 port 138 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { 139 let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock(); 140 let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize]; 141 142 return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() }; 143 } 144