xref: /DragonOS/kernel/src/driver/disk/ahci/mod.rs (revision 9fa0e95eeed8630a8a69c874090af2f10e8eee02)
1004e86ffSlogin // 导出 ahci 相关的 module
2004e86ffSlogin pub mod ahci_inode;
3004e86ffSlogin pub mod ahcidisk;
4004e86ffSlogin pub mod hba;
5004e86ffSlogin 
6816ee5aeSLoGin use crate::arch::MMArch;
7*9fa0e95eSLoGin use crate::driver::base::block::manager::block_dev_manager;
8eb49bb99S曾俊 use crate::driver::block::cache::cached_block_device::BlockCache;
9*9fa0e95eSLoGin use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk;
108d94ea66SYJwu2023 use crate::driver::pci::pci::{
118d94ea66SYJwu2023     get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
128d94ea66SYJwu2023 };
132eab6dd7S曾俊 
142eab6dd7S曾俊 use crate::driver::disk::ahci::{
15004e86ffSlogin     hba::HbaMem,
16004e86ffSlogin     hba::{HbaPort, HbaPortType},
17004e86ffSlogin };
182eab6dd7S曾俊 use crate::libs::rwlock::RwLockWriteGuard;
192eab6dd7S曾俊 use crate::libs::spinlock::{SpinLock, SpinLockGuard};
20816ee5aeSLoGin use crate::mm::{MemoryManagementArch, VirtAddr};
21*9fa0e95eSLoGin use alloc::{boxed::Box, collections::LinkedList, vec::Vec};
228d94ea66SYJwu2023 use core::sync::atomic::compiler_fence;
23*9fa0e95eSLoGin use log::debug;
2491e9d4abSLoGin use system_error::SystemError;
25004e86ffSlogin 
26004e86ffSlogin // 仅module内可见 全局数据区  hbr_port, disks
27004e86ffSlogin static LOCKED_HBA_MEM_LIST: SpinLock<Vec<&mut HbaMem>> = SpinLock::new(Vec::new());
28004e86ffSlogin 
298d94ea66SYJwu2023 const AHCI_CLASS: u8 = 0x1;
308d94ea66SYJwu2023 const AHCI_SUBCLASS: u8 = 0x6;
318d94ea66SYJwu2023 
32004e86ffSlogin /* TFES - Task File Error Status */
33004e86ffSlogin #[allow(non_upper_case_globals)]
34004e86ffSlogin pub const HBA_PxIS_TFES: u32 = 1 << 30;
35004e86ffSlogin 
368d94ea66SYJwu2023 /// @brief 寻找所有的ahci设备
378d94ea66SYJwu2023 /// @param list 链表的写锁
388d94ea66SYJwu2023 /// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError>   成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
ahci_device_search<'a>( list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>, ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError>398d94ea66SYJwu2023 fn ahci_device_search<'a>(
408d94ea66SYJwu2023     list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
418d94ea66SYJwu2023 ) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> {
428d94ea66SYJwu2023     let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
438d94ea66SYJwu2023 
448d94ea66SYJwu2023     if result.is_empty() {
458d94ea66SYJwu2023         return Err(SystemError::ENODEV);
468d94ea66SYJwu2023     }
471496ba7bSLoGin 
481496ba7bSLoGin     return Ok(result);
498d94ea66SYJwu2023 }
508d94ea66SYJwu2023 
51004e86ffSlogin /// @brief: 初始化 ahci
ahci_init() -> Result<(), SystemError>521496ba7bSLoGin pub fn ahci_init() -> Result<(), SystemError> {
538d94ea66SYJwu2023     let mut list = PCI_DEVICE_LINKEDLIST.write();
548d94ea66SYJwu2023     let ahci_device = ahci_device_search(&mut list)?;
55004e86ffSlogin 
568d94ea66SYJwu2023     for device in ahci_device {
578d94ea66SYJwu2023         let standard_device = device.as_standard_device_mut().unwrap();
588d94ea66SYJwu2023         standard_device.bar_ioremap();
597ae679ddSLoGin         // 对于每一个ahci控制器分配一块空间
60004e86ffSlogin         let ahci_port_base_vaddr =
61004e86ffSlogin             Box::leak(Box::new([0u8; (1 << 20) as usize])) as *mut u8 as usize;
628d94ea66SYJwu2023         let virtaddr = standard_device
638d94ea66SYJwu2023             .bar()
648d94ea66SYJwu2023             .ok_or(SystemError::EACCES)?
658d94ea66SYJwu2023             .get_bar(5)
668d94ea66SYJwu2023             .or(Err(SystemError::EACCES))?
678d94ea66SYJwu2023             .virtual_address()
688d94ea66SYJwu2023             .unwrap();
69004e86ffSlogin         // 最后把这个引用列表放入到全局列表
70004e86ffSlogin         let mut hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
718d94ea66SYJwu2023         //这里两次unsafe转引用规避rust只能有一个可变引用的检查,提高运行速度
722dd9f0c7SLoGin         let hba_mem = unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() };
732dd9f0c7SLoGin         hba_mem_list.push(unsafe { (virtaddr.data() as *mut HbaMem).as_mut().unwrap() });
748d94ea66SYJwu2023         let pi = volatile_read!(hba_mem.pi);
758d94ea66SYJwu2023         let hba_mem_index = hba_mem_list.len() - 1;
76004e86ffSlogin         drop(hba_mem_list);
77004e86ffSlogin         // 初始化所有的port
78004e86ffSlogin         for j in 0..32 {
79004e86ffSlogin             if (pi >> j) & 1 > 0 {
808d94ea66SYJwu2023                 let hba_mem_list = LOCKED_HBA_MEM_LIST.lock();
818d94ea66SYJwu2023                 let hba_mem_port = &mut hba_mem.ports[j];
828d94ea66SYJwu2023                 let tp = hba_mem_port.check_type();
83004e86ffSlogin                 match tp {
84004e86ffSlogin                     HbaPortType::None => {
852eab6dd7S曾俊                         debug!("<ahci_rust_init> Find a None type Disk.");
86004e86ffSlogin                     }
87004e86ffSlogin                     HbaPortType::Unknown(err) => {
882eab6dd7S曾俊                         debug!("<ahci_rust_init> Find a Unknown({:?}) type Disk.", err);
89004e86ffSlogin                     }
90004e86ffSlogin                     _ => {
912eab6dd7S曾俊                         debug!("<ahci_rust_init> Find a {:?} type Disk.", tp);
92004e86ffSlogin 
93004e86ffSlogin                         // 计算地址
94816ee5aeSLoGin                         let fb = unsafe {
95816ee5aeSLoGin                             MMArch::virt_2_phys(VirtAddr::new(
96816ee5aeSLoGin                                 ahci_port_base_vaddr + (32 << 10) + (j << 8),
97816ee5aeSLoGin                             ))
98816ee5aeSLoGin                         }
99816ee5aeSLoGin                         .unwrap()
100816ee5aeSLoGin                         .data();
101816ee5aeSLoGin                         let clb = unsafe {
102816ee5aeSLoGin                             MMArch::virt_2_phys(VirtAddr::new(ahci_port_base_vaddr + (j << 10)))
103816ee5aeSLoGin                                 .unwrap()
104816ee5aeSLoGin                                 .data()
105816ee5aeSLoGin                         };
106004e86ffSlogin                         let ctbas = (0..32)
107816ee5aeSLoGin                             .map(|x| unsafe {
108816ee5aeSLoGin                                 MMArch::virt_2_phys(VirtAddr::new(
109004e86ffSlogin                                     ahci_port_base_vaddr + (40 << 10) + (j << 13) + (x << 8),
110816ee5aeSLoGin                                 ))
111816ee5aeSLoGin                                 .unwrap()
112816ee5aeSLoGin                                 .data() as u64
113004e86ffSlogin                             })
114004e86ffSlogin                             .collect::<Vec<_>>();
115004e86ffSlogin 
116004e86ffSlogin                         // 初始化 port
1178d94ea66SYJwu2023                         hba_mem_port.init(clb as u64, fb as u64, &ctbas);
118004e86ffSlogin                         drop(hba_mem_list);
119004e86ffSlogin                         compiler_fence(core::sync::atomic::Ordering::SeqCst);
120*9fa0e95eSLoGin                         let ahci_disk = LockedAhciDisk::new(hba_mem_index as u8, j as u8)?;
121*9fa0e95eSLoGin                         block_dev_manager()
122*9fa0e95eSLoGin                             .register(ahci_disk)
123*9fa0e95eSLoGin                             .expect("register ahci disk failed");
124004e86ffSlogin 
1252eab6dd7S曾俊                         debug!("start register ahci device");
126004e86ffSlogin                     }
127004e86ffSlogin                 }
128004e86ffSlogin             }
129004e86ffSlogin         }
130eb49bb99S曾俊         BlockCache::init();
131004e86ffSlogin     }
132004e86ffSlogin 
133004e86ffSlogin     compiler_fence(core::sync::atomic::Ordering::SeqCst);
134004e86ffSlogin     return Ok(());
135004e86ffSlogin }
136004e86ffSlogin 
137004e86ffSlogin /// @brief: 通过 ctrl_num 和 port_num 获取 port
_port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort1388d94ea66SYJwu2023 fn _port(ctrl_num: u8, port_num: u8) -> &'static mut HbaPort {
139004e86ffSlogin     let list: SpinLockGuard<Vec<&mut HbaMem>> = LOCKED_HBA_MEM_LIST.lock();
140004e86ffSlogin     let port: &HbaPort = &list[ctrl_num as usize].ports[port_num as usize];
1418d94ea66SYJwu2023 
142004e86ffSlogin     return unsafe { (port as *const HbaPort as *mut HbaPort).as_mut().unwrap() };
143004e86ffSlogin }
144