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