1004e86ffSlogin // 导出 ahci 相关的 module 2004e86ffSlogin pub mod ahci_inode; 3004e86ffSlogin pub mod ahcidisk; 4004e86ffSlogin pub mod hba; 5004e86ffSlogin 6*b087521eSChiichen use crate::driver::base::block::block_device::BlockDevice; 7*b087521eSChiichen use crate::driver::base::block::disk_info::BLK_GF_AHCI; 8004e86ffSlogin // 依赖的rust工具包 98d94ea66SYJwu2023 use crate::driver::pci::pci::{ 108d94ea66SYJwu2023 get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST, 118d94ea66SYJwu2023 }; 12004e86ffSlogin use crate::filesystem::devfs::devfs_register; 13004e86ffSlogin use crate::kerror; 148d94ea66SYJwu2023 use crate::libs::rwlock::RwLockWriteGuard; 15004e86ffSlogin use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 16004e86ffSlogin use crate::mm::virt_2_phys; 17676b8ef6SMork use crate::syscall::SystemError; 18004e86ffSlogin use crate::{ 19004e86ffSlogin driver::disk::ahci::{ 20004e86ffSlogin ahcidisk::LockedAhciDisk, 21004e86ffSlogin hba::HbaMem, 22004e86ffSlogin hba::{HbaPort, HbaPortType}, 23004e86ffSlogin }, 24004e86ffSlogin kdebug, 25004e86ffSlogin }; 26004e86ffSlogin use ahci_inode::LockedAhciInode; 278d94ea66SYJwu2023 use alloc::{ 288d94ea66SYJwu2023 boxed::Box, 298d94ea66SYJwu2023 collections::LinkedList, 308d94ea66SYJwu2023 format, 318d94ea66SYJwu2023 string::{String, ToString}, 328d94ea66SYJwu2023 sync::Arc, 338d94ea66SYJwu2023 vec::Vec, 34004e86ffSlogin }; 358d94ea66SYJwu2023 use core::sync::atomic::compiler_fence; 36004e86ffSlogin 37004e86ffSlogin // 仅module内可见 全局数据区 hbr_port, disks 38004e86ffSlogin static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new()); 39004e86ffSlogin static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new()); 40004e86ffSlogin 418d94ea66SYJwu2023 const AHCI_CLASS: u8 = 0x1; 428d94ea66SYJwu2023 const AHCI_SUBCLASS: u8 = 0x6; 438d94ea66SYJwu2023 44004e86ffSlogin /* TFES - Task File Error Status */ 45004e86ffSlogin #[allow(non_upper_case_globals)] 46004e86ffSlogin pub const HBA_PxIS_TFES: u32 = 1 << 30; 47004e86ffSlogin 48004e86ffSlogin #[no_mangle] 49004e86ffSlogin pub extern "C" fn ahci_init() -> i32 { 50004e86ffSlogin let r = ahci_rust_init(); 51004e86ffSlogin if r.is_ok() { 52004e86ffSlogin return 0; 53004e86ffSlogin } else { 54676b8ef6SMork return r.unwrap_err().to_posix_errno(); 55004e86ffSlogin } 56004e86ffSlogin } 578d94ea66SYJwu2023 588d94ea66SYJwu2023 /// @brief 寻找所有的ahci设备 598d94ea66SYJwu2023 /// @param list 链表的写锁 608d94ea66SYJwu2023 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err 618d94ea66SYJwu2023 fn ahci_device_search<'a>( 628d94ea66SYJwu2023 list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, 638d94ea66SYJwu2023 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> { 648d94ea66SYJwu2023 let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS); 658d94ea66SYJwu2023 668d94ea66SYJwu2023 if result.is_empty() { 678d94ea66SYJwu2023 return Err(SystemError::ENODEV); 688d94ea66SYJwu2023 } 698d94ea66SYJwu2023 kdebug!("{}", result.len()); 708d94ea66SYJwu2023 Ok(result) 718d94ea66SYJwu2023 } 728d94ea66SYJwu2023 73004e86ffSlogin /// @brief: 初始化 ahci 74676b8ef6SMork pub fn ahci_rust_init() -> Result<(), SystemError> { 758d94ea66SYJwu2023 let mut list = PCI_DEVICE_LINKEDLIST.write(); 768d94ea66SYJwu2023 let ahci_device = ahci_device_search(&mut list)?; 77004e86ffSlogin // 全局数据 - 列表 78004e86ffSlogin let mut disks_list = LOCKED_DISKS_LIST.lock(); 79004e86ffSlogin 808d94ea66SYJwu2023 for device in ahci_device { 818d94ea66SYJwu2023 let standard_device = device.as_standard_device_mut().unwrap(); 828d94ea66SYJwu2023 standard_device.bar_ioremap(); 83004e86ffSlogin // 对于每一个ahci控制器分配一块空间 (目前slab algorithm最大支持1MB) 84004e86ffSlogin let ahci_port_base_vaddr = 85004e86ffSlogin Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize; 868d94ea66SYJwu2023 let virtaddr = standard_device 878d94ea66SYJwu2023 .bar() 888d94ea66SYJwu2023 .ok_or(SystemError::EACCES)? 898d94ea66SYJwu2023 .get_bar(5) 908d94ea66SYJwu2023 .or(Err(SystemError::EACCES))? 918d94ea66SYJwu2023 .virtual_address() 928d94ea66SYJwu2023 .unwrap(); 93004e86ffSlogin // 最后把这个引用列表放入到全局列表 94004e86ffSlogin let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 958d94ea66SYJwu2023 //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度 962dd9f0c7SLoGin let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }; 972dd9f0c7SLoGin hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() }); 988d94ea66SYJwu2023 let pi = volatile_read!(hba_mem.pi); 998d94ea66SYJwu2023 let hba_mem_index = hba_mem_list.len() - 1; 100004e86ffSlogin drop(hba_mem_list); 101004e86ffSlogin // 初始化所有的port 102004e86ffSlogin let mut id = 0; 103004e86ffSlogin for j in 0..32 { 104004e86ffSlogin if (pi >> j) & 1 > 0 { 1058d94ea66SYJwu2023 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 1068d94ea66SYJwu2023 let hba_mem_port = &mut hba_mem.ports[j]; 1078d94ea66SYJwu2023 let tp = hba_mem_port.check_type(); 108004e86ffSlogin match tp { 109004e86ffSlogin HbaPortType::None => { 110004e86ffSlogin kdebug!("<ahci_rust_init> Find a None type Disk."); 111004e86ffSlogin } 112004e86ffSlogin HbaPortType::Unknown(err) => { 113004e86ffSlogin kdebug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err); 114004e86ffSlogin } 115004e86ffSlogin _ => { 116004e86ffSlogin kdebug!("<ahci_rust_init> Find a {:?} type Disk.", tp); 117004e86ffSlogin 118004e86ffSlogin // 计算地址 119004e86ffSlogin let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8)); 120004e86ffSlogin let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10)); 121004e86ffSlogin let ctbas = (0..32) 122004e86ffSlogin .map(|x| { 123004e86ffSlogin virt_2_phys( 124004e86ffSlogin ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8), 125004e86ffSlogin ) as u64 126004e86ffSlogin }) 127004e86ffSlogin .collect::<Vec<_>>(); 128004e86ffSlogin 129004e86ffSlogin // 初始化 port 1308d94ea66SYJwu2023 hba_mem_port.init(clb as u64, fb as u64, &ctbas); 131004e86ffSlogin drop(hba_mem_list); 132004e86ffSlogin compiler_fence(core::sync::atomic::Ordering::SeqCst); 133004e86ffSlogin // 创建 disk 134004e86ffSlogin disks_list.push(LockedAhciDisk::new( 135004e86ffSlogin format!("ahci_disk_{}", id), 136004e86ffSlogin BLK_GF_AHCI, 1378d94ea66SYJwu2023 hba_mem_index as u8, 138004e86ffSlogin j as u8, 139004e86ffSlogin )?); 140004e86ffSlogin id += 1; // ID 从0开始 141004e86ffSlogin 142004e86ffSlogin kdebug!("start register ahci device"); 143004e86ffSlogin 144004e86ffSlogin // 挂载到devfs上面去 145004e86ffSlogin let ret = devfs_register( 146004e86ffSlogin format!("ahci_{}", id).as_str(), 147004e86ffSlogin LockedAhciInode::new(disks_list.last().unwrap().clone()), 148004e86ffSlogin ); 149004e86ffSlogin if let Err(err) = ret { 150004e86ffSlogin kerror!( 151676b8ef6SMork "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}", 152004e86ffSlogin id, 1538d94ea66SYJwu2023 hba_mem_index as u8, 154004e86ffSlogin j, 155004e86ffSlogin err 156004e86ffSlogin ); 157004e86ffSlogin } 158004e86ffSlogin } 159004e86ffSlogin } 160004e86ffSlogin } 161004e86ffSlogin } 162004e86ffSlogin } 163004e86ffSlogin 164004e86ffSlogin compiler_fence(core::sync::atomic::Ordering::SeqCst); 165004e86ffSlogin return Ok(()); 166004e86ffSlogin } 167004e86ffSlogin 168004e86ffSlogin /// @brief: 获取所有的 disk 169004e86ffSlogin #[allow(dead_code)] 170004e86ffSlogin pub fn disks() -> Vec<Arc<LockedAhciDisk>> { 171004e86ffSlogin let disks_list = LOCKED_DISKS_LIST.lock(); 172004e86ffSlogin return disks_list.clone(); 173004e86ffSlogin } 174004e86ffSlogin 175004e86ffSlogin /// @brief: 通过 name 获取 disk 176676b8ef6SMork pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> { 177004e86ffSlogin let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock(); 1788d94ea66SYJwu2023 let result = disks_list 1798d94ea66SYJwu2023 .iter() 1808d94ea66SYJwu2023 .find(|x| x.0.lock().name == name) 1818d94ea66SYJwu2023 .ok_or(SystemError::ENXIO)? 1828d94ea66SYJwu2023 .clone(); 1838d94ea66SYJwu2023 return Ok(result); 184004e86ffSlogin } 185004e86ffSlogin 186004e86ffSlogin /// @brief: 通过 ctrl_num 和 port_num 获取 port 1878d94ea66SYJwu2023 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { 188004e86ffSlogin let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock(); 189004e86ffSlogin let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize]; 1908d94ea66SYJwu2023 191004e86ffSlogin return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() }; 192004e86ffSlogin } 193004e86ffSlogin 194004e86ffSlogin /// @brief: 测试函数 195004e86ffSlogin pub fn __test_ahci() { 196004e86ffSlogin let _res = ahci_rust_init(); 197004e86ffSlogin let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap(); 198004e86ffSlogin #[deny(overflowing_literals)] 199004e86ffSlogin let mut buf = [0u8; 3000usize]; 200004e86ffSlogin 201004e86ffSlogin for i in 0..2000 { 202004e86ffSlogin buf[i] = i as u8; 203004e86ffSlogin } 204004e86ffSlogin 205004e86ffSlogin let _dd = disk; 206004e86ffSlogin 207004e86ffSlogin // 测试1, 写两个块,读4个块 208004e86ffSlogin // _dd.write_at(123, 2, &buf).unwrap(); 209004e86ffSlogin let mut read_buf = [0u8; 3000usize]; 210004e86ffSlogin _dd.read_at(122, 4, &mut read_buf).unwrap(); 211004e86ffSlogin 212004e86ffSlogin // 测试2, 只读写一个字节 213004e86ffSlogin for i in 0..512 { 214004e86ffSlogin buf[i] = 233; 215004e86ffSlogin } 216004e86ffSlogin // _dd.write_at(123, 2, &buf).unwrap(); 217004e86ffSlogin let mut read_buf2 = [0u8; 3000usize]; 218004e86ffSlogin _dd.read_at(122, 4, &mut read_buf2).unwrap(); 219004e86ffSlogin } 220