1 // 导出 ahci 相关的 module 2 pub mod ahci_inode; 3 pub mod ahcidisk; 4 pub mod hba; 5 6 use crate::io::device::BlockDevice; 7 // 依赖的rust工具包 8 use crate::filesystem::devfs::devfs_register; 9 use crate::io::disk_info::BLK_GF_AHCI; 10 use crate::kerror; 11 use crate::libs::spinlock::{SpinLock, SpinLockGuard}; 12 use crate::mm::virt_2_phys; 13 use crate::syscall::SystemError; 14 use crate::{ 15 driver::disk::ahci::{ 16 ahcidisk::LockedAhciDisk, 17 hba::HbaMem, 18 hba::{HbaPort, HbaPortType}, 19 }, 20 kdebug, 21 }; 22 use ahci_inode::LockedAhciInode; 23 use alloc::boxed::Box; 24 use alloc::string::ToString; 25 use alloc::{format, string::String, sync::Arc, vec::Vec}; 26 use core::sync::atomic::compiler_fence; 27 28 // 依赖的C结构体/常量 29 use crate::include::bindings::bindings::{ 30 ahci_cpp_init, pci_device_structure_general_device_t, pci_device_structure_header_t, 31 AHCI_MAPPING_BASE, MAX_AHCI_DEVICES, PAGE_2M_MASK, 32 }; 33 34 // 仅module内可见 全局数据区 hbr_port, disks 35 static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new()); 36 static LOCKED_DISKS_LIST: SpinLock<Vec<Arc<LockedAhciDisk>>> = SpinLock::new(Vec::new()); 37 38 /* TFES - Task File Error Status */ 39 #[allow(non_upper_case_globals)] 40 pub const HBA_PxIS_TFES: u32 = 1 << 30; 41 42 #[no_mangle] 43 pub extern "C" fn ahci_init() -> i32 { 44 let r = ahci_rust_init(); 45 if r.is_ok() { 46 return 0; 47 } else { 48 return r.unwrap_err().to_posix_errno(); 49 } 50 } 51 /// @brief: 初始化 ahci 52 pub fn ahci_rust_init() -> Result<(), SystemError> { 53 compiler_fence(core::sync::atomic::Ordering::SeqCst); 54 55 let mut ahci_dev_counts: u32 = 0; 56 let mut ahci_devs: [*mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize] = 57 [0 as *mut pci_device_structure_header_t; MAX_AHCI_DEVICES as usize]; 58 let mut gen_devs: [*mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize] = 59 [0 as *mut pci_device_structure_general_device_t; MAX_AHCI_DEVICES as usize]; 60 61 compiler_fence(core::sync::atomic::Ordering::SeqCst); 62 unsafe { 63 // 单线程 init, 所以写 ahci_devs 全局变量不会出错? 64 ahci_cpp_init( 65 (&mut ahci_dev_counts) as *mut u32, 66 (&mut ahci_devs) as *mut *mut pci_device_structure_header_t, 67 (&mut gen_devs) as *mut *mut pci_device_structure_general_device_t, 68 ); 69 } 70 compiler_fence(core::sync::atomic::Ordering::SeqCst); 71 72 // 全局数据 - 列表 73 let mut disks_list = LOCKED_DISKS_LIST.lock(); 74 75 for i in 0..(ahci_dev_counts as usize) { 76 // 对于每一个ahci控制器分配一块空间 (目前slab algorithm最大支持1MB) 77 let ahci_port_base_vaddr = 78 Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize; 79 compiler_fence(core::sync::atomic::Ordering::SeqCst); 80 // 获取全局引用 : 计算 HBA_MEM 的虚拟地址 依赖于C的宏定义 cal_HBA_MEM_VIRT_ADDR 81 let virt_addr = AHCI_MAPPING_BASE as usize + unsafe { (*gen_devs[i]).BAR5 as usize } 82 - (unsafe { (*gen_devs[0]).BAR5 as usize } & PAGE_2M_MASK as usize); 83 compiler_fence(core::sync::atomic::Ordering::SeqCst); 84 85 // 最后把这个引用列表放入到全局列表 86 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 87 hba_mem_list.push(unsafe { (virt_addr as *mut HbaMem).as_mut().unwrap() }); 88 let pi = volatile_read!(hba_mem_list[i].pi); 89 drop(hba_mem_list); 90 compiler_fence(core::sync::atomic::Ordering::SeqCst); 91 92 // 初始化所有的port 93 let mut id = 0; 94 for j in 0..32 { 95 if (pi >> j) & 1 > 0 { 96 let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock(); 97 let tp = hba_mem_list[i].ports[j].check_type(); 98 match tp { 99 HbaPortType::None => { 100 kdebug!("<ahci_rust_init> Find a None type Disk."); 101 } 102 HbaPortType::Unknown(err) => { 103 kdebug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err); 104 } 105 _ => { 106 kdebug!("<ahci_rust_init> Find a {:?} type Disk.", tp); 107 108 // 计算地址 109 let fb = virt_2_phys(ahci_port_base_vaddr + (32 << 10) + (j << 8)); 110 let clb = virt_2_phys(ahci_port_base_vaddr + (j << 10)); 111 compiler_fence(core::sync::atomic::Ordering::SeqCst); 112 let ctbas = (0..32) 113 .map(|x| { 114 virt_2_phys( 115 ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8), 116 ) as u64 117 }) 118 .collect::<Vec<_>>(); 119 120 // 初始化 port 121 hba_mem_list[i].ports[j].init(clb as u64, fb as u64, &ctbas); 122 123 // 释放锁 124 drop(hba_mem_list); 125 compiler_fence(core::sync::atomic::Ordering::SeqCst); 126 127 // 创建 disk 128 disks_list.push(LockedAhciDisk::new( 129 format!("ahci_disk_{}", id), 130 BLK_GF_AHCI, 131 i as u8, 132 j as u8, 133 )?); 134 id += 1; // ID 从0开始 135 136 kdebug!("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 kerror!( 145 "Ahci_{} ctrl = {}, port = {} failed to register, error code = {:?}", 146 id, 147 i, 148 j, 149 err 150 ); 151 } 152 } 153 } 154 } 155 } 156 } 157 158 compiler_fence(core::sync::atomic::Ordering::SeqCst); 159 return Ok(()); 160 } 161 162 /// @brief: 获取所有的 disk 163 #[allow(dead_code)] 164 pub fn disks() -> Vec<Arc<LockedAhciDisk>> { 165 let disks_list = LOCKED_DISKS_LIST.lock(); 166 return disks_list.clone(); 167 } 168 169 /// @brief: 通过 name 获取 disk 170 pub fn get_disks_by_name(name: String) -> Result<Arc<LockedAhciDisk>, SystemError> { 171 compiler_fence(core::sync::atomic::Ordering::SeqCst); 172 let disks_list: SpinLockGuard<Vec<Arc<LockedAhciDisk>>> = LOCKED_DISKS_LIST.lock(); 173 for i in 0..disks_list.len() { 174 if disks_list[i].0.lock().name == name { 175 return Ok(disks_list[i].clone()); 176 } 177 } 178 compiler_fence(core::sync::atomic::Ordering::SeqCst); 179 return Err(SystemError::ENXIO); 180 181 } 182 183 /// @brief: 通过 ctrl_num 和 port_num 获取 port 184 pub fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort { 185 compiler_fence(core::sync::atomic::Ordering::SeqCst); 186 let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock(); 187 let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize]; 188 compiler_fence(core::sync::atomic::Ordering::SeqCst); 189 return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() }; 190 } 191 192 /// @brief: 测试函数 193 pub fn __test_ahci() { 194 let _res = ahci_rust_init(); 195 let disk: Arc<LockedAhciDisk> = get_disks_by_name("ahci_disk_0".to_string()).unwrap(); 196 #[deny(overflowing_literals)] 197 let mut buf = [0u8; 3000usize]; 198 199 for i in 0..2000 { 200 buf[i] = i as u8; 201 } 202 203 let _dd = disk; 204 205 // 测试1, 写两个块,读4个块 206 // _dd.write_at(123, 2, &buf).unwrap(); 207 let mut read_buf = [0u8; 3000usize]; 208 _dd.read_at(122, 4, &mut read_buf).unwrap(); 209 210 // 测试2, 只读写一个字节 211 for i in 0..512 { 212 buf[i] = 233; 213 } 214 // _dd.write_at(123, 2, &buf).unwrap(); 215 let mut read_buf2 = [0u8; 3000usize]; 216 _dd.read_at(122, 4, &mut read_buf2).unwrap(); 217 } 218